summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/Makefile78
-rw-r--r--src/mesa/drivers/beos/Makefile8
-rw-r--r--src/mesa/drivers/common/driverfuncs.c39
-rw-r--r--src/mesa/drivers/common/driverfuncs.h4
-rw-r--r--src/mesa/drivers/directfb/Makefile2
-rw-r--r--src/mesa/drivers/dri/Makefile2
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c124
-rw-r--r--src/mesa/drivers/dri/common/dri_util.h20
-rw-r--r--src/mesa/drivers/dri/common/utils.c229
-rw-r--r--src/mesa/drivers/dri/common/utils.h29
-rw-r--r--src/mesa/drivers/dri/common/vblank.c4
-rw-r--r--src/mesa/drivers/dri/common/xmlpool/Makefile4
-rw-r--r--src/mesa/drivers/dri/glcore/Makefile84
-rw-r--r--src/mesa/drivers/dri/glcore/glcore_driver.c128
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.c22
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_upload.c9
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex.c13
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex.h1
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_copy.c4
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_image.c4
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_subimage.c4
-rw-r--r--src/mesa/drivers/dri/r300/r300_reg.h1
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c6
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertprog.c6
-rw-r--r--src/mesa/drivers/dri/swrast/Makefile24
-rw-r--r--src/mesa/drivers/dri/swrast/swrast.c727
-rw-r--r--src/mesa/drivers/dri/swrast/swrast_priv.h142
-rw-r--r--src/mesa/drivers/dri/swrast/swrast_span.c367
-rw-r--r--src/mesa/drivers/dri/swrast/swrast_spantemp.h328
-rw-r--r--src/mesa/drivers/dri/unichrome/via_screen.c2
-rw-r--r--src/mesa/drivers/dri/unichrome/via_tex.c4
-rw-r--r--src/mesa/drivers/glslcompiler/Makefile2
-rw-r--r--src/mesa/drivers/x11/fakeglx.c9
-rw-r--r--src/mesa/drivers/xorg/.gitignore3
-rw-r--r--src/mesa/drivers/xorg/Makefile95
-rw-r--r--src/mesa/drivers/xorg/glcore.c24
-rw-r--r--src/mesa/glapi/Makefile70
-rw-r--r--src/mesa/glapi/glapi.c11
-rw-r--r--src/mesa/glapi/glthread.c4
-rw-r--r--src/mesa/glapi/glthread.h6
-rw-r--r--src/mesa/main/config.h1
-rw-r--r--src/mesa/main/context.c40
-rw-r--r--src/mesa/main/dd.h6
-rw-r--r--src/mesa/main/dlist.c33
-rw-r--r--src/mesa/main/fbobject.c2
-rw-r--r--src/mesa/main/mipmap.c1
-rw-r--r--src/mesa/main/mipmap.h1
-rw-r--r--src/mesa/main/mtypes.h30
-rw-r--r--src/mesa/main/state.c28
-rw-r--r--src/mesa/main/texenvprogram.c59
-rw-r--r--src/mesa/main/texstore.c32
-rw-r--r--src/mesa/main/version.h2
-rw-r--r--src/mesa/shader/arbprogparse.c5
-rw-r--r--src/mesa/shader/descrip.mms7
-rw-r--r--src/mesa/shader/prog_execute.c10
-rw-r--r--src/mesa/shader/prog_execute.h2
-rw-r--r--src/mesa/shader/prog_instruction.c211
-rw-r--r--src/mesa/shader/prog_instruction.h9
-rw-r--r--src/mesa/shader/prog_parameter.c52
-rw-r--r--src/mesa/shader/prog_parameter.h10
-rw-r--r--src/mesa/shader/prog_print.c42
-rw-r--r--src/mesa/shader/prog_statevars.c52
-rw-r--r--src/mesa/shader/prog_statevars.h5
-rw-r--r--src/mesa/shader/prog_uniform.c157
-rw-r--r--src/mesa/shader/prog_uniform.h91
-rw-r--r--src/mesa/shader/program.c388
-rw-r--r--src/mesa/shader/program.h33
-rw-r--r--src/mesa/shader/programopt.c117
-rw-r--r--src/mesa/shader/programopt.h2
-rw-r--r--src/mesa/shader/shader_api.c648
-rw-r--r--src/mesa/shader/shader_api.h103
-rw-r--r--src/mesa/shader/slang/library/Makefile2
-rw-r--r--src/mesa/shader/slang/slang_codegen.c11
-rw-r--r--src/mesa/shader/slang/slang_compile.c15
-rw-r--r--src/mesa/shader/slang/slang_emit.c10
-rw-r--r--src/mesa/shader/slang/slang_link.c252
-rw-r--r--src/mesa/shader/slang/slang_link.h4
-rw-r--r--src/mesa/sources1
-rw-r--r--src/mesa/swrast/s_drawpix.c4
-rw-r--r--src/mesa/swrast/s_fragprog.c14
-rw-r--r--src/mesa/swrast/s_span.c1
-rw-r--r--src/mesa/swrast/s_texstore.c10
-rw-r--r--src/mesa/tnl/t_context.h2
-rw-r--r--src/mesa/tnl/t_vp_build.c47
-rw-r--r--src/mesa/vbo/vbo_exec_draw.c2
-rw-r--r--src/mesa/vbo/vbo_save_draw.c2
-rw-r--r--src/mesa/x86-64/Makefile2
-rw-r--r--src/mesa/x86/Makefile2
-rw-r--r--src/mesa/x86/read_rgba_span_x86.S4
89 files changed, 3580 insertions, 1627 deletions
diff --git a/src/mesa/Makefile b/src/mesa/Makefile
index 633bfb19a3b..08d723553e8 100644
--- a/src/mesa/Makefile
+++ b/src/mesa/Makefile
@@ -24,25 +24,38 @@ GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY)
# Figure out what to make here
-default:
+default: depend
@for driver in $(DRIVER_DIRS) ; do \
case "$$driver" in \
- x11) $(MAKE) stand-alone ;; \
- dri) $(MAKE) linux-solo ;; \
- osmesa) $(MAKE) osmesa-only ;; \
- beos) $(MAKE) beos ;; \
- directfb) $(MAKE) directfb ;; \
- fbdev) $(MAKE) fbdev ;; \
+ x11) $(MAKE) stand-alone || exit 1 ;; \
+ dri) $(MAKE) linux-solo || exit 1 ;; \
+ osmesa) $(MAKE) osmesa-only || exit 1 ;; \
+ beos) $(MAKE) beos || exit 1 ;; \
+ directfb) $(MAKE) directfb || exit 1 ;; \
+ fbdev) $(MAKE) fbdev || exit 1 ;; \
*) echo "$$driver is invalid in DRIVER_DIRS" >&2; exit 1;; \
esac ; \
done
+install: default
+ @for driver in $(DRIVER_DIRS) ; do \
+ case "$$driver" in \
+ osmesa) if [ "$(DRIVER_DIRS)" = osmesa ]; then \
+ $(MAKE) install-headers install-osmesa || exit 1 ; \
+ else \
+ $(MAKE) install-osmesa || exit 1 ; \
+ fi ;; \
+ dri) $(MAKE) install-libgl install-dri || exit 1 ;; \
+ *) $(MAKE) install-libgl || exit 1 ;; \
+ esac ; \
+ done
+
######################################################################
# BeOS driver target
beos: depend subdirs libmesa.a
- cd drivers/beos; $(MAKE)
+ cd drivers/beos && $(MAKE)
######################################################################
@@ -56,7 +69,7 @@ libmesa.a: $(SOLO_OBJECTS)
fi
linux-solo: depend subdirs libmesa.a
- cd drivers/dri ; $(MAKE)
+ cd drivers/dri && $(MAKE)
#####################################################################
@@ -69,7 +82,7 @@ libgl-core: $(CORE_OBJECTS)
$(GL_LIB_DEPS)
directfb: depend subdirs libgl-core
- cd drivers/directfb ; $(MAKE)
+ cd drivers/directfb && $(MAKE)
#####################################################################
@@ -145,11 +158,11 @@ depend: $(ALL_SOURCES)
subdirs:
@ if echo "$(ASM_FLAGS)" | grep -q USE_X86_ASM ; then \
- (cd x86 ; $(MAKE)) ; \
+ (cd x86 && $(MAKE)) || exit 1 ; \
fi
@ if echo "$(ASM_FLAGS)" | grep -q USE_X86_64_ASM ; then \
- (cd x86 ; $(MAKE)) ; \
- (cd x86-64 ; $(MAKE)) ; \
+ (cd x86 && $(MAKE)) || exit 1 ; \
+ (cd x86-64 && $(MAKE)) || exit 1 ; \
fi
pcedit = sed \
@@ -160,31 +173,25 @@ pcedit = sed \
gl.pc: gl.pc.in
$(pcedit) $< > $@
-install-libgl: gl.pc
+install-headers:
$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GL
+ $(INSTALL) -m 644 $(TOP)/include/GL/*.h \
+ $(DESTDIR)$(INSTALL_DIR)/include/GL
+
+install-libgl: default gl.pc install-headers
$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig
- $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(DESTDIR)$(INSTALL_DIR)/include/GL
- @if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \
- $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* \
- $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \
- fi
+ $(INSTALL) $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)* \
+ $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
$(INSTALL) -m 644 gl.pc $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig
-install-osmesa:
- @if [ -e $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME) ]; then \
- $(INSTALL) $(TOP)/$(LIB_DIR)/libOSMesa* \
- $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \
- fi
-
-install-drivers:
- @for target in $(DRIVER_DIRS); do \
- case "$$target" in \
- dri) cd drivers/dri ; $(MAKE) install ;; \
- esac; \
- done
+install-osmesa: default
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+ $(INSTALL) $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME)* \
+ $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
-install: default install-libgl install-osmesa install-drivers
+install-dri:
+ cd drivers/dri && $(MAKE) install
## NOT INSTALLED YET:
## $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES
@@ -200,9 +207,10 @@ clean:
-rm -f */*/*.o
-rm -f depend depend.bak libmesa.a
-rm -f drivers/*/*.o
- (cd drivers/dri && $(MAKE) clean)
- (cd x86 && $(MAKE) clean)
- (cd x86-64 && $(MAKE) clean)
+ -@cd drivers/dri && $(MAKE) clean
+ -@cd drivers/xorg && $(MAKE) clean
+ -@cd x86 && $(MAKE) clean
+ -@cd x86-64 && $(MAKE) clean
-include depend
diff --git a/src/mesa/drivers/beos/Makefile b/src/mesa/drivers/beos/Makefile
index 9c7d6affc3b..0448650a8c6 100644
--- a/src/mesa/drivers/beos/Makefile
+++ b/src/mesa/drivers/beos/Makefile
@@ -170,10 +170,10 @@ OBJECTS := $(DRIVER_OBJECTS:.cpp=.o)
default: depend $(TOP)/$(LIB_DIR) $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
$(MESA_MODULES):
- cd $(TOP)/src/mesa; $(MAKE) mesa.a ;
+ cd $(TOP)/src/mesa && $(MAKE) mesa.a ;
$(GLU_MODULES):
- cd $(GLU_DIR); $(MAKE) $(subst $(GLU_DIR)/,,$(GLU_MODULES)) ;
+ cd $(GLU_DIR) && $(MAKE) $(subst $(GLU_DIR)/,,$(GLU_MODULES)) ;
$(TOP)/$(LIB_DIR):
mkdir $(TOP)/$(LIB_DIR)
@@ -184,13 +184,13 @@ $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(OBJECTS) $(MESA_MODULES) $(GLU_MODULES)
$(MKLIB_OPTIONS) $(GL_LIB_DEPS) $(OBJECTS) $(MESA_MODULES) $(GLU_MODULES)
# $(GLU_OBJECTS):
-# cd $(GLU_DIR); $(MAKE) $< ;
+# cd $(GLU_DIR) && $(MAKE) $< ;
depend: $(DRIVER_SOURCES) $(GLU_SOURCES)
touch depend
$(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(DRIVER_SOURCES) $(GLU_SOURCES) > /dev/null
clean:
- rm -f depend $(OBJECTS)
+ -rm -f depend depend.bak $(OBJECTS)
include depend
diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index 03fbab69e39..e61b9f59cf5 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -29,6 +29,7 @@
#include "buffers.h"
#include "context.h"
#include "framebuffer.h"
+#include "mipmap.h"
#include "queryobj.h"
#include "renderbuffer.h"
#include "texcompress.h"
@@ -98,6 +99,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
driver->CopyTexSubImage1D = _swrast_copy_texsubimage1d;
driver->CopyTexSubImage2D = _swrast_copy_texsubimage2d;
driver->CopyTexSubImage3D = _swrast_copy_texsubimage3d;
+ driver->GenerateMipmap = _mesa_generate_mipmap;
driver->TestProxyTexImage = _mesa_test_proxy_teximage;
driver->CompressedTexImage1D = _mesa_store_compressed_teximage1d;
driver->CompressedTexImage2D = _mesa_store_compressed_teximage2d;
@@ -260,43 +262,6 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
/**
- * Plug in Mesa's GLSL functions.
- */
-void
-_mesa_init_glsl_driver_functions(struct dd_function_table *driver)
-{
- driver->AttachShader = _mesa_attach_shader;
- driver->BindAttribLocation = _mesa_bind_attrib_location;
- driver->CompileShader = _mesa_compile_shader;
- driver->CreateProgram = _mesa_create_program;
- driver->CreateShader = _mesa_create_shader;
- driver->DeleteProgram2 = _mesa_delete_program2;
- driver->DeleteShader = _mesa_delete_shader;
- driver->DetachShader = _mesa_detach_shader;
- driver->GetActiveAttrib = _mesa_get_active_attrib;
- driver->GetActiveUniform = _mesa_get_active_uniform;
- driver->GetAttachedShaders = _mesa_get_attached_shaders;
- driver->GetAttribLocation = _mesa_get_attrib_location;
- driver->GetHandle = _mesa_get_handle;
- driver->GetProgramiv = _mesa_get_programiv;
- driver->GetProgramInfoLog = _mesa_get_program_info_log;
- driver->GetShaderiv = _mesa_get_shaderiv;
- driver->GetShaderInfoLog = _mesa_get_shader_info_log;
- driver->GetShaderSource = _mesa_get_shader_source;
- driver->GetUniformfv = _mesa_get_uniformfv;
- driver->GetUniformLocation = _mesa_get_uniform_location;
- driver->IsProgram = _mesa_is_program;
- driver->IsShader = _mesa_is_shader;
- driver->LinkProgram = _mesa_link_program;
- driver->ShaderSource = _mesa_shader_source;
- driver->Uniform = _mesa_uniform;
- driver->UniformMatrix = _mesa_uniform_matrix;
- driver->UseProgram = _mesa_use_program;
- driver->ValidateProgram = _mesa_validate_program;
-}
-
-
-/**
* Call the ctx->Driver.* state functions with current values to initialize
* driver state.
* Only the Intel drivers use this so far.
diff --git a/src/mesa/drivers/common/driverfuncs.h b/src/mesa/drivers/common/driverfuncs.h
index 6ed23c4520e..4c90ed12f60 100644
--- a/src/mesa/drivers/common/driverfuncs.h
+++ b/src/mesa/drivers/common/driverfuncs.h
@@ -31,10 +31,6 @@ _mesa_init_driver_functions(struct dd_function_table *driver);
extern void
-_mesa_init_glsl_driver_functions(struct dd_function_table *driver);
-
-
-extern void
_mesa_init_driver_state(GLcontext *ctx);
diff --git a/src/mesa/drivers/directfb/Makefile b/src/mesa/drivers/directfb/Makefile
index c515785b2a1..dc71b385cac 100644
--- a/src/mesa/drivers/directfb/Makefile
+++ b/src/mesa/drivers/directfb/Makefile
@@ -50,5 +50,5 @@ install:
clean:
- rm -f *.o *.so
+ -rm -f *.o *.so
diff --git a/src/mesa/drivers/dri/Makefile b/src/mesa/drivers/dri/Makefile
index 69a8c553947..c6464a2a244 100644
--- a/src/mesa/drivers/dri/Makefile
+++ b/src/mesa/drivers/dri/Makefile
@@ -33,7 +33,7 @@ install:
clean:
- @for dir in $(DRI_DIRS) ; do \
+ -@for dir in $(DRI_DIRS) ; do \
if [ -d $$dir ] ; then \
(cd $$dir && $(MAKE) clean) ; \
fi \
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index b7718f50fd7..58702089e5f 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -31,6 +31,7 @@
#include "dri_util.h"
#include "drm_sarea.h"
+#include "utils.h"
#ifndef GLX_OML_sync_control
typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator);
@@ -66,6 +67,18 @@ __driUtilMessage(const char *f, ...)
}
}
+GLint
+driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
+{
+ if (rect2.x1 > rect1.x1) rect1.x1 = rect2.x1;
+ if (rect2.x2 < rect1.x2) rect1.x2 = rect2.x2;
+ if (rect2.y1 > rect1.y1) rect1.y1 = rect2.y1;
+ if (rect2.y2 < rect1.y2) rect1.y2 = rect2.y2;
+
+ if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0;
+
+ return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1);
+}
/*****************************************************************/
/** \name Context (un)binding functions */
@@ -965,117 +978,6 @@ static const __DRIextension **driGetExtensions(__DRIscreen *psp)
return psp->extensions;
}
-#define __ATTRIB(attrib, field) \
- { attrib, offsetof(__GLcontextModes, field) }
-
-static const struct { unsigned int attrib, offset; } attribMap[] = {
- __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
- __ATTRIB(__DRI_ATTRIB_LEVEL, level),
- __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
- __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
- __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
- __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
- __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits),
- __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits),
- __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
- __ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
- __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
- __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
- __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
- __ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode),
- __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
- __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
- __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
- __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
- __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
- __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
- __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
- __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
- __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
- __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets),
- __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
-
- /* The struct field doesn't matter here, these are handled by the
- * switch in driGetConfigAttribIndex. We need them in the array
- * so the iterator includes them though.*/
- __ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level),
- __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level),
- __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level)
-};
-
-#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
-
-static int
-driGetConfigAttribIndex(const __DRIconfig *config,
- unsigned int index, unsigned int *value)
-{
- switch (attribMap[index].attrib) {
- case __DRI_ATTRIB_RENDER_TYPE:
- if (config->modes.rgbMode)
- *value = __DRI_ATTRIB_RGBA_BIT;
- else
- *value = __DRI_ATTRIB_COLOR_INDEX_BIT;
- break;
- case __DRI_ATTRIB_CONFIG_CAVEAT:
- if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG)
- *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG;
- else if (config->modes.visualRating == GLX_SLOW_CONFIG)
- *value = __DRI_ATTRIB_SLOW_BIT;
- else
- *value = 0;
- break;
- case __DRI_ATTRIB_SWAP_METHOD:
- break;
-
- default:
- *value = *(unsigned int *)
- ((char *) &config->modes + attribMap[index].offset);
-
- break;
- }
-
- return GL_TRUE;
-}
-
-static int
-driGetConfigAttrib(const __DRIconfig *config,
- unsigned int attrib, unsigned int *value)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(attribMap); i++)
- if (attribMap[i].attrib == attrib)
- return driGetConfigAttribIndex(config, i, value);
-
- return GL_FALSE;
-}
-
-static int
-driIndexConfigAttrib(const __DRIconfig *config, int index,
- unsigned int *attrib, unsigned int *value)
-{
- if (index >= 0 && index < ARRAY_SIZE(attribMap)) {
- *attrib = attribMap[index].attrib;
- return driGetConfigAttribIndex(config, index, value);
- }
-
- return GL_FALSE;
-}
-
const __DRIlegacyExtension driLegacyExtension = {
{ __DRI_LEGACY, __DRI_LEGACY_VERSION },
driCreateNewScreen,
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index 06e1d20a3cf..8e1cdfc893f 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -61,7 +61,6 @@
#define GLX_BAD_CONTEXT 5
typedef struct __DRIswapInfoRec __DRIswapInfo;
-typedef struct __DRIutilversionRec2 __DRIutilversion2;
/* Typedefs to avoid rewriting the world. */
typedef struct __DRIscreenRec __DRIscreenPrivate;
@@ -536,22 +535,6 @@ struct __DRIscreenRec {
drmLock *lock;
};
-struct __DRIconfigRec {
- __GLcontextModes modes;
-};
-
-/**
- * Used to store a version which includes a major range instead of a single
- * major version number.
- */
-struct __DRIutilversionRec2 {
- int major_min; /** min allowed Major version number. */
- int major_max; /** max allowed Major version number. */
- int minor; /**< Minor version number. */
- int patch; /**< Patch-level. */
-};
-
-
extern void
__driUtilMessage(const char *f, ...);
@@ -566,4 +549,7 @@ extern float
driCalculateSwapUsage( __DRIdrawable *dPriv,
int64_t last_swap_ust, int64_t current_ust );
+extern GLint
+driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 );
+
#endif /* _DRI_UTIL_H_ */
diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c
index 237d51cf22b..7fbe0d855d0 100644
--- a/src/mesa/drivers/dri/common/utils.c
+++ b/src/mesa/drivers/dri/common/utils.c
@@ -419,21 +419,6 @@ driCheckDriDdxDrmVersions2(const char * driver_name,
drmActual, drmExpected);
}
-
-
-GLint
-driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
-{
- if (rect2.x1 > rect1.x1) rect1.x1 = rect2.x1;
- if (rect2.x2 < rect1.x2) rect1.x2 = rect2.x2;
- if (rect2.y1 > rect1.y1) rect1.y1 = rect2.y1;
- if (rect2.y2 < rect1.y2) rect1.y2 = rect2.y2;
-
- if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0;
-
- return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1);
-}
-
GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer,
GLint *x, GLint *y,
GLsizei *width, GLsizei *height )
@@ -540,68 +525,62 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type,
unsigned num_depth_stencil_bits,
const GLenum * db_modes, unsigned num_db_modes)
{
- static const u_int8_t bits_table[3][4] = {
+ static const u_int8_t bits_table[4][4] = {
/* R G B A */
+ { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */
{ 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
{ 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
{ 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
};
- /* The following arrays are all indexed by the fb_type masked with 0x07.
- * Given the four supported fb_type values, this results in valid array
- * indices of 3, 4, 5, and 7.
- */
- static const u_int32_t masks_table_rgb[8][4] = {
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ static const u_int32_t masks_table_rgb[6][4] = {
+ { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
+ { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
{ 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
{ 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
{ 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8 */
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 } /* 8_8_8_8_REV */
};
- static const u_int32_t masks_table_rgba[8][4] = {
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ static const u_int32_t masks_table_rgba[6][4] = {
+ { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
+ { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
{ 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
{ 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
{ 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8 */
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */
};
- static const u_int32_t masks_table_bgr[8][4] = {
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ static const u_int32_t masks_table_bgr[6][4] = {
+ { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
+ { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
{ 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
{ 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
{ 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8 */
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */
};
- static const u_int32_t masks_table_bgra[8][4] = {
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ static const u_int32_t masks_table_bgra[6][4] = {
+ { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
+ { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
{ 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
{ 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
{ 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8 */
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */
};
- static const u_int8_t bytes_per_pixel[8] = {
- 0, 0, 0, 2, 2, 4, 0, 4
+ static const u_int8_t bytes_per_pixel[6] = {
+ 1, /* 3_3_2 */
+ 1, /* 2_3_3_REV */
+ 2, /* 5_6_5 */
+ 2, /* 5_6_5_REV */
+ 4, /* 8_8_8_8 */
+ 4 /* 8_8_8_8_REV */
};
const u_int8_t * bits;
const u_int32_t * masks;
- const int index = fb_type & 0x07;
+ int index;
__DRIconfig **configs, **c;
__GLcontextModes *modes;
unsigned i;
@@ -610,10 +589,29 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type,
unsigned num_modes;
unsigned num_accum_bits = 2;
- if ( bytes_per_pixel[ index ] == 0 ) {
- fprintf( stderr, "[%s:%u] Framebuffer type 0x%04x has 0 bytes per pixel.\n",
- __FUNCTION__, __LINE__, fb_type );
- return NULL;
+ switch ( fb_type ) {
+ case GL_UNSIGNED_BYTE_3_3_2:
+ index = 0;
+ break;
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ index = 1;
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ index = 2;
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ index = 3;
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8:
+ index = 4;
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ index = 5;
+ break;
+ default:
+ fprintf( stderr, "[%s:%u] Unknown framebuffer type 0x%04x.\n",
+ __FUNCTION__, __LINE__, fb_type );
+ return NULL;
}
@@ -625,35 +623,41 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type,
switch ( fb_format ) {
case GL_RGB:
- bits = (bytes_per_pixel[ index ] == 2)
- ? bits_table[0] : bits_table[1];
masks = masks_table_rgb[ index ];
break;
case GL_RGBA:
- bits = (bytes_per_pixel[ index ] == 2)
- ? bits_table[0] : bits_table[2];
masks = masks_table_rgba[ index ];
break;
case GL_BGR:
- bits = (bytes_per_pixel[ index ] == 2)
- ? bits_table[0] : bits_table[1];
masks = masks_table_bgr[ index ];
break;
case GL_BGRA:
- bits = (bytes_per_pixel[ index ] == 2)
- ? bits_table[0] : bits_table[2];
masks = masks_table_bgra[ index ];
break;
default:
- fprintf( stderr, "[%s:%u] Framebuffer format 0x%04x is not GL_RGB, GL_RGBA, GL_BGR, or GL_BGRA.\n",
- __FUNCTION__, __LINE__, fb_format );
+ fprintf( stderr, "[%s:%u] Unknown framebuffer format 0x%04x.\n",
+ __FUNCTION__, __LINE__, fb_format );
return NULL;
}
+ switch ( bytes_per_pixel[ index ] ) {
+ case 1:
+ bits = bits_table[0];
+ break;
+ case 2:
+ bits = bits_table[1];
+ break;
+ default:
+ bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR))
+ ? bits_table[2]
+ : bits_table[3];
+ break;
+ }
+
num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits;
configs = _mesa_calloc((num_modes + 1) * sizeof *configs);
if (configs == NULL)
@@ -755,3 +759,114 @@ const __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b)
return all;
}
+
+#define __ATTRIB(attrib, field) \
+ { attrib, offsetof(__GLcontextModes, field) }
+
+static const struct { unsigned int attrib, offset; } attribMap[] = {
+ __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
+ __ATTRIB(__DRI_ATTRIB_LEVEL, level),
+ __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
+ __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
+ __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
+ __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
+ __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits),
+ __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits),
+ __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
+ __ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
+ __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
+ __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
+ __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
+ __ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode),
+ __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
+ __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
+ __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
+ __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
+ __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
+ __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
+ __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets),
+ __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
+
+ /* The struct field doesn't matter here, these are handled by the
+ * switch in driGetConfigAttribIndex. We need them in the array
+ * so the iterator includes them though.*/
+ __ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level),
+ __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level),
+ __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level)
+};
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+static int
+driGetConfigAttribIndex(const __DRIconfig *config,
+ unsigned int index, unsigned int *value)
+{
+ switch (attribMap[index].attrib) {
+ case __DRI_ATTRIB_RENDER_TYPE:
+ if (config->modes.rgbMode)
+ *value = __DRI_ATTRIB_RGBA_BIT;
+ else
+ *value = __DRI_ATTRIB_COLOR_INDEX_BIT;
+ break;
+ case __DRI_ATTRIB_CONFIG_CAVEAT:
+ if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG)
+ *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG;
+ else if (config->modes.visualRating == GLX_SLOW_CONFIG)
+ *value = __DRI_ATTRIB_SLOW_BIT;
+ else
+ *value = 0;
+ break;
+ case __DRI_ATTRIB_SWAP_METHOD:
+ break;
+
+ default:
+ *value = *(unsigned int *)
+ ((char *) &config->modes + attribMap[index].offset);
+
+ break;
+ }
+
+ return GL_TRUE;
+}
+
+int
+driGetConfigAttrib(const __DRIconfig *config,
+ unsigned int attrib, unsigned int *value)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(attribMap); i++)
+ if (attribMap[i].attrib == attrib)
+ return driGetConfigAttribIndex(config, i, value);
+
+ return GL_FALSE;
+}
+
+int
+driIndexConfigAttrib(const __DRIconfig *config, int index,
+ unsigned int *attrib, unsigned int *value)
+{
+ if (index >= 0 && index < ARRAY_SIZE(attribMap)) {
+ *attrib = attribMap[index].attrib;
+ return driGetConfigAttribIndex(config, index, value);
+ }
+
+ return GL_FALSE;
+}
diff --git a/src/mesa/drivers/dri/common/utils.h b/src/mesa/drivers/dri/common/utils.h
index 45a78e5ca5a..0c09a7e68fb 100644
--- a/src/mesa/drivers/dri/common/utils.h
+++ b/src/mesa/drivers/dri/common/utils.h
@@ -29,8 +29,11 @@
#ifndef DRI_DEBUG_H
#define DRI_DEBUG_H
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
#include "context.h"
-#include "dri_util.h"
+
+typedef struct __DRIutilversionRec2 __DRIutilversion2;
struct dri_debug_control {
const char * string;
@@ -84,6 +87,17 @@ struct dri_extension {
const struct dri_extension_function * functions;
};
+/**
+ * Used to store a version which includes a major range instead of a single
+ * major version number.
+ */
+struct __DRIutilversionRec2 {
+ int major_min; /** min allowed Major version number. */
+ int major_max; /** max allowed Major version number. */
+ int minor; /**< Minor version number. */
+ int patch; /**< Patch-level. */
+};
+
extern unsigned driParseDebugString( const char * debug,
const struct dri_debug_control * control );
@@ -106,12 +120,14 @@ extern GLboolean driCheckDriDdxDrmVersions3(const char * driver_name,
const __DRIversion * ddxActual, const __DRIutilversion2 * ddxExpected,
const __DRIversion * drmActual, const __DRIversion * drmExpected);
-extern GLint driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 );
-
extern GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer,
GLint *x, GLint *y,
GLsizei *width, GLsizei *height );
+struct __DRIconfigRec {
+ __GLcontextModes modes;
+};
+
extern __DRIconfig **
driCreateConfigs(GLenum fb_format, GLenum fb_type,
const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
@@ -120,4 +136,11 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type,
const __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b);
+int
+driGetConfigAttrib(const __DRIconfig *config,
+ unsigned int attrib, unsigned int *value);
+int
+driIndexConfigAttrib(const __DRIconfig *config, int index,
+ unsigned int *attrib, unsigned int *value);
+
#endif /* DRI_DEBUG_H */
diff --git a/src/mesa/drivers/dri/common/vblank.c b/src/mesa/drivers/dri/common/vblank.c
index e81cc6886f2..dc2cbcc84d4 100644
--- a/src/mesa/drivers/dri/common/vblank.c
+++ b/src/mesa/drivers/dri/common/vblank.c
@@ -260,8 +260,8 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd )
if ( first_time ) {
fprintf(stderr,
"%s: drmWaitVBlank returned %d, IRQs don't seem to be"
- " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH"
- " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret);
+ " working correctly.\nTry adjusting the vblank_mode"
+ " configuration parameter.\n", __FUNCTION__, ret);
first_time = GL_FALSE;
}
diff --git a/src/mesa/drivers/dri/common/xmlpool/Makefile b/src/mesa/drivers/dri/common/xmlpool/Makefile
index b077809cd18..62ec919ea68 100644
--- a/src/mesa/drivers/dri/common/xmlpool/Makefile
+++ b/src/mesa/drivers/dri/common/xmlpool/Makefile
@@ -57,8 +57,8 @@ all: options.h
# Only intermediate files are cleaned up. options.h is not deleted because
# it's in CVS.
clean:
- rm -f $(POT) *~
- rm -rf $(LANGS)
+ -rm -f $(POT) *~
+ -rm -rf $(LANGS)
# Default target options.h
options.h: t_options.h mo
diff --git a/src/mesa/drivers/dri/glcore/Makefile b/src/mesa/drivers/dri/glcore/Makefile
deleted file mode 100644
index 968190acfc0..00000000000
--- a/src/mesa/drivers/dri/glcore/Makefile
+++ /dev/null
@@ -1,84 +0,0 @@
-# src/mesa/drivers/dri/glcore/Makefile
-
-TOP = ../../../../..
-include $(TOP)/configs/current
-
-LIBNAME = glcore_dri.so
-
-DRIVER_SOURCES = glcore_driver.c \
- $(TOP)/src/mesa/drivers/common/driverfuncs.c \
- ../common/dri_util.c
-
-C_SOURCES = \
- $(DRIVER_SOURCES) \
- $(DRI_SOURCES)
-
-
-# Include directories
-INCLUDE_DIRS = \
- -I. \
- -I../common \
- -I../dri_client \
- -I../dri_client/imports \
- -Iserver \
- -I$(TOP)/include \
- -I$(DRM_SOURCE_PATH)/shared-core \
- -I$(TOP)/src/mesa \
- -I$(TOP)/src/mesa/main \
- -I$(TOP)/src/mesa/glapi \
- -I$(TOP)/src/mesa/math \
- -I$(TOP)/src/mesa/transform \
- -I$(TOP)/src/mesa/shader \
- -I$(TOP)/src/mesa/swrast \
- -I$(TOP)/src/mesa/swrast_setup
-
-# Core Mesa objects
-MESA_MODULES = $(TOP)/src/mesa/libmesa.a
-
-# Libraries that the driver shared lib depends on
-LIB_DEPS = -lm -lpthread -lc
-# LIB_DEPS = -lGL -lm -lpthread -lc
-
-
-ASM_SOURCES =
-
-OBJECTS = $(C_SOURCES:.c=.o) \
- $(ASM_SOURCES:.S=.o)
-
-
-##### RULES #####
-
-.c.o:
- $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(DEFINES) $< -o $@
-
-.S.o:
- $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(DEFINES) $< -o $@
-
-
-##### TARGETS #####
-
-default: depend $(TOP)/$(LIB_DIR)/$(LIBNAME)
-
-
-$(TOP)/$(LIB_DIR)/$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile
- CC="$(CC)" CXX="$(CXX)" $(TOP)/bin/mklib -o $(LIBNAME) -noprefix \
- -ldflags '$(LDFLAGS)' -install $(TOP)/$(LIB_DIR) \
- $(OBJECTS) $(WINLIB) $(LIB_DEPS) $(WINOBJ) $(MESA_MODULES)
-
-
-depend: $(C_SOURCES) $(ASM_SOURCES)
- touch depend
- $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDE_DIRS) $(C_SOURCES) $(ASM_SOURCES) \
- > /dev/null
-
-
-# Emacs tags
-tags:
- etags `find . -name \*.[ch]` `find ../include`
-
-
-clean:
- -rm -f *.o server/*.o
-
-
-include depend
diff --git a/src/mesa/drivers/dri/glcore/glcore_driver.c b/src/mesa/drivers/dri/glcore/glcore_driver.c
deleted file mode 100644
index 25778160419..00000000000
--- a/src/mesa/drivers/dri/glcore/glcore_driver.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2006 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * This implements a software-only "DRI" driver. It doesn't actually speak
- * any DRI protocol or talk to the DRM, it just looks enough like a DRI driver
- * that libglx in the server can load it for software rendering in the
- * unaccelerated case.
- */
-
-static GLboolean
-glcoreInitDriver(__DRIscreenPrivate *driScreenPriv)
-{
-}
-
-static void
-glcoreDestroyScreen(__DRIScreenPrivate *driScreenPriv)
-{
-}
-
-static GLboolean
-glcoreCreateContext(const __GLcontextModes *glVisual,
- __DRIcontextPrivate *driContextPriv,
- void *shared_context)
-{
-}
-
-static void
-glcoreDestroyContext(__DRIcontextPrivate *driContextPriv)
-{
-}
-
-static GLboolean
-glcoreCreateBuffer(__DRIscreenPrivate *driScreenPriv,
- __DRIdrawablePrivate *driDrawablePriv,
- const __GLcontextModes *mesaVisual,
- GLboolean isPixmap)
-{
-}
-
-static void
-glcoreDestroyBuffer(__DRIdrawablePrivate *driDrawablePriv)
-{
-}
-
-static void
-glcoreSwapBuffers(__DRIdrawablePrivate *driDrawablePriv)
-{
-}
-
-static GLboolean
-glcoreMakeCurrent(__DRIcontextPrivate *driContextPriv,
- __DRIdrawablePrivate *driDrawablePriv,
- __DRIdrawablePrivate *driReadablePriv)
-{
-}
-
-static GLboolean
-glcoreUnbindContext(__DRIcontextPrivate *driContextPriv)
-{
-}
-
-static struct __DriverAPIRec glcore_api = {
- .InitDriver = glcoreInitDriver,
- .DestroyScreen = glcoreDestroyScreen,
- .CreateContext = glcoreCreateContext,
- .DestroyContext = glcoreDestroyContext,
- .CreateBuffer = glcoreCreateBuffer,
- .DestroyBuffer = glcoreDestroyBuffer,
- .SwapBuffers = glcoreSwapBuffers,
- .MakeCurrent = glcoreMakeCurrent,
- .UnbindContext = glcoreUnbindContext,
-};
-
-static __GLcontextModes *
-glcoreFillInModes(unsigned pixel_bits)
-{
-}
-
-PUBLIC void *
-__driCreateNewScreen_20050727(__DRInativeDisplay *dpy, int scrn,
- __DRIscreen *psc, const __GLcontextModes *modes,
- const __DRIversion *ddx_version,
- const __DRIversion *dri_version,
- const __DRIversion *drm_version,
- const __DRIframebuffer *fb, drmAddress pSarea,
- int fd, int internal_api_version,
- const ___DRIinterfaceMethods *interface,
- __GLcontextModes **driver_modes)
-{
- __DRIscreenPrivate *driScreenPriv;
- glcoreDriverPrivate *glcoreDriverPriv;
-
- /* would normally check ddx/dri/drm versions here */
-
- driScreenPriv = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, ddx_version,
- dri_version, drm_version, fb,
- internal_api_version, &glcore_api);
- if (!driScreenPriv)
- return NULL;
-
- glcoreDriverPriv = driScreenPriv->pDrvPriv;
-
- *driver_modes = glcoreFillInModes(glcoreDriverPriv->bpp);
-
- driInitExtensions(NULL, NULL, GL_FALSE);
-
- return driScreenPriv;
-}
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 6124ab6b0f0..f90c5f7b082 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -257,10 +257,12 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
struct intel_context *intel = intel_context(ctx);
struct brw_context *brw = brw_context(ctx);
GLboolean retval = GL_FALSE;
- GLuint i, ret;
+ GLuint i;
GLuint ib_offset;
dri_bo *ib_bo;
GLboolean force_flush = GL_FALSE;
+ int ret;
+
if (ctx->NewState)
_mesa_update_state( ctx );
@@ -316,6 +318,14 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
goto flush;
}
+ /* Various fallback checks:
+ */
+ if (brw->intel.Fallback)
+ goto out;
+
+ if (check_fallbacks( brw, prim, nr_prims ))
+ goto out;
+
/* need to account for index buffer and vertex buffer */
if (ib) {
ret = brw_prepare_indices( brw, ib , &ib_bo, &ib_offset);
@@ -333,16 +343,6 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
force_flush = GL_TRUE;
goto flush;
}
-
-
-
- /* Various fallback checks:
- */
- if (brw->intel.Fallback)
- goto out;
-
- if (check_fallbacks( brw, prim, nr_prims ))
- goto out;
/* Upload index, vertex data:
*/
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index aa985d68b69..2d99238ddcd 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -404,6 +404,7 @@ int brw_prepare_vertices( struct brw_context *brw,
*/
copy_array_to_vbo_array(brw, upload[0], interleave);
+ ret |= dri_bufmgr_check_aperture_space(upload[0]->bo);
for (i = 1; i < nr_uploads; i++) {
/* Then, just point upload[i] at upload[0]'s buffer. */
upload[i]->stride = interleave;
@@ -416,13 +417,13 @@ int brw_prepare_vertices( struct brw_context *brw,
else {
/* Upload non-interleaved arrays */
for (i = 0; i < nr_uploads; i++) {
- copy_array_to_vbo_array(brw, upload[i], upload[i]->element_size);
+ copy_array_to_vbo_array(brw, upload[i], upload[i]->element_size);
+ if (upload[i]->bo) {
+ ret |= dri_bufmgr_check_aperture_space(upload[i]->bo);
+ }
}
}
- if (brw->vb.upload.bo) {
- ret |= dri_bufmgr_check_aperture_space(brw->vb.upload.bo);
- }
if (ret)
return 1;
diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c
index 329af0d1b04..f1d6a6dbfc0 100644
--- a/src/mesa/drivers/dri/intel/intel_tex.c
+++ b/src/mesa/drivers/dri/intel/intel_tex.c
@@ -172,14 +172,13 @@ timed_memcpy(void *dest, const void *src, size_t n)
*/
void
intel_generate_mipmap(GLcontext *ctx, GLenum target,
- const struct gl_texture_unit *texUnit,
struct gl_texture_object *texObj)
{
struct intel_texture_object *intelObj = intel_texture_object(texObj);
GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
int face, i;
- _mesa_generate_mipmap(ctx, target, texUnit, texObj);
+ _mesa_generate_mipmap(ctx, target, texObj);
/* Update the level information in our private data in the new images, since
* it didn't get set as part of a normal TexImage path.
@@ -198,6 +197,15 @@ intel_generate_mipmap(GLcontext *ctx, GLenum target,
}
}
+static void intelGenerateMipmap(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj)
+{
+ struct intel_context *intel = intel_context(ctx);
+ struct intel_texture_object *intelObj = intel_texture_object(texObj);
+
+ intel_tex_map_images(intel, intelObj);
+ intel_generate_mipmap(ctx, target, texObj);
+ intel_tex_unmap_images(intel, intelObj);
+}
void
intelInitTextureFuncs(struct dd_function_table *functions)
@@ -221,6 +229,7 @@ intelInitTextureFuncs(struct dd_function_table *functions)
functions->CopyTexSubImage2D = _swrast_copy_texsubimage2d;
#endif
functions->GetTexImage = intelGetTexImage;
+ functions->GenerateMipmap = intelGenerateMipmap;
/* compressed texture functions */
functions->CompressedTexImage2D = intelCompressedTexImage2D;
diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h
index 3a87137cc9e..60ab8203e52 100644
--- a/src/mesa/drivers/dri/intel/intel_tex.h
+++ b/src/mesa/drivers/dri/intel/intel_tex.h
@@ -151,7 +151,6 @@ void intel_tex_unmap_images(struct intel_context *intel,
int intel_compressed_num_bytes(GLuint mesaFormat);
void intel_generate_mipmap(GLcontext *ctx, GLenum target,
- const struct gl_texture_unit *texUnit,
struct gl_texture_object *texObj);
#endif
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
index 7facc469f48..1add7c6188c 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
@@ -161,9 +161,7 @@ do_copy_texsubimage(struct intel_context *intel,
/* GL_SGIS_generate_mipmap */
if (intelImage->level == texObj->BaseLevel && texObj->GenerateMipmap) {
- intel_generate_mipmap(ctx, target,
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
- texObj);
+ intel_generate_mipmap(ctx, target, texObj);
}
return GL_TRUE;
diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
index bcb65835c6b..95ddbd59202 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_image.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
@@ -522,9 +522,7 @@ intelTexImage(GLcontext * ctx,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- intel_generate_mipmap(ctx, target,
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
- texObj);
+ intel_generate_mipmap(ctx, target, texObj);
}
_mesa_unmap_teximage_pbo(ctx, unpack);
diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
index 78621814c3a..5428a1d0689 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
@@ -103,9 +103,7 @@ intelTexSubimage(GLcontext * ctx,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- intel_generate_mipmap(ctx, target,
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
- texObj);
+ intel_generate_mipmap(ctx, target, texObj);
}
_mesa_unmap_teximage_pbo(ctx, packing);
diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
index 8b0da0db4e0..acdd72b74b4 100644
--- a/src/mesa/drivers/dri/r300/r300_reg.h
+++ b/src/mesa/drivers/dri/r300/r300_reg.h
@@ -67,7 +67,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/*
* Vertex Array Processing (VAP) Control
- * Stolen from r200 code from Christoph Brill (It's a guess!)
*/
#define R300_VAP_CNTL 0x2080
# define R300_PVS_NUM_SLOTS_SHIFT 0
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index 6f1f4aac74a..cb39ce01106 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -1891,9 +1891,11 @@ static inline void r300SetupVertexProgramFragment(r300ContextPtr r300, int dest,
}
}
-#define MIN3(a,b,c) ((a)<(b) ? MIN2(a, c): MIN2(b, c))
+#define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c))
-static void r300VapCntl(r300ContextPtr rmesa, GLuint input_count, GLuint output_count, GLuint temp_count)
+
+static void r300VapCntl(r300ContextPtr rmesa, GLuint input_count,
+ GLuint output_count, GLuint temp_count)
{
int vtx_mem_size;
int pvs_num_slots;
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
index e91d96852db..861f0427cf5 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
@@ -1426,6 +1426,8 @@ void r300SelectVertexShader(r300ContextPtr r300)
GLint wpos_idx;
vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
+ wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead;
+ wanted_key.OutputsWritten = vpc->mesa_program.Base.OutputsWritten;
InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
wpos_idx = -1;
@@ -1439,11 +1441,9 @@ void r300SelectVertexShader(r300ContextPtr r300)
_mesa_exit(-1);
}
- InputsRead |= (FRAG_BIT_TEX0 << i);
+ wanted_key.OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i);
wpos_idx = i;
}
- wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead;
- wanted_key.OutputsWritten = vpc->mesa_program.Base.OutputsWritten;
add_outputs(&wanted_key, VERT_RESULT_HPOS);
diff --git a/src/mesa/drivers/dri/swrast/Makefile b/src/mesa/drivers/dri/swrast/Makefile
new file mode 100644
index 00000000000..5f3a4f2191b
--- /dev/null
+++ b/src/mesa/drivers/dri/swrast/Makefile
@@ -0,0 +1,24 @@
+# src/mesa/drivers/dri/swrast/Makefile
+
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = swrast_dri.so
+
+DRIVER_SOURCES = \
+ swrast.c \
+ swrast_span.c
+
+C_SOURCES = \
+ $(SWRAST_COMMON_SOURCES) \
+ $(DRIVER_SOURCES)
+
+ASM_SOURCES =
+
+SWRAST_COMMON_SOURCES = \
+ ../../common/driverfuncs.c \
+ ../common/utils.c
+
+include ../Makefile.template
+
+symlinks:
diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c
new file mode 100644
index 00000000000..c4dba591987
--- /dev/null
+++ b/src/mesa/drivers/dri/swrast/swrast.c
@@ -0,0 +1,727 @@
+/*
+ * Copyright (C) 2008 George Sapountzis <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * DRI software rasterizer
+ *
+ * This is the mesa swrast module packaged into a DRI driver structure.
+ *
+ * The front-buffer is allocated by the loader. The loader provides read/write
+ * callbacks for access to the front-buffer. The driver uses a scratch row for
+ * front-buffer rendering to avoid repeated calls to the loader.
+ *
+ * The back-buffer is allocated by the driver and is private.
+ */
+
+#include "context.h"
+#include "extensions.h"
+#include "framebuffer.h"
+#include "imports.h"
+#include "renderbuffer.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+#include "vbo/vbo.h"
+#include "drivers/common/driverfuncs.h"
+
+#include "swrast_priv.h"
+
+
+#define need_GL_VERSION_1_3
+#define need_GL_VERSION_1_4
+#define need_GL_VERSION_1_5
+#define need_GL_VERSION_2_0
+
+/* sw extensions for imaging */
+#define need_GL_EXT_blend_color
+#define need_GL_EXT_blend_minmax
+#define need_GL_EXT_convolution
+#define need_GL_EXT_histogram
+#define need_GL_SGI_color_table
+
+/* sw extensions not associated with some GL version */
+#define need_GL_ARB_shader_objects
+#define need_GL_ARB_vertex_program
+#define need_GL_APPLE_vertex_array_object
+#define need_GL_ATI_fragment_shader
+#define need_GL_EXT_depth_bounds_test
+#define need_GL_EXT_framebuffer_object
+#define need_GL_EXT_framebuffer_blit
+#define need_GL_EXT_gpu_program_parameters
+#define need_GL_EXT_paletted_texture
+#define need_GL_IBM_multimode_draw_arrays
+#define need_GL_MESA_resize_buffers
+#define need_GL_NV_vertex_program
+#define need_GL_NV_fragment_program
+
+#include "extension_helper.h"
+#include "utils.h"
+
+const struct dri_extension card_extensions[] =
+{
+ { "GL_VERSION_1_3", GL_VERSION_1_3_functions },
+ { "GL_VERSION_1_4", GL_VERSION_1_4_functions },
+ { "GL_VERSION_1_5", GL_VERSION_1_5_functions },
+ { "GL_VERSION_2_0", GL_VERSION_2_0_functions },
+
+ { "GL_EXT_blend_color", GL_EXT_blend_color_functions },
+ { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions },
+ { "GL_EXT_convolution", GL_EXT_convolution_functions },
+ { "GL_EXT_histogram", GL_EXT_histogram_functions },
+ { "GL_SGI_color_table", GL_SGI_color_table_functions },
+
+ { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions },
+ { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
+ { "GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions },
+ { "GL_ATI_fragment_shader", GL_ATI_fragment_shader_functions },
+ { "GL_EXT_depth_bounds_test", GL_EXT_depth_bounds_test_functions },
+ { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
+ { "GL_EXT_framebuffer_blit", GL_EXT_framebuffer_blit_functions },
+ { "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions },
+ { "GL_EXT_paletted_texture", GL_EXT_paletted_texture_functions },
+ { "GL_IBM_multimode_draw_arrays", GL_IBM_multimode_draw_arrays_functions },
+ { "GL_MESA_resize_buffers", GL_MESA_resize_buffers_functions },
+ { "GL_NV_vertex_program", GL_NV_vertex_program_functions },
+ { "GL_NV_fragment_program", GL_NV_fragment_program_functions },
+ { NULL, NULL }
+};
+
+
+/**
+ * Screen and config-related functions
+ */
+
+static void
+setupLoaderExtensions(__DRIscreen *psp,
+ const __DRIextension **extensions)
+{
+ int i;
+
+ for (i = 0; extensions[i]; i++) {
+ if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0)
+ psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i];
+ }
+}
+
+static __DRIconfig **
+swrastFillInModes(__DRIscreen *psp,
+ unsigned pixel_bits, unsigned depth_bits,
+ unsigned stencil_bits, GLboolean have_back_buffer)
+{
+ __DRIconfig **configs;
+ unsigned depth_buffer_factor;
+ unsigned back_buffer_factor;
+ GLenum fb_format;
+ GLenum fb_type;
+
+ /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
+ * support pageflipping at all.
+ */
+ static const GLenum back_buffer_modes[] = {
+ GLX_NONE, GLX_SWAP_UNDEFINED_OML
+ };
+
+ u_int8_t depth_bits_array[4];
+ u_int8_t stencil_bits_array[4];
+
+ depth_bits_array[0] = 0;
+ depth_bits_array[1] = 0;
+ depth_bits_array[2] = depth_bits;
+ depth_bits_array[3] = depth_bits;
+
+ /* Just like with the accumulation buffer, always provide some modes
+ * with a stencil buffer.
+ */
+ stencil_bits_array[0] = 0;
+ stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
+ stencil_bits_array[2] = 0;
+ stencil_bits_array[3] = (stencil_bits == 0) ? 8 : stencil_bits;
+
+ depth_buffer_factor = 4;
+ back_buffer_factor = 2;
+
+ if (pixel_bits == 8) {
+ fb_format = GL_RGB;
+ fb_type = GL_UNSIGNED_BYTE_2_3_3_REV;
+ }
+ else if (pixel_bits == 16) {
+ fb_format = GL_RGB;
+ fb_type = GL_UNSIGNED_SHORT_5_6_5;
+ }
+ else {
+ fb_format = GL_BGRA;
+ fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ }
+
+ configs = driCreateConfigs(fb_format, fb_type,
+ depth_bits_array, stencil_bits_array,
+ depth_buffer_factor, back_buffer_modes,
+ back_buffer_factor);
+ if (configs == NULL) {
+ fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
+ __LINE__);
+ return NULL;
+ }
+
+ return configs;
+}
+
+static __DRIscreen *
+driCreateNewScreen(int scrn, const __DRIextension **extensions,
+ const __DRIconfig ***driver_configs, void *data)
+{
+ static const __DRIextension *emptyExtensionList[] = { NULL };
+ __DRIscreen *psp;
+ __DRIconfig **configs8, **configs16, **configs32;
+
+ (void) data;
+
+ TRACE;
+
+ psp = _mesa_calloc(sizeof(*psp));
+ if (!psp)
+ return NULL;
+
+ setupLoaderExtensions(psp, extensions);
+
+ psp->num = scrn;
+ psp->extensions = emptyExtensionList;
+
+ configs8 = swrastFillInModes(psp, 8, 8, 0, 1);
+ configs16 = swrastFillInModes(psp, 16, 16, 0, 1);
+ configs32 = swrastFillInModes(psp, 32, 24, 8, 1);
+
+ configs16 = (__DRIconfig **)driConcatConfigs(configs8, configs16);
+
+ *driver_configs = driConcatConfigs(configs16, configs32);
+
+ driInitExtensions( NULL, card_extensions, GL_FALSE );
+
+ return psp;
+}
+
+static void driDestroyScreen(__DRIscreen *psp)
+{
+ TRACE;
+
+ if (psp) {
+ _mesa_free(psp);
+ }
+}
+
+static const __DRIextension **driGetExtensions(__DRIscreen *psp)
+{
+ TRACE;
+
+ return psp->extensions;
+}
+
+
+/**
+ * Framebuffer and renderbuffer-related functions.
+ */
+
+static GLuint
+choose_pixel_format(const GLvisual *v)
+{
+ if (v->rgbMode) {
+ int bpp = v->rgbBits;
+
+ if (bpp == 32
+ && v->redMask == 0xff0000
+ && v->greenMask == 0x00ff00
+ && v->blueMask == 0x0000ff)
+ return PF_A8R8G8B8;
+ else if (bpp == 16
+ && v->redMask == 0xf800
+ && v->greenMask == 0x07e0
+ && v->blueMask == 0x001f)
+ return PF_R5G6B5;
+ else if (bpp == 8
+ && v->redMask == 0x07
+ && v->greenMask == 0x38
+ && v->blueMask == 0xc0)
+ return PF_R3G3B2;
+ }
+ else {
+ if (v->indexBits == 8)
+ return PF_CI8;
+ }
+
+ _mesa_problem( NULL, "unexpected format in %s", __FUNCTION__ );
+ return 0;
+}
+
+static void
+swrast_delete_renderbuffer(struct gl_renderbuffer *rb)
+{
+ TRACE;
+
+ _mesa_free(rb->Data);
+ _mesa_free(rb);
+}
+
+static GLboolean
+swrast_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLenum internalFormat, GLuint width, GLuint height)
+{
+ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+ int bpp;
+ unsigned mask = PITCH_ALIGN_BITS - 1;
+
+ TRACE;
+
+ rb->Data = NULL;
+ rb->Width = width;
+ rb->Height = height;
+
+ switch (internalFormat) {
+ case GL_RGB:
+ bpp = rb->RedBits + rb->GreenBits + rb->BlueBits;
+ break;
+ case GL_RGBA:
+ bpp = rb->RedBits + rb->GreenBits + rb->BlueBits + rb->AlphaBits;
+ break;
+ case GL_COLOR_INDEX8_EXT:
+ bpp = rb->IndexBits;
+ break;
+ default:
+ _mesa_problem( NULL, "unexpected format in %s", __FUNCTION__ );
+ return GL_FALSE;
+ }
+
+ /* always pad to PITCH_ALIGN_BITS */
+ xrb->pitch = ((width * bpp + mask) & ~mask) / 8;
+
+ return GL_TRUE;
+}
+
+static GLboolean
+swrast_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLenum internalFormat, GLuint width, GLuint height)
+{
+ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+
+ TRACE;
+
+ _mesa_free(rb->Data);
+
+ (void) swrast_alloc_front_storage(ctx, rb, internalFormat, width, height);
+
+ rb->Data = _mesa_malloc(height * xrb->pitch);
+
+ return GL_TRUE;
+}
+
+static struct swrast_renderbuffer *
+swrast_new_renderbuffer(const GLvisual *visual, GLboolean front)
+{
+ struct swrast_renderbuffer *xrb = _mesa_calloc(sizeof *xrb);
+ GLuint pixel_format;
+
+ TRACE;
+
+ if (xrb) {
+ _mesa_init_renderbuffer(&xrb->Base, 0);
+
+ pixel_format = choose_pixel_format(visual);
+
+ xrb->Base.Delete = swrast_delete_renderbuffer;
+ if (front) {
+ xrb->Base.AllocStorage = swrast_alloc_front_storage;
+ swrast_set_span_funcs_front(xrb, pixel_format);
+ }
+ else {
+ xrb->Base.AllocStorage = swrast_alloc_back_storage;
+ swrast_set_span_funcs_back(xrb, pixel_format);
+ }
+
+ switch (pixel_format) {
+ case PF_A8R8G8B8:
+ xrb->Base.InternalFormat = GL_RGBA;
+ xrb->Base._BaseFormat = GL_RGBA;
+ xrb->Base.DataType = GL_UNSIGNED_BYTE;
+ xrb->Base.RedBits = 8 * sizeof(GLubyte);
+ xrb->Base.GreenBits = 8 * sizeof(GLubyte);
+ xrb->Base.BlueBits = 8 * sizeof(GLubyte);
+ xrb->Base.AlphaBits = 8 * sizeof(GLubyte);
+ break;
+ case PF_R5G6B5:
+ xrb->Base.InternalFormat = GL_RGB;
+ xrb->Base._BaseFormat = GL_RGB;
+ xrb->Base.DataType = GL_UNSIGNED_BYTE;
+ xrb->Base.RedBits = 5 * sizeof(GLubyte);
+ xrb->Base.GreenBits = 6 * sizeof(GLubyte);
+ xrb->Base.BlueBits = 5 * sizeof(GLubyte);
+ xrb->Base.AlphaBits = 0;
+ break;
+ case PF_R3G3B2:
+ xrb->Base.InternalFormat = GL_RGB;
+ xrb->Base._BaseFormat = GL_RGB;
+ xrb->Base.DataType = GL_UNSIGNED_BYTE;
+ xrb->Base.RedBits = 3 * sizeof(GLubyte);
+ xrb->Base.GreenBits = 3 * sizeof(GLubyte);
+ xrb->Base.BlueBits = 2 * sizeof(GLubyte);
+ xrb->Base.AlphaBits = 0;
+ break;
+ case PF_CI8:
+ xrb->Base.InternalFormat = GL_COLOR_INDEX8_EXT;
+ xrb->Base._BaseFormat = GL_COLOR_INDEX;
+ xrb->Base.DataType = GL_UNSIGNED_BYTE;
+ xrb->Base.IndexBits = 8 * sizeof(GLubyte);
+ break;
+ default:
+ return NULL;
+ }
+ }
+ return xrb;
+}
+
+static __DRIdrawable *
+driCreateNewDrawable(__DRIscreen *screen,
+ const __DRIconfig *config, void *data)
+{
+ __DRIdrawable *buf;
+ struct swrast_renderbuffer *frontrb, *backrb;
+
+ TRACE;
+
+ buf = _mesa_calloc(sizeof *buf);
+ if (!buf)
+ return NULL;
+
+ buf->loaderPrivate = data;
+
+ buf->driScreenPriv = screen;
+
+ buf->row = _mesa_malloc(MAX_WIDTH * 4);
+
+ /* basic framebuffer setup */
+ _mesa_initialize_framebuffer(&buf->Base, &config->modes);
+
+ /* add front renderbuffer */
+ frontrb = swrast_new_renderbuffer(&config->modes, GL_TRUE);
+ _mesa_add_renderbuffer(&buf->Base, BUFFER_FRONT_LEFT, &frontrb->Base);
+
+ /* add back renderbuffer */
+ if (config->modes.doubleBufferMode) {
+ backrb = swrast_new_renderbuffer(&config->modes, GL_FALSE);
+ _mesa_add_renderbuffer(&buf->Base, BUFFER_BACK_LEFT, &backrb->Base);
+ }
+
+ /* add software renderbuffers */
+ _mesa_add_soft_renderbuffers(&buf->Base,
+ GL_FALSE, /* color */
+ config->modes.haveDepthBuffer,
+ config->modes.haveStencilBuffer,
+ config->modes.haveAccumBuffer,
+ GL_FALSE, /* alpha */
+ GL_FALSE /* aux bufs */);
+
+ return buf;
+}
+
+static void
+driDestroyDrawable(__DRIdrawable *buf)
+{
+ TRACE;
+
+ if (buf) {
+ struct gl_framebuffer *fb = &buf->Base;
+
+ _mesa_free(buf->row);
+
+ fb->DeletePending = GL_TRUE;
+ _mesa_unreference_framebuffer(&fb);
+ }
+}
+
+static void driSwapBuffers(__DRIdrawable *buf)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ struct swrast_renderbuffer *frontrb =
+ swrast_renderbuffer(buf->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
+ struct swrast_renderbuffer *backrb =
+ swrast_renderbuffer(buf->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+
+ __DRIscreen *screen = buf->driScreenPriv;
+
+ TRACE;
+
+ /* check for signle-buffered */
+ if (backrb == NULL)
+ return;
+
+ /* check if swapping currently bound buffer */
+ if (ctx && ctx->DrawBuffer == &(buf->Base)) {
+ /* flush pending rendering */
+ _mesa_notifySwapBuffers(ctx);
+ }
+
+ screen->swrast_loader->putImage(buf, __DRI_SWRAST_IMAGE_OP_SWAP,
+ 0, 0,
+ frontrb->Base.Width,
+ frontrb->Base.Height,
+ backrb->Base.Data,
+ buf->loaderPrivate);
+}
+
+
+/**
+ * General device driver functions.
+ */
+
+static void
+get_window_size( GLframebuffer *fb, GLsizei *w, GLsizei *h )
+{
+ __DRIdrawable *buf = swrast_drawable(fb);
+ __DRIscreen *screen = buf->driScreenPriv;
+ int x, y;
+
+ screen->swrast_loader->getDrawableInfo(buf,
+ &x, &y, w, h,
+ buf->loaderPrivate);
+}
+
+static void
+swrast_check_and_update_window_size( GLcontext *ctx, GLframebuffer *fb )
+{
+ GLsizei width, height;
+
+ get_window_size(fb, &width, &height);
+ if (fb->Width != width || fb->Height != height) {
+ _mesa_resize_framebuffer(ctx, fb, width, height);
+ }
+}
+
+static const GLubyte *
+get_string(GLcontext *ctx, GLenum pname)
+{
+ (void) ctx;
+ switch (pname) {
+ case GL_VENDOR:
+ return (const GLubyte *) "Mesa Project";
+ case GL_RENDERER:
+ return (const GLubyte *) "Software Rasterizer";
+ default:
+ return NULL;
+ }
+}
+
+static void
+update_state( GLcontext *ctx, GLuint new_state )
+{
+ /* not much to do here - pass it on */
+ _swrast_InvalidateState( ctx, new_state );
+ _swsetup_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
+ _tnl_InvalidateState( ctx, new_state );
+}
+
+static void
+viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ GLframebuffer *draw = ctx->WinSysDrawBuffer;
+ GLframebuffer *read = ctx->WinSysReadBuffer;
+
+ swrast_check_and_update_window_size(ctx, draw);
+ swrast_check_and_update_window_size(ctx, read);
+}
+
+static void
+swrast_init_driver_functions(struct dd_function_table *driver)
+{
+ driver->GetString = get_string;
+ driver->UpdateState = update_state;
+ driver->GetBufferSize = NULL;
+ driver->Viewport = viewport;
+}
+
+
+/**
+ * Context-related functions.
+ */
+
+static __DRIcontext *
+driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
+ __DRIcontext *shared, void *data)
+{
+ __DRIcontext *ctx;
+ GLcontext *mesaCtx;
+ struct dd_function_table functions;
+
+ TRACE;
+
+ ctx = _mesa_calloc(sizeof *ctx);
+ if (!ctx)
+ return NULL;
+
+ ctx->loaderPrivate = data;
+
+ ctx->driScreenPriv = screen;
+
+ /* build table of device driver functions */
+ _mesa_init_driver_functions(&functions);
+ swrast_init_driver_functions(&functions);
+
+ if (!_mesa_initialize_context(&ctx->Base, &config->modes,
+ shared ? &shared->Base : NULL,
+ &functions, (void *) ctx)) {
+ _mesa_free(ctx);
+ return NULL;
+ }
+
+ mesaCtx = &ctx->Base;
+
+ /* do bounds checking to prevent segfaults and server crashes! */
+ mesaCtx->Const.CheckArrayBounds = GL_TRUE;
+
+ /* create module contexts */
+ _swrast_CreateContext( mesaCtx );
+ _vbo_CreateContext( mesaCtx );
+ _tnl_CreateContext( mesaCtx );
+ _swsetup_CreateContext( mesaCtx );
+ _swsetup_Wakeup( mesaCtx );
+
+ /* use default TCL pipeline */
+ {
+ TNLcontext *tnl = TNL_CONTEXT(mesaCtx);
+ tnl->Driver.RunPipeline = _tnl_run_pipeline;
+ }
+
+ _mesa_enable_sw_extensions(mesaCtx);
+ _mesa_enable_1_3_extensions(mesaCtx);
+ _mesa_enable_1_4_extensions(mesaCtx);
+ _mesa_enable_1_5_extensions(mesaCtx);
+ _mesa_enable_2_0_extensions(mesaCtx);
+ _mesa_enable_2_1_extensions(mesaCtx);
+
+ return ctx;
+}
+
+static void
+driDestroyContext(__DRIcontext *ctx)
+{
+ GLcontext *mesaCtx;
+ TRACE;
+
+ if (ctx) {
+ mesaCtx = &ctx->Base;
+ _swsetup_DestroyContext( mesaCtx );
+ _swrast_DestroyContext( mesaCtx );
+ _tnl_DestroyContext( mesaCtx );
+ _vbo_DestroyContext( mesaCtx );
+ _mesa_destroy_context( mesaCtx );
+ }
+}
+
+static int
+driCopyContext(__DRIcontext *dst, __DRIcontext *src, unsigned long mask)
+{
+ TRACE;
+
+ _mesa_copy_context(&src->Base, &dst->Base, mask);
+ return GL_TRUE;
+}
+
+static int driBindContext(__DRIcontext *ctx,
+ __DRIdrawable *draw,
+ __DRIdrawable *read)
+{
+ GLcontext *mesaCtx;
+ GLframebuffer *mesaDraw;
+ GLframebuffer *mesaRead;
+ TRACE;
+
+ if (ctx) {
+ if (!draw || !read)
+ return GL_FALSE;
+
+ mesaCtx = &ctx->Base;
+ mesaDraw = &draw->Base;
+ mesaRead = &read->Base;
+
+ /* check for same context and buffer */
+ if (mesaCtx == _mesa_get_current_context()
+ && mesaCtx->DrawBuffer == mesaDraw
+ && mesaCtx->ReadBuffer == mesaRead) {
+ return GL_TRUE;
+ }
+
+ _glapi_check_multithread();
+
+ swrast_check_and_update_window_size(mesaCtx, mesaDraw);
+ if (read != draw)
+ swrast_check_and_update_window_size(mesaCtx, mesaRead);
+
+ _mesa_make_current( mesaCtx,
+ mesaDraw,
+ mesaRead );
+ }
+ else {
+ /* unbind */
+ _mesa_make_current( NULL, NULL, NULL );
+ }
+
+ return GL_TRUE;
+}
+
+static int driUnbindContext(__DRIcontext *ctx)
+{
+ TRACE;
+ (void) ctx;
+ _mesa_make_current(NULL, NULL, NULL);
+ return GL_TRUE;
+}
+
+
+static const __DRIcoreExtension driCoreExtension = {
+ { __DRI_CORE, __DRI_CORE_VERSION },
+ NULL, /* driCreateNewScreen */
+ driDestroyScreen,
+ driGetExtensions,
+ driGetConfigAttrib,
+ driIndexConfigAttrib,
+ NULL, /* driCreateNewDrawable */
+ driDestroyDrawable,
+ driSwapBuffers,
+ driCreateNewContext,
+ driCopyContext,
+ driDestroyContext,
+ driBindContext,
+ driUnbindContext
+};
+
+static const __DRIswrastExtension driSWRastExtension = {
+ { __DRI_SWRAST, __DRI_SWRAST_VERSION },
+ driCreateNewScreen,
+ driCreateNewDrawable
+};
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+ &driCoreExtension.base,
+ &driSWRastExtension.base,
+ NULL
+};
diff --git a/src/mesa/drivers/dri/swrast/swrast_priv.h b/src/mesa/drivers/dri/swrast/swrast_priv.h
new file mode 100644
index 00000000000..a3e3922f128
--- /dev/null
+++ b/src/mesa/drivers/dri/swrast/swrast_priv.h
@@ -0,0 +1,142 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.1
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Authors:
+ * George Sapountzis <[email protected]>
+ */
+
+
+#ifndef _SWRAST_PRIV_H
+#define _SWRAST_PRIV_H
+
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
+#include "mtypes.h"
+
+
+/**
+ * Debugging
+ */
+#define DEBUG_CORE 0
+#define DEBUG_SPAN 0
+
+#if DEBUG_CORE
+#define TRACE _mesa_printf("--> %s\n", __FUNCTION__)
+#else
+#define TRACE
+#endif
+
+#if DEBUG_SPAN
+#define TRACE_SPAN _mesa_printf("--> %s\n", __FUNCTION__)
+#else
+#define TRACE_SPAN
+#endif
+
+
+/**
+ * Data types
+ */
+struct __DRIscreenRec {
+ int num;
+
+ const __DRIextension **extensions;
+
+ const __DRIswrastLoaderExtension *swrast_loader;
+};
+
+struct __DRIcontextRec {
+ GLcontext Base;
+
+ void *loaderPrivate;
+
+ __DRIscreen *driScreenPriv;
+};
+
+struct __DRIdrawableRec {
+ GLframebuffer Base;
+
+ void *loaderPrivate;
+
+ __DRIscreen *driScreenPriv;
+
+ /* scratch row for optimized front-buffer rendering */
+ char *row;
+};
+
+struct swrast_renderbuffer {
+ struct gl_renderbuffer Base;
+
+ /* renderbuffer pitch (in bytes) */
+ GLuint pitch;
+};
+
+static inline __DRIcontext *
+swrast_context(GLcontext *ctx)
+{
+ return (__DRIcontext *) ctx;
+}
+
+static inline __DRIdrawable *
+swrast_drawable(GLframebuffer *fb)
+{
+ return (__DRIdrawable *) fb;
+}
+
+static inline struct swrast_renderbuffer *
+swrast_renderbuffer(struct gl_renderbuffer *rb)
+{
+ return (struct swrast_renderbuffer *) rb;
+}
+
+
+/**
+ * Pixel formats we support
+ */
+#define PF_CI8 1 /**< Color Index mode */
+#define PF_A8R8G8B8 2 /**< 32-bit TrueColor: 8-A, 8-R, 8-G, 8-B bits */
+#define PF_R5G6B5 3 /**< 16-bit TrueColor: 5-R, 6-G, 5-B bits */
+#define PF_R3G3B2 4 /**< 8-bit TrueColor: 3-R, 3-G, 2-B bits */
+
+
+/**
+ * Renderbuffer pitch alignment (in bits).
+ *
+ * The xorg loader requires padding images to 32 bits. However, this should
+ * become a screen/drawable parameter XXX
+ */
+#define PITCH_ALIGN_BITS 32
+
+
+/* swrast_span.c */
+
+extern void
+swrast_set_span_funcs_back(struct swrast_renderbuffer *xrb,
+ GLuint pixel_format);
+
+extern void
+swrast_set_span_funcs_front(struct swrast_renderbuffer *xrb,
+ GLuint pixel_format);
+
+#endif /* _SWRAST_PRIV_H_ */
diff --git a/src/mesa/drivers/dri/swrast/swrast_span.c b/src/mesa/drivers/dri/swrast/swrast_span.c
new file mode 100644
index 00000000000..5e990368b2e
--- /dev/null
+++ b/src/mesa/drivers/dri/swrast/swrast_span.c
@@ -0,0 +1,367 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.1
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Authors:
+ * George Sapountzis <[email protected]>
+ */
+
+#include "swrast_priv.h"
+
+#define YFLIP(_xrb, Y) ((_xrb)->Base.Height - (Y) - 1)
+
+/*
+ * Dithering support takes the "computation" extreme in the "computation vs.
+ * storage" trade-off. This approach is very simple to implement and any
+ * computational overhead should be acceptable. XMesa uses table lookups for
+ * around 8KB of storage overhead per visual.
+ */
+#define DITHER 1
+
+static const GLubyte kernel[16] = {
+ 0*16, 8*16, 2*16, 10*16,
+ 12*16, 4*16, 14*16, 6*16,
+ 3*16, 11*16, 1*16, 9*16,
+ 15*16, 7*16, 13*16, 5*16,
+};
+
+#if DITHER
+#define DITHER_COMP(X, Y) kernel[((X) & 0x3) | (((Y) & 0x3) << 2)]
+
+#define DITHER_CLAMP(X) (((X) < CHAN_MAX) ? (X) : CHAN_MAX)
+#else
+#define DITHER_COMP(X, Y) 0
+
+#define DITHER_CLAMP(X) (X)
+#endif
+
+
+/*
+ * Pixel macros shared across front/back buffer span functions.
+ */
+
+/* 32-bit BGRA */
+#define STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) \
+ DST[3] = VALUE[ACOMP]; \
+ DST[2] = VALUE[RCOMP]; \
+ DST[1] = VALUE[GCOMP]; \
+ DST[0] = VALUE[BCOMP]
+#define STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE) \
+ DST[3] = 0xff; \
+ DST[2] = VALUE[RCOMP]; \
+ DST[1] = VALUE[GCOMP]; \
+ DST[0] = VALUE[BCOMP]
+#define FETCH_PIXEL_A8R8G8B8(DST, SRC) \
+ DST[ACOMP] = SRC[3]; \
+ DST[RCOMP] = SRC[2]; \
+ DST[GCOMP] = SRC[1]; \
+ DST[BCOMP] = SRC[0]
+
+
+/* 16-bit BGR */
+#define STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) \
+ do { \
+ int d = DITHER_COMP(X, Y) >> 6; \
+ GLushort *p = (GLushort *)DST; \
+ *p = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xf8) << 8) | \
+ ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xfc) << 3) | \
+ ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xf8) >> 3) ); \
+ } while(0)
+#define FETCH_PIXEL_R5G6B5(DST, SRC) \
+ do { \
+ GLushort p = *(GLushort *)SRC; \
+ DST[ACOMP] = 0xff; \
+ DST[RCOMP] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
+ DST[GCOMP] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
+ DST[BCOMP] = ((p << 3) & 0xf8) * 255 / 0xf8; \
+ } while(0)
+
+
+/* 8-bit BGR */
+#define STORE_PIXEL_R3G3B2(DST, X, Y, VALUE) \
+ do { \
+ int d = DITHER_COMP(X, Y) >> 3; \
+ GLubyte *p = (GLubyte *)DST; \
+ *p = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xe0) >> 5) | \
+ ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xe0) >> 2) | \
+ ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xc0) >> 0) ); \
+ } while(0)
+#define FETCH_PIXEL_R3G3B2(DST, SRC) \
+ do { \
+ GLubyte p = *(GLubyte *)SRC; \
+ DST[ACOMP] = 0xff; \
+ DST[RCOMP] = ((p << 5) & 0xe0) * 255 / 0xe0; \
+ DST[GCOMP] = ((p << 2) & 0xe0) * 255 / 0xe0; \
+ DST[BCOMP] = ((p << 0) & 0xc0) * 255 / 0xc0; \
+ } while(0)
+
+
+/*
+ * Generate code for back-buffer span functions.
+ */
+
+/* 32-bit BGRA */
+#define NAME(FUNC) FUNC##_A8R8G8B8
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 4;
+#define INC_PIXEL_PTR(P) P += 4
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+ STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
+#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
+ STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE)
+#define FETCH_PIXEL(DST, SRC) \
+ FETCH_PIXEL_A8R8G8B8(DST, SRC)
+
+#include "swrast/s_spantemp.h"
+
+
+/* 16-bit BGR */
+#define NAME(FUNC) FUNC##_R5G6B5
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 2;
+#define INC_PIXEL_PTR(P) P += 2
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+ STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
+#define FETCH_PIXEL(DST, SRC) \
+ FETCH_PIXEL_R5G6B5(DST, SRC)
+
+#include "swrast/s_spantemp.h"
+
+
+/* 8-bit BGR */
+#define NAME(FUNC) FUNC##_R3G3B2
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 1;
+#define INC_PIXEL_PTR(P) P += 1
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+ STORE_PIXEL_R3G3B2(DST, X, Y, VALUE)
+#define FETCH_PIXEL(DST, SRC) \
+ FETCH_PIXEL_R3G3B2(DST, SRC)
+
+#include "swrast/s_spantemp.h"
+
+
+/* 8-bit color index */
+#define NAME(FUNC) FUNC##_CI8
+#define CI_MODE
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X);
+#define INC_PIXEL_PTR(P) P += 1
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+ *DST = VALUE[0]
+#define FETCH_PIXEL(DST, SRC) \
+ DST = SRC[0]
+
+#include "swrast/s_spantemp.h"
+
+
+/*
+ * Generate code for front-buffer span functions.
+ */
+
+/* 32-bit BGRA */
+#define NAME(FUNC) FUNC##_A8R8G8B8_front
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = (GLubyte *)row;
+#define INC_PIXEL_PTR(P) P += 4
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+ STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
+#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
+ STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE)
+#define FETCH_PIXEL(DST, SRC) \
+ FETCH_PIXEL_A8R8G8B8(DST, SRC)
+
+#include "swrast_spantemp.h"
+
+
+/* 16-bit BGR */
+#define NAME(FUNC) FUNC##_R5G6B5_front
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = (GLubyte *)row;
+#define INC_PIXEL_PTR(P) P += 2
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+ STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
+#define FETCH_PIXEL(DST, SRC) \
+ FETCH_PIXEL_R5G6B5(DST, SRC)
+
+#include "swrast_spantemp.h"
+
+
+/* 8-bit BGR */
+#define NAME(FUNC) FUNC##_R3G3B2_front
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = (GLubyte *)row;
+#define INC_PIXEL_PTR(P) P += 1
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+ STORE_PIXEL_R3G3B2(DST, X, Y, VALUE)
+#define FETCH_PIXEL(DST, SRC) \
+ FETCH_PIXEL_R3G3B2(DST, SRC)
+
+#include "swrast_spantemp.h"
+
+
+/* 8-bit color index */
+#define NAME(FUNC) FUNC##_CI8_front
+#define CI_MODE
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = (GLubyte *)row;
+#define INC_PIXEL_PTR(P) P += 1
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+ *DST = VALUE[0]
+#define FETCH_PIXEL(DST, SRC) \
+ DST = SRC[0]
+
+#include "swrast_spantemp.h"
+
+
+/*
+ * Back-buffers are malloced memory and always private.
+ *
+ * BACK_PIXMAP (not supported)
+ * BACK_XIMAGE
+ */
+void
+swrast_set_span_funcs_back(struct swrast_renderbuffer *xrb,
+ GLuint pixel_format)
+{
+ switch (pixel_format) {
+ case PF_A8R8G8B8:
+ xrb->Base.GetRow = get_row_A8R8G8B8;
+ xrb->Base.GetValues = get_values_A8R8G8B8;
+ xrb->Base.PutRow = put_row_A8R8G8B8;
+ xrb->Base.PutRowRGB = put_row_rgb_A8R8G8B8;
+ xrb->Base.PutMonoRow = put_mono_row_A8R8G8B8;
+ xrb->Base.PutValues = put_values_A8R8G8B8;
+ xrb->Base.PutMonoValues = put_mono_values_A8R8G8B8;
+ break;
+ case PF_R5G6B5:
+ xrb->Base.GetRow = get_row_R5G6B5;
+ xrb->Base.GetValues = get_values_R5G6B5;
+ xrb->Base.PutRow = put_row_R5G6B5;
+ xrb->Base.PutRowRGB = put_row_rgb_R5G6B5;
+ xrb->Base.PutMonoRow = put_mono_row_R5G6B5;
+ xrb->Base.PutValues = put_values_R5G6B5;
+ xrb->Base.PutMonoValues = put_mono_values_R5G6B5;
+ break;
+ case PF_R3G3B2:
+ xrb->Base.GetRow = get_row_R3G3B2;
+ xrb->Base.GetValues = get_values_R3G3B2;
+ xrb->Base.PutRow = put_row_R3G3B2;
+ xrb->Base.PutRowRGB = put_row_rgb_R3G3B2;
+ xrb->Base.PutMonoRow = put_mono_row_R3G3B2;
+ xrb->Base.PutValues = put_values_R3G3B2;
+ xrb->Base.PutMonoValues = put_mono_values_R3G3B2;
+ break;
+ case PF_CI8:
+ xrb->Base.GetRow = get_row_CI8;
+ xrb->Base.GetValues = get_values_CI8;
+ xrb->Base.PutRow = put_row_CI8;
+ xrb->Base.PutMonoRow = put_mono_row_CI8;
+ xrb->Base.PutValues = put_values_CI8;
+ xrb->Base.PutMonoValues = put_mono_values_CI8;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+}
+
+
+/*
+ * Front-buffers are provided by the loader, the xorg loader uses pixmaps.
+ *
+ * WINDOW, An X window
+ * GLXWINDOW, GLX window
+ * PIXMAP, GLX pixmap
+ * PBUFFER GLX Pbuffer
+ */
+void
+swrast_set_span_funcs_front(struct swrast_renderbuffer *xrb,
+ GLuint pixel_format)
+{
+ switch (pixel_format) {
+ case PF_A8R8G8B8:
+ xrb->Base.GetRow = get_row_A8R8G8B8_front;
+ xrb->Base.GetValues = get_values_A8R8G8B8_front;
+ xrb->Base.PutRow = put_row_A8R8G8B8_front;
+ xrb->Base.PutRowRGB = put_row_rgb_A8R8G8B8_front;
+ xrb->Base.PutMonoRow = put_mono_row_A8R8G8B8_front;
+ xrb->Base.PutValues = put_values_A8R8G8B8_front;
+ xrb->Base.PutMonoValues = put_mono_values_A8R8G8B8_front;
+ break;
+ case PF_R5G6B5:
+ xrb->Base.GetRow = get_row_R5G6B5_front;
+ xrb->Base.GetValues = get_values_R5G6B5_front;
+ xrb->Base.PutRow = put_row_R5G6B5_front;
+ xrb->Base.PutRowRGB = put_row_rgb_R5G6B5_front;
+ xrb->Base.PutMonoRow = put_mono_row_R5G6B5_front;
+ xrb->Base.PutValues = put_values_R5G6B5_front;
+ xrb->Base.PutMonoValues = put_mono_values_R5G6B5_front;
+ break;
+ case PF_R3G3B2:
+ xrb->Base.GetRow = get_row_R3G3B2_front;
+ xrb->Base.GetValues = get_values_R3G3B2_front;
+ xrb->Base.PutRow = put_row_R3G3B2_front;
+ xrb->Base.PutRowRGB = put_row_rgb_R3G3B2_front;
+ xrb->Base.PutMonoRow = put_mono_row_R3G3B2_front;
+ xrb->Base.PutValues = put_values_R3G3B2_front;
+ xrb->Base.PutMonoValues = put_mono_values_R3G3B2_front;
+ break;
+ case PF_CI8:
+ xrb->Base.GetRow = get_row_CI8_front;
+ xrb->Base.GetValues = get_values_CI8_front;
+ xrb->Base.PutRow = put_row_CI8_front;
+ xrb->Base.PutMonoRow = put_mono_row_CI8_front;
+ xrb->Base.PutValues = put_values_CI8_front;
+ xrb->Base.PutMonoValues = put_mono_values_CI8_front;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+}
diff --git a/src/mesa/drivers/dri/swrast/swrast_spantemp.h b/src/mesa/drivers/dri/swrast/swrast_spantemp.h
new file mode 100644
index 00000000000..e7a9c86d7de
--- /dev/null
+++ b/src/mesa/drivers/dri/swrast/swrast_spantemp.h
@@ -0,0 +1,328 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5.1
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * Modified version of swrast/s_spantemp.h for front-buffer rendering. The
+ * no-mask paths use a scratch row to avoid repeated calls to the loader.
+ *
+ * For the mask paths we always use an array of 4 elements of RB_TYPE. This is
+ * to satisfy the xorg loader requirement of an image pitch of 32 bits and
+ * should be ok for other loaders also.
+ */
+
+
+#ifndef _SWRAST_SPANTEMP_ONCE
+#define _SWRAST_SPANTEMP_ONCE
+
+static inline void
+PUT_PIXEL( GLcontext *glCtx, GLint x, GLint y, GLubyte *p )
+{
+ __DRIcontext *ctx = swrast_context(glCtx);
+ __DRIdrawable *draw = swrast_drawable(glCtx->DrawBuffer);
+
+ __DRIscreen *screen = ctx->driScreenPriv;
+
+ screen->swrast_loader->putImage(draw, __DRI_SWRAST_IMAGE_OP_DRAW,
+ x, y, 1, 1, (char *)p,
+ draw->loaderPrivate);
+}
+
+
+static inline void
+GET_PIXEL( GLcontext *glCtx, GLint x, GLint y, GLubyte *p )
+{
+ __DRIcontext *ctx = swrast_context(glCtx);
+ __DRIdrawable *read = swrast_drawable(glCtx->ReadBuffer);
+
+ __DRIscreen *screen = ctx->driScreenPriv;
+
+ screen->swrast_loader->getImage(read, x, y, 1, 1, (char *)p,
+ read->loaderPrivate);
+}
+
+static inline void
+PUT_ROW( GLcontext *glCtx, GLint x, GLint y, GLuint n, char *row )
+{
+ __DRIcontext *ctx = swrast_context(glCtx);
+ __DRIdrawable *draw = swrast_drawable(glCtx->DrawBuffer);
+
+ __DRIscreen *screen = ctx->driScreenPriv;
+
+ screen->swrast_loader->putImage(draw, __DRI_SWRAST_IMAGE_OP_DRAW,
+ x, y, n, 1, row,
+ draw->loaderPrivate);
+}
+
+static inline void
+GET_ROW( GLcontext *glCtx, GLint x, GLint y, GLuint n, char *row )
+{
+ __DRIcontext *ctx = swrast_context(glCtx);
+ __DRIdrawable *read = swrast_drawable(glCtx->ReadBuffer);
+
+ __DRIscreen *screen = ctx->driScreenPriv;
+
+ screen->swrast_loader->getImage(read, x, y, n, 1, row,
+ read->loaderPrivate);
+}
+
+#endif /* _SWRAST_SPANTEMP_ONCE */
+
+
+/*
+ * Templates for the span/pixel-array write/read functions called via
+ * the gl_renderbuffer's GetRow, GetValues, PutRow, PutMonoRow, PutValues
+ * and PutMonoValues functions.
+ *
+ * Define the following macros before including this file:
+ * NAME(BASE) to generate the function name (i.e. add prefix or suffix)
+ * RB_TYPE the renderbuffer DataType
+ * CI_MODE if set, color index mode, else RGBA
+ * SPAN_VARS to declare any local variables
+ * INIT_PIXEL_PTR(P, X, Y) to initialize a pointer to a pixel
+ * INC_PIXEL_PTR(P) to increment a pixel pointer by one pixel
+ * STORE_PIXEL(DST, X, Y, VALUE) to store pixel values in buffer
+ * FETCH_PIXEL(DST, SRC) to fetch pixel values from buffer
+ *
+ * Note that in the STORE_PIXEL macros, we also pass in the (X,Y) coordinates
+ * for the pixels to be stored. This is useful when dithering and probably
+ * ignored otherwise.
+ */
+
+#include "macros.h"
+
+
+#ifdef CI_MODE
+#define RB_COMPONENTS 1
+#elif !defined(RB_COMPONENTS)
+#define RB_COMPONENTS 4
+#endif
+
+
+static void
+NAME(get_row)( GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLuint count, GLint x, GLint y, void *values )
+{
+#ifdef SPAN_VARS
+ SPAN_VARS
+#endif
+#ifdef CI_MODE
+ RB_TYPE *dest = (RB_TYPE *) values;
+#else
+ RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values;
+#endif
+ GLuint i;
+ char *row = swrast_drawable(ctx->ReadBuffer)->row;
+ INIT_PIXEL_PTR(pixel, x, y);
+ GET_ROW( ctx, x, YFLIP(xrb, y), count, row );
+ for (i = 0; i < count; i++) {
+ FETCH_PIXEL(dest[i], pixel);
+ INC_PIXEL_PTR(pixel);
+ }
+ (void) rb;
+}
+
+
+static void
+NAME(get_values)( GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLuint count, const GLint x[], const GLint y[], void *values )
+{
+#ifdef SPAN_VARS
+ SPAN_VARS
+#endif
+#ifdef CI_MODE
+ RB_TYPE *dest = (RB_TYPE *) values;
+#else
+ RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values;
+#endif
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ RB_TYPE pixel[4];
+ GET_PIXEL(ctx, x[i], YFLIP(xrb, y[i]), pixel);
+ FETCH_PIXEL(dest[i], pixel);
+ }
+ (void) rb;
+}
+
+
+static void
+NAME(put_row)( GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLuint count, GLint x, GLint y,
+ const void *values, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+ SPAN_VARS
+#endif
+ const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values;
+ GLuint i;
+ if (mask) {
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ RB_TYPE pixel[4];
+ STORE_PIXEL(pixel, x + i, y, src[i]);
+ PUT_PIXEL(ctx, x + i, YFLIP(xrb, y), pixel);
+ }
+ }
+ }
+ else {
+ char *row = swrast_drawable(ctx->DrawBuffer)->row;
+ INIT_PIXEL_PTR(pixel, x, y);
+ for (i = 0; i < count; i++) {
+ STORE_PIXEL(pixel, x + i, y, src[i]);
+ INC_PIXEL_PTR(pixel);
+ }
+ PUT_ROW( ctx, x, YFLIP(xrb, y), count, row );
+ }
+ (void) rb;
+}
+
+
+#if !defined(CI_MODE)
+static void
+NAME(put_row_rgb)( GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLuint count, GLint x, GLint y,
+ const void *values, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+ SPAN_VARS
+#endif
+ const RB_TYPE (*src)[3] = (const RB_TYPE (*)[3]) values;
+ GLuint i;
+ if (mask) {
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ RB_TYPE pixel[4];
+#ifdef STORE_PIXEL_RGB
+ STORE_PIXEL_RGB(pixel, x + i, y, src[i]);
+#else
+ STORE_PIXEL(pixel, x + i, y, src[i]);
+#endif
+ PUT_PIXEL(ctx, x + i, YFLIP(xrb, y), pixel);
+ }
+ }
+ }
+ else {
+ char *row = swrast_drawable(ctx->DrawBuffer)->row;
+ INIT_PIXEL_PTR(pixel, x, y);
+ for (i = 0; i < count; i++) {
+#ifdef STORE_PIXEL_RGB
+ STORE_PIXEL_RGB(pixel, x + i, y, src[i]);
+#else
+ STORE_PIXEL(pixel, x + i, y, src[i]);
+#endif
+ INC_PIXEL_PTR(pixel);
+ }
+ PUT_ROW( ctx, x, YFLIP(xrb, y), count, row );
+ }
+ (void) rb;
+}
+#endif
+
+
+static void
+NAME(put_mono_row)( GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLuint count, GLint x, GLint y,
+ const void *value, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+ SPAN_VARS
+#endif
+ const RB_TYPE *src = (const RB_TYPE *) value;
+ GLuint i;
+ if (mask) {
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ RB_TYPE pixel[4];
+ STORE_PIXEL(pixel, x + i, y, src);
+ PUT_PIXEL(ctx, x + i, YFLIP(xrb, y), pixel);
+ }
+ }
+ }
+ else {
+ char *row = swrast_drawable(ctx->DrawBuffer)->row;
+ INIT_PIXEL_PTR(pixel, x, y);
+ for (i = 0; i < count; i++) {
+ STORE_PIXEL(pixel, x + i, y, src);
+ INC_PIXEL_PTR(pixel);
+ }
+ PUT_ROW( ctx, x, YFLIP(xrb, y), count, row );
+ }
+ (void) rb;
+}
+
+
+static void
+NAME(put_values)( GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLuint count, const GLint x[], const GLint y[],
+ const void *values, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+ SPAN_VARS
+#endif
+ const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values;
+ GLuint i;
+ ASSERT(mask);
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ RB_TYPE pixel[4];
+ STORE_PIXEL(pixel, x[i], y[i], src[i]);
+ PUT_PIXEL(ctx, x[i], YFLIP(xrb, y[i]), pixel);
+ }
+ }
+ (void) rb;
+}
+
+
+static void
+NAME(put_mono_values)( GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLuint count, const GLint x[], const GLint y[],
+ const void *value, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+ SPAN_VARS
+#endif
+ const RB_TYPE *src = (const RB_TYPE *) value;
+ GLuint i;
+ ASSERT(mask);
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ RB_TYPE pixel[4];
+ STORE_PIXEL(pixel, x[i], y[i], src);
+ PUT_PIXEL(ctx, x[i], YFLIP(xrb, y[i]), pixel);
+ }
+ }
+ (void) rb;
+}
+
+
+#undef NAME
+#undef RB_TYPE
+#undef RB_COMPONENTS
+#undef CI_MODE
+#undef SPAN_VARS
+#undef INIT_PIXEL_PTR
+#undef INC_PIXEL_PTR
+#undef STORE_PIXEL
+#undef STORE_PIXEL_RGB
+#undef FETCH_PIXEL
diff --git a/src/mesa/drivers/dri/unichrome/via_screen.c b/src/mesa/drivers/dri/unichrome/via_screen.c
index ca193bfa538..3648710533b 100644
--- a/src/mesa/drivers/dri/unichrome/via_screen.c
+++ b/src/mesa/drivers/dri/unichrome/via_screen.c
@@ -24,8 +24,8 @@
#include <stdio.h>
-#include "utils.h"
#include "dri_util.h"
+#include "utils.h"
#include "glheader.h"
#include "context.h"
#include "framebuffer.h"
diff --git a/src/mesa/drivers/dri/unichrome/via_tex.c b/src/mesa/drivers/dri/unichrome/via_tex.c
index 0261a3ff177..15f15a89a6f 100644
--- a/src/mesa/drivers/dri/unichrome/via_tex.c
+++ b/src/mesa/drivers/dri/unichrome/via_tex.c
@@ -820,9 +820,7 @@ static void viaTexImage(GLcontext *ctx,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, target,
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
- texObj);
+ _mesa_generate_mipmap(ctx, target, texObj);
}
_mesa_unmap_teximage_pbo(ctx, packing);
diff --git a/src/mesa/drivers/glslcompiler/Makefile b/src/mesa/drivers/glslcompiler/Makefile
index 858457ddd40..dc4abd44d49 100644
--- a/src/mesa/drivers/glslcompiler/Makefile
+++ b/src/mesa/drivers/glslcompiler/Makefile
@@ -41,4 +41,4 @@ glslcompiler.o: glslcompiler.c
clean:
- rm -f *.o *~ $(PROGRAM)
+ -rm -f *.o *~ $(PROGRAM)
diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c
index 7a170b4d3d1..e5cd8f0b805 100644
--- a/src/mesa/drivers/x11/fakeglx.c
+++ b/src/mesa/drivers/x11/fakeglx.c
@@ -1183,11 +1183,12 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
* GLX_ARB_multisample
*/
case GLX_SAMPLE_BUFFERS_ARB:
- /* ms not supported */
- return NULL;
case GLX_SAMPLES_ARB:
- /* ms not supported */
- return NULL;
+ parselist++;
+ if (*parselist++ != 0)
+ /* ms not supported */
+ return NULL;
+ break;
/*
* FBConfig attribs.
diff --git a/src/mesa/drivers/xorg/.gitignore b/src/mesa/drivers/xorg/.gitignore
deleted file mode 100644
index 18a777939c6..00000000000
--- a/src/mesa/drivers/xorg/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-glxheader.h
-xmesaP.h
-xm_*
diff --git a/src/mesa/drivers/xorg/Makefile b/src/mesa/drivers/xorg/Makefile
deleted file mode 100644
index a1b417447be..00000000000
--- a/src/mesa/drivers/xorg/Makefile
+++ /dev/null
@@ -1,95 +0,0 @@
-# src/mesa/drivers/xorg/Makefile
-
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = libGLcore.so
-
-SYMLINKS = \
- glxheader.h \
- xmesaP.h \
- xm_api.c \
- xm_buffer.c \
- xm_dd.c \
- xm_image.c \
- xm_image.h \
- xm_line.c \
- xm_span.c \
- xm_tri.c
-
-C_SOURCES = \
- xm_api.c \
- xm_buffer.c \
- xm_dd.c \
- xm_image.c \
- xm_line.c \
- xm_span.c \
- xm_tri.c \
- glcore.c
-
-########################################
-
-MESA_MODULES = $(TOP)/src/mesa/libmesa.a
-
-C_SOURCES += ../common/driverfuncs.c
-ifeq ("${DRIVER_DIRS}", "dri")
-C_SOURCES += ../dri/common/utils.c
-endif
-
-OBJECTS = $(C_SOURCES:.c=.o)
-
-### Include directories
-INCLUDES = \
- -I. \
- -I.. \
- -I$(TOP)/include \
- -I$(TOP)/src/mesa \
- -I$(TOP)/src/mesa/main \
- -I$(TOP)/src/mesa/glapi \
- `pkg-config --cflags xorg-server`
-
-ifeq ("${DRIVER_DIRS}", "dri")
-INCLUDES += \
- -I$(TOP)/src/mesa/drivers/dri/common \
- `pkg-config --cflags libdrm`
-endif
-
-# undef 'USE_XSHM' to make it explicit that 'XFree86Server' takes precedence
-DRIVER_DEFINES = -UUSE_XSHM -DXFree86Server
-
-##### RULES #####
-
-.c.o:
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@
-
-
-##### TARGETS #####
-
-default: depend symlinks $(LIBNAME)
-
-
-$(LIBNAME): $(OBJECTS) $(MESA_MODULES) Makefile
- $(TOP)/bin/mklib -noprefix -o $@ \
- $(OBJECTS) $(MESA_MODULES) $(GLCORE_LIB_DEPS)
-
-
-depend: $(C_SOURCES) $(SYMLINKS)
- touch depend
- $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \
- > /dev/null
-
-
-clean:
- -rm -f *.o *.so $(SYMLINKS)
- -rm -f depend depend.bak
-
-install: $(LIBNAME)
- $(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
- $(INSTALL) -m 755 $(LIBNAME) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
-
-$(SYMLINKS):
- @[ -e $@ ] || ln -sf ../x11/$@ ./
-
-symlinks: $(SYMLINKS)
-
-include depend
diff --git a/src/mesa/drivers/xorg/glcore.c b/src/mesa/drivers/xorg/glcore.c
deleted file mode 100644
index a0199117c67..00000000000
--- a/src/mesa/drivers/xorg/glcore.c
+++ /dev/null
@@ -1,24 +0,0 @@
-
-#define _NEED_GL_CORE_IF
-#include <GL/xmesa.h>
-#include <GL/internal/glcore.h>
-#include "xmesaP.h"
-
-PUBLIC
-__GLcoreModule GL_Core = {
- XMesaCreateVisual,
- XMesaDestroyVisual,
-
- XMesaCreateWindowBuffer,
- XMesaCreatePixmapBuffer,
- XMesaDestroyBuffer,
- XMesaSwapBuffers,
- XMesaResizeBuffers,
-
- XMesaCreateContext,
- XMesaDestroyContext,
- XMesaCopyContext,
- XMesaMakeCurrent2,
- XMesaForceCurrent,
- XMesaLoseCurrent
-};
diff --git a/src/mesa/glapi/Makefile b/src/mesa/glapi/Makefile
index 6520f75e134..adc53d92494 100644
--- a/src/mesa/glapi/Makefile
+++ b/src/mesa/glapi/Makefile
@@ -7,27 +7,43 @@
TOP = ../../..
include $(TOP)/configs/current
-GLX_DIR = ../../glx/x11
-
OUTPUTS = glprocs.h glapitemp.h glapioffsets.h glapitable.h dispatch.h \
../main/enums.c \
../x86/glapi_x86.S \
../x86-64/glapi_x86-64.S \
../sparc/glapi_sparc.S \
../drivers/dri/common/extension_helper.h \
- $(GLX_DIR)/indirect.c \
- $(GLX_DIR)/indirect.h \
- $(GLX_DIR)/indirect_init.c \
- $(GLX_DIR)/indirect_size.h \
- $(GLX_DIR)/indirect_size.c \
+ ../../glx/x11/indirect.c \
+ ../../glx/x11/indirect.h \
+ ../../glx/x11/indirect_init.c \
+ ../../glx/x11/indirect_size.h \
+ ../../glx/x11/indirect_size.c
+
+
+GLX_DIR = $(XORG_BASE)/glx
+
+SERVER_GLAPI_FILES = \
+ $(GLX_DIR)/glapi.h \
+ $(GLX_DIR)/glapi.c \
+ $(GLX_DIR)/glthread.c \
+ $(GLX_DIR)/glthread.h
+
+SERVER_OUTPUTS = \
$(GLX_DIR)/indirect_dispatch.c \
$(GLX_DIR)/indirect_dispatch_swap.c \
$(GLX_DIR)/indirect_dispatch.h \
$(GLX_DIR)/indirect_reqsize.c \
$(GLX_DIR)/indirect_reqsize.h \
+ $(GLX_DIR)/indirect_size.h \
$(GLX_DIR)/indirect_size_get.c \
$(GLX_DIR)/indirect_size_get.h \
- $(GLX_DIR)/indirect_table.c
+ $(GLX_DIR)/indirect_table.c \
+ $(GLX_DIR)/glapitemp.h \
+ $(GLX_DIR)/glapitable.h \
+ $(GLX_DIR)/glapioffsets.h \
+ $(GLX_DIR)/glprocs.h \
+ $(GLX_DIR)/dispatch.h \
+ $(SERVER_GLAPI_FILES)
API_XML = gl_API.xml \
EXT_framebuffer_object.xml \
@@ -36,21 +52,33 @@ API_XML = gl_API.xml \
COMMON = gl_XML.py glX_XML.py license.py $(API_XML) typeexpr.py
COMMON_GLX = $(COMMON) glX_API.xml glX_XML.py glX_proto_common.py
-all: $(OUTPUTS)
+all: check-xorg-source $(OUTPUTS) $(SERVER_OUTPUTS)
+
+check-xorg-source:
+ @if ! test -d $(GLX_DIR); then \
+ echo "ERROR: Must specify path to xserver checkout; set XORG_BASE."; \
+ exit 1; \
+ fi
+
+$(GLX_DIR)/%.c: %.c
+ cp $< $@
+
+$(GLX_DIR)/%.h: %.h
+ cp $< $@
-glprocs.h: gl_procs.py $(COMMON)
+glprocs.h $(GLX_DIR)/glprocs.h: gl_procs.py $(COMMON)
$(PYTHON2) $(PYTHON_FLAGS) $< > $@
-glapitemp.h: gl_apitemp.py $(COMMON)
+glapitemp.h $(GLX_DIR)/glapitemp.h: gl_apitemp.py $(COMMON)
$(PYTHON2) $(PYTHON_FLAGS) $< > $@
-glapioffsets.h: gl_offsets.py $(COMMON)
+glapioffsets.h $(GLX_DIR)/glapioffsets.h: gl_offsets.py $(COMMON)
$(PYTHON2) $(PYTHON_FLAGS) $< > $@
-glapitable.h: gl_table.py $(COMMON)
+glapitable.h $(GLX_DIR)/glapitable.h: gl_table.py $(COMMON)
$(PYTHON2) $(PYTHON_FLAGS) $< > $@
-dispatch.h: gl_table.py $(COMMON)
+dispatch.h $(GLX_DIR)/dispatch.h: gl_table.py $(COMMON)
$(PYTHON2) $(PYTHON_FLAGS) $< -m remap_table > $@
../main/enums.c: gl_enums.py $(COMMON)
@@ -69,20 +97,20 @@ dispatch.h: gl_table.py $(COMMON)
../drivers/dri/common/extension_helper.h: extension_helper.py $(COMMON)
$(PYTHON2) $(PYTHON_FLAGS) $< > $@
-$(GLX_DIR)/indirect.c: glX_proto_send.py $(COMMON_GLX)
+../../glx/x11/indirect.c: glX_proto_send.py $(COMMON_GLX)
$(PYTHON2) $(PYTHON_FLAGS) $< -m proto | $(INDENT) $(INDENT_FLAGS) > $@
-$(GLX_DIR)/indirect.h: glX_proto_send.py $(COMMON_GLX)
+../../glx/x11/indirect.h: glX_proto_send.py $(COMMON_GLX)
$(PYTHON2) $(PYTHON_FLAGS) $< -m init_h > $@
-$(GLX_DIR)/indirect_init.c: glX_proto_send.py $(COMMON_GLX)
+../../glx/x11/indirect_init.c: glX_proto_send.py $(COMMON_GLX)
$(PYTHON2) $(PYTHON_FLAGS) $< -m init_c > $@
-$(GLX_DIR)/indirect_size.h: glX_proto_size.py $(COMMON_GLX)
+../../glx/x11/indirect_size.h $(GLX_DIR)/indirect_size.h: glX_proto_size.py $(COMMON_GLX)
$(PYTHON2) $(PYTHON_FLAGS) $< -m size_h --only-set -h _INDIRECT_SIZE_H_ \
| $(INDENT) $(INDENT_FLAGS) > $@
-$(GLX_DIR)/indirect_size.c: glX_proto_size.py $(COMMON_GLX)
+../../glx/x11/indirect_size.c: glX_proto_size.py $(COMMON_GLX)
$(PYTHON2) $(PYTHON_FLAGS) $< -m size_c --only-set \
| $(INDENT) $(INDENT_FLAGS) > $@
@@ -113,5 +141,5 @@ $(GLX_DIR)/indirect_table.c: glX_server_table.py gl_and_glX_API.xml $(COMMON_GLX
$(PYTHON2) $(PYTHON_FLAGS) $< -f gl_and_glX_API.xml > $@
clean:
- rm -f *~ *.pyo
- rm -f $(OUTPUTS)
+ -rm -f *~ *.pyo
+ -rm -f $(OUTPUTS)
diff --git a/src/mesa/glapi/glapi.c b/src/mesa/glapi/glapi.c
index 36b09e68e50..c4d101aee55 100644
--- a/src/mesa/glapi/glapi.c
+++ b/src/mesa/glapi/glapi.c
@@ -51,10 +51,19 @@
#ifdef HAVE_DIX_CONFIG_H
+
#include <dix-config.h>
-#endif
+#define PUBLIC
+
+#else
#include "glheader.h"
+
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
#include "glapi.h"
#include "glapioffsets.h"
#include "glapitable.h"
diff --git a/src/mesa/glapi/glthread.c b/src/mesa/glapi/glthread.c
index 92f2e5bf560..813d6f9dbc2 100644
--- a/src/mesa/glapi/glthread.c
+++ b/src/mesa/glapi/glthread.c
@@ -25,7 +25,7 @@
/*
* XXX There's probably some work to do in order to make this file
- * truly reusable outside of Mesa. First, the glheader.h include must go.
+ * truly reusable outside of Mesa.
*/
@@ -33,7 +33,7 @@
#include <dix-config.h>
#endif
-#include "glheader.h"
+#include <stdlib.h>
#include "glthread.h"
diff --git a/src/mesa/glapi/glthread.h b/src/mesa/glapi/glthread.h
index a61086d0dc6..e2765cebb10 100644
--- a/src/mesa/glapi/glthread.h
+++ b/src/mesa/glapi/glthread.h
@@ -259,11 +259,11 @@ typedef benaphore _glthread_Mutex;
* THREADS not defined
*/
-typedef GLuint _glthread_TSD;
+typedef int _glthread_TSD;
-typedef GLuint _glthread_Thread;
+typedef int _glthread_Thread;
-typedef GLuint _glthread_Mutex;
+typedef int _glthread_Mutex;
#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index ab0f035b45b..58a39d11d4d 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -188,6 +188,7 @@
#define MAX_PROGRAM_ADDRESS_REGS 2
#define MAX_UNIFORMS 128
#define MAX_VARYING 8
+#define MAX_SAMPLERS 8
/*@}*/
/** For GL_NV_vertex_program */
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 733aaad0309..2c387d8e2cb 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -149,8 +149,6 @@ int MESA_DEBUG_FLAGS = 0;
/* ubyte -> float conversion */
GLfloat _mesa_ubyte_to_float_color_tab[256];
-static void
-free_shared_state( GLcontext *ctx, struct gl_shared_state *ss );
/**
@@ -420,12 +418,14 @@ alloc_shared_state( GLcontext *ctx )
#endif
#if FEATURE_ARB_vertex_program
- ss->DefaultVertexProgram = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
+ ss->DefaultVertexProgram = (struct gl_vertex_program *)
+ ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
if (!ss->DefaultVertexProgram)
goto cleanup;
#endif
#if FEATURE_ARB_fragment_program
- ss->DefaultFragmentProgram = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
+ ss->DefaultFragmentProgram = (struct gl_fragment_program *)
+ ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
if (!ss->DefaultFragmentProgram)
goto cleanup;
#endif
@@ -502,12 +502,10 @@ cleanup:
_mesa_DeleteHashTable(ss->Programs);
#endif
#if FEATURE_ARB_vertex_program
- if (ss->DefaultVertexProgram)
- ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
+ _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
#endif
#if FEATURE_ARB_fragment_program
- if (ss->DefaultFragmentProgram)
- ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
+ _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
#endif
#if FEATURE_ATI_fragment_shader
if (ss->DefaultFragmentShader)
@@ -584,6 +582,8 @@ delete_program_cb(GLuint id, void *data, void *userData)
{
struct gl_program *prog = (struct gl_program *) data;
GLcontext *ctx = (GLcontext *) userData;
+ ASSERT(prog->RefCount == 1); /* should only be referenced by hash table */
+ prog->RefCount = 0; /* now going away */
ctx->Driver.DeleteProgram(ctx, prog);
}
@@ -709,15 +709,21 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
_mesa_HashDeleteAll(ss->DisplayList, delete_displaylist_cb, ctx);
_mesa_DeleteHashTable(ss->DisplayList);
+#if FEATURE_ARB_shader_objects
+ _mesa_HashWalk(ss->ShaderObjects, free_shader_program_data_cb, ctx);
+ _mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx);
+ _mesa_DeleteHashTable(ss->ShaderObjects);
+#endif
+
#if defined(FEATURE_NV_vertex_program) || defined(FEATURE_NV_fragment_program)
_mesa_HashDeleteAll(ss->Programs, delete_program_cb, ctx);
_mesa_DeleteHashTable(ss->Programs);
#endif
#if FEATURE_ARB_vertex_program
- ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
+ _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
#endif
#if FEATURE_ARB_fragment_program
- ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
+ _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
#endif
#if FEATURE_ATI_fragment_shader
@@ -734,12 +740,6 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
_mesa_HashDeleteAll(ss->ArrayObjects, delete_arrayobj_cb, ctx);
_mesa_DeleteHashTable(ss->ArrayObjects);
-#if FEATURE_ARB_shader_objects
- _mesa_HashWalk(ss->ShaderObjects, free_shader_program_data_cb, ctx);
- _mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx);
- _mesa_DeleteHashTable(ss->ShaderObjects);
-#endif
-
#if FEATURE_EXT_framebuffer_object
_mesa_HashDeleteAll(ss->FrameBuffers, delete_framebuffer_cb, ctx);
_mesa_DeleteHashTable(ss->FrameBuffers);
@@ -1251,6 +1251,14 @@ _mesa_free_context_data( GLcontext *ctx )
_mesa_unreference_framebuffer(&ctx->DrawBuffer);
_mesa_unreference_framebuffer(&ctx->ReadBuffer);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
+
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
+
_mesa_free_attrib_data(ctx);
_mesa_free_lighting_data( ctx );
_mesa_free_eval_data( ctx );
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index ce33905af13..e3ded41acac 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -328,6 +328,12 @@ struct dd_function_table {
GLsizei width, GLsizei height );
/**
+ * Called by glGenerateMipmap() or when GL_GENERATE_MIPMAP_SGIS is enabled.
+ */
+ void (*GenerateMipmap)(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj);
+
+ /**
* Called by glTexImage[123]D when user specifies a proxy texture
* target.
*
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 23ede7bb68f..63a00e04f51 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -3248,6 +3248,36 @@ save_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
static void GLAPIENTRY
+save_StencilFuncSeparateATI(GLenum frontfunc, GLenum backfunc, GLint ref,
+ GLuint mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ /* GL_FRONT */
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_STENCIL_FUNC_SEPARATE, 4);
+ if (n) {
+ n[1].e = GL_FRONT;
+ n[2].e = frontfunc;
+ n[3].i = ref;
+ n[4].ui = mask;
+ }
+ /* GL_BACK */
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_STENCIL_FUNC_SEPARATE, 4);
+ if (n) {
+ n[1].e = GL_BACK;
+ n[2].e = backfunc;
+ n[3].i = ref;
+ n[4].ui = mask;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_StencilFuncSeparate(ctx->Exec, (GL_FRONT, frontfunc, ref, mask));
+ CALL_StencilFuncSeparate(ctx->Exec, (GL_BACK, backfunc, ref, mask));
+ }
+}
+
+
+static void GLAPIENTRY
save_StencilMaskSeparate(GLenum face, GLuint mask)
{
GET_CURRENT_CONTEXT(ctx);
@@ -7838,6 +7868,9 @@ _mesa_init_dlist_table(struct _glapi_table *table)
SET_StencilMaskSeparate(table, save_StencilMaskSeparate);
SET_StencilOpSeparate(table, save_StencilOpSeparate);
+ /* ATI_separate_stencil */
+ SET_StencilFuncSeparateATI(table, save_StencilFuncSeparateATI);
+
/* GL_ARB_imaging */
/* Not all are supported */
SET_BlendColor(table, save_BlendColor);
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 9b60c732940..8e9948cb45d 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -1544,7 +1544,7 @@ _mesa_GenerateMipmapEXT(GLenum target)
/* XXX this might not handle cube maps correctly */
_mesa_lock_texture(ctx, texObj);
- _mesa_generate_mipmap(ctx, target, texUnit, texObj);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
_mesa_unlock_texture(ctx, texObj);
}
diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c
index 44357fbd6a3..8ca912b3a9d 100644
--- a/src/mesa/main/mipmap.c
+++ b/src/mesa/main/mipmap.c
@@ -934,7 +934,6 @@ make_2d_stack_mipmap(const struct gl_texture_format *format, GLint border,
*/
void
_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
- const struct gl_texture_unit *texUnit,
struct gl_texture_object *texObj)
{
const struct gl_texture_image *srcImage;
diff --git a/src/mesa/main/mipmap.h b/src/mesa/main/mipmap.h
index df786032838..46e16902c86 100644
--- a/src/mesa/main/mipmap.h
+++ b/src/mesa/main/mipmap.h
@@ -30,7 +30,6 @@
extern void
_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
- const struct gl_texture_unit *texUnit,
struct gl_texture_object *texObj);
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index c8718a7f636..04da767ec91 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1544,19 +1544,17 @@ struct gl_texture_unit
/*@}*/
};
-struct texenvprog_cache_item {
- GLuint hash;
- void *key;
- struct gl_fragment_program *data;
- struct texenvprog_cache_item *next;
-};
-struct texenvprog_cache {
+struct texenvprog_cache_item;
+
+struct texenvprog_cache
+{
struct texenvprog_cache_item **items;
GLuint size, n_items;
GLcontext *ctx;
};
+
/**
* Texture attribute group (GL_TEXTURE_BIT).
*/
@@ -1865,6 +1863,7 @@ enum register_file
/** Vertex and fragment instructions */
struct prog_instruction;
struct gl_program_parameter_list;
+struct gl_uniform_list;
/**
@@ -1884,6 +1883,7 @@ struct gl_program
GLbitfield InputsRead; /**< Bitmask of which input regs are read */
GLbitfield OutputsWritten; /**< Bitmask of which output regs are written to */
GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */
+ GLbitfield SamplersUsed; /**< Bitfield of which samplers are used */
GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */
/** Named parameters, constants, etc. from program text */
@@ -1896,6 +1896,11 @@ struct gl_program
/** Vertex program user-defined attributes */
struct gl_program_parameter_list *Attributes;
+ /** Map from sampler unit to texture unit (set by glUniform1i()) */
+ GLubyte SamplerUnits[MAX_SAMPLERS];
+ /** Which texture target is being sampled (TEXTURE_1D/2D/3D/etc_INDEX) */
+ GLubyte SamplerTargets[MAX_SAMPLERS];
+
/** Logical counts */
/*@{*/
GLuint NumInstructions;
@@ -2088,7 +2093,7 @@ struct gl_query_state
/**
- * A GLSL shader object.
+ * A GLSL vertex or fragment shader object.
*/
struct gl_shader
{
@@ -2106,7 +2111,8 @@ struct gl_shader
/**
- * A GLSL program object. Basically a linked collection of "shaders".
+ * A GLSL program object.
+ * Basically a linked collection of vertex and fragment shaders.
*/
struct gl_shader_program
{
@@ -2121,7 +2127,7 @@ struct gl_shader_program
/* post-link info: */
struct gl_vertex_program *VertexProgram; /**< Linked vertex program */
struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */
- struct gl_program_parameter_list *Uniforms; /**< Plus constants, etc */
+ struct gl_uniform_list *Uniforms;
struct gl_program_parameter_list *Varying;
struct gl_program_parameter_list *Attributes; /**< Vertex attributes */
GLboolean LinkStatus; /**< GL_LINK_STATUS */
@@ -2185,10 +2191,10 @@ struct gl_shared_state
/*@{*/
struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */
#if FEATURE_ARB_vertex_program
- struct gl_program *DefaultVertexProgram;
+ struct gl_vertex_program *DefaultVertexProgram;
#endif
#if FEATURE_ARB_fragment_program
- struct gl_program *DefaultFragmentProgram;
+ struct gl_fragment_program *DefaultFragmentProgram;
#endif
/*@}*/
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 5ff67b654e8..1c73c5c462b 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -978,50 +978,60 @@ update_program(GLcontext *ctx)
* 3. Programs derived from fixed-function state.
*/
- ctx->FragmentProgram._Current = NULL;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
if (shProg && shProg->LinkStatus) {
/* Use shader programs */
/* XXX this isn't quite right, since we may have either a vertex
* _or_ fragment shader (not always both).
*/
- ctx->VertexProgram._Current = shProg->VertexProgram;
- ctx->FragmentProgram._Current = shProg->FragmentProgram;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
+ shProg->VertexProgram);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
+ shProg->FragmentProgram);
}
else {
if (ctx->VertexProgram._Enabled) {
/* use user-defined vertex program */
- ctx->VertexProgram._Current = ctx->VertexProgram.Current;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
+ ctx->VertexProgram.Current);
}
else if (ctx->VertexProgram._MaintainTnlProgram) {
/* Use vertex program generated from fixed-function state.
* The _Current pointer will get set in
* _tnl_UpdateFixedFunctionProgram() later if appropriate.
*/
- ctx->VertexProgram._Current = NULL;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
}
else {
/* no vertex program */
- ctx->VertexProgram._Current = NULL;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
}
if (ctx->FragmentProgram._Enabled) {
/* use user-defined vertex program */
- ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
+ ctx->FragmentProgram.Current);
}
else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
/* Use fragment program generated from fixed-function state.
* The _Current pointer will get set in _mesa_UpdateTexEnvProgram()
* later if appropriate.
*/
- ctx->FragmentProgram._Current = NULL;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
}
else {
/* no fragment program */
- ctx->FragmentProgram._Current = NULL;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
}
}
+ if (ctx->VertexProgram._Current)
+ assert(ctx->VertexProgram._Current->Base.Parameters);
+ if (ctx->FragmentProgram._Current)
+ assert(ctx->FragmentProgram._Current->Base.Parameters);
+
+
ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled;
if (ctx->FragmentProgram._MaintainTexEnvProgram &&
!ctx->FragmentProgram._Enabled) {
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index fb68bf0720e..68a4db91974 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -28,12 +28,23 @@
#include "glheader.h"
#include "macros.h"
#include "enums.h"
+#include "shader/program.h"
#include "shader/prog_parameter.h"
#include "shader/prog_instruction.h"
#include "shader/prog_print.h"
#include "shader/prog_statevars.h"
#include "texenvprogram.h"
+
+struct texenvprog_cache_item
+{
+ GLuint hash;
+ void *key;
+ struct gl_fragment_program *data;
+ struct texenvprog_cache_item *next;
+};
+
+
/**
* This MAX is probably a bit generous, but that's OK. There can be
* up to four instructions per texture unit (TEX + 3 for combine),
@@ -1133,7 +1144,7 @@ search_cache(const struct texenvprog_cache *cache,
for (c = cache->items[hash % cache->size]; c; c = c->next) {
if (c->hash == hash && memcmp(c->key, key, keysize) == 0)
- return (struct gl_fragment_program *) c->data;
+ return c->data;
}
return NULL;
@@ -1161,7 +1172,7 @@ static void rehash( struct texenvprog_cache *cache )
cache->size = size;
}
-static void clear_cache( struct texenvprog_cache *cache )
+static void clear_cache(GLcontext *ctx, struct texenvprog_cache *cache)
{
struct texenvprog_cache_item *c, *next;
GLuint i;
@@ -1170,8 +1181,7 @@ static void clear_cache( struct texenvprog_cache *cache )
for (c = cache->items[i]; c; c = next) {
next = c->next;
_mesa_free(c->key);
- cache->ctx->Driver.DeleteProgram(cache->ctx,
- (struct gl_program *) c->data);
+ _mesa_reference_fragprog(ctx, &c->data, NULL);
_mesa_free(c);
}
cache->items[i] = NULL;
@@ -1182,25 +1192,25 @@ static void clear_cache( struct texenvprog_cache *cache )
}
-static void cache_item( struct texenvprog_cache *cache,
+static void cache_item( GLcontext *ctx,
+ struct texenvprog_cache *cache,
GLuint hash,
const struct state_key *key,
- void *data )
+ struct gl_fragment_program *prog)
{
- struct texenvprog_cache_item *c
- = (struct texenvprog_cache_item *) MALLOC(sizeof(*c));
+ struct texenvprog_cache_item *c = CALLOC_STRUCT(texenvprog_cache_item);
c->hash = hash;
c->key = _mesa_malloc(sizeof(*key));
memcpy(c->key, key, sizeof(*key));
- c->data = (struct gl_fragment_program *) data;
+ _mesa_reference_fragprog(ctx, &c->data, prog);
if (cache->n_items > cache->size * 1.5) {
if (cache->size < 1000)
rehash(cache);
else
- clear_cache(cache);
+ clear_cache(ctx, cache);
}
cache->n_items++;
@@ -1243,32 +1253,29 @@ _mesa_UpdateTexEnvProgram( GLcontext *ctx )
/* If a conventional fragment program/shader isn't in effect... */
if (!ctx->FragmentProgram._Enabled &&
(!ctx->Shader.CurrentProgram || !ctx->Shader.CurrentProgram->FragmentProgram)) {
+ struct gl_fragment_program *newProg;
+
make_state_key(ctx, &key);
hash = hash_key(&key);
- ctx->FragmentProgram._Current =
- ctx->FragmentProgram._TexEnvProgram =
- search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key));
+ newProg = search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key));
+
+ if (!newProg) {
+ /* create new tex env program */
- if (!ctx->FragmentProgram._TexEnvProgram) {
if (0)
_mesa_printf("Building new texenv proggy for key %x\n", hash);
- /* create new tex env program */
- ctx->FragmentProgram._Current =
- ctx->FragmentProgram._TexEnvProgram =
- (struct gl_fragment_program *)
+ newProg = (struct gl_fragment_program *)
ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
- create_new_program(ctx, &key, ctx->FragmentProgram._TexEnvProgram);
+ create_new_program(ctx, &key, newProg);
- cache_item(&ctx->Texture.env_fp_cache, hash, &key,
- ctx->FragmentProgram._TexEnvProgram);
- }
- else {
- if (0)
- _mesa_printf("Found existing texenv program for key %x\n", hash);
+ cache_item(ctx, &ctx->Texture.env_fp_cache, hash, &key, newProg);
}
+
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, newProg);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, newProg);
}
else {
/* _Current pointer has been updated in update_program */
@@ -1298,6 +1305,6 @@ void _mesa_TexEnvProgramCacheInit( GLcontext *ctx )
void _mesa_TexEnvProgramCacheDestroy( GLcontext *ctx )
{
- clear_cache(&ctx->Texture.env_fp_cache);
+ clear_cache(ctx, &ctx->Texture.env_fp_cache);
_mesa_free(ctx->Texture.env_fp_cache.items);
}
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index 90edca86e83..5363e9e0801 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -2918,9 +2918,7 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, target,
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
- texObj);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
_mesa_unmap_teximage_pbo(ctx, packing);
@@ -3004,9 +3002,7 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, target,
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
- texObj);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
_mesa_unmap_teximage_pbo(ctx, packing);
@@ -3080,9 +3076,7 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, target,
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
- texObj);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
_mesa_unmap_teximage_pbo(ctx, packing);
@@ -3128,9 +3122,7 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, target,
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
- texObj);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
_mesa_unmap_teximage_pbo(ctx, packing);
@@ -3183,9 +3175,7 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, target,
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
- texObj);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
_mesa_unmap_teximage_pbo(ctx, packing);
@@ -3238,9 +3228,7 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, target,
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
- texObj);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
_mesa_unmap_teximage_pbo(ctx, packing);
@@ -3314,9 +3302,7 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, target,
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
- texObj);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
_mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
@@ -3426,9 +3412,7 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, target,
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
- texObj);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
_mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
diff --git a/src/mesa/main/version.h b/src/mesa/main/version.h
index 9229077f42c..2f459e517a5 100644
--- a/src/mesa/main/version.h
+++ b/src/mesa/main/version.h
@@ -31,7 +31,7 @@
#define MESA_MAJOR 7
#define MESA_MINOR 1
#define MESA_PATCH 0
-#define MESA_VERSION_STRING "7.1"
+#define MESA_VERSION_STRING "7.1 rc1"
/* To make version comparison easy */
#define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c
index 74004e9b137..60aaabe679f 100644
--- a/src/mesa/shader/arbprogparse.c
+++ b/src/mesa/shader/arbprogparse.c
@@ -3851,8 +3851,11 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target,
program->Base.NumNativeTexIndirections = ap.Base.NumTexIndirections;
program->Base.InputsRead = ap.Base.InputsRead;
program->Base.OutputsWritten = ap.Base.OutputsWritten;
- for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
+ for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) {
program->Base.TexturesUsed[i] = ap.TexturesUsed[i];
+ if (ap.TexturesUsed[i])
+ program->Base.SamplersUsed |= (1 << i);
+ }
program->Base.ShadowSamplers = ap.ShadowSamplers;
program->FogOption = ap.FogOption;
program->UsesKill = ap.UsesKill;
diff --git a/src/mesa/shader/descrip.mms b/src/mesa/shader/descrip.mms
index 157c193c792..bdac946efe2 100644
--- a/src/mesa/shader/descrip.mms
+++ b/src/mesa/shader/descrip.mms
@@ -1,6 +1,6 @@
# Makefile for core library for VMS
# contributed by Jouk Jansen [email protected]
-# Last revision : 3 October 2007
+# Last revision : 27 May 2008
.first
define gl [---.include.gl]
define math [-.math]
@@ -35,7 +35,7 @@ SOURCES = \
prog_parameter.c \
prog_print.c \
prog_statevars.c \
- shader_api.c
+ shader_api.c prog_uniform.c
OBJECTS = \
atifragshader.obj,\
@@ -52,7 +52,7 @@ OBJECTS = \
prog_parameter.obj,\
prog_print.obj,\
prog_statevars.obj,\
- shader_api.obj
+ shader_api.obj,prog_uniform.obj
##### RULES #####
@@ -90,3 +90,4 @@ prog_parameter.obj : prog_parameter.c
prog_print.obj : prog_print.c
prog_statevars.obj : prog_statevars.c
shader_api.obj : shader_api.c
+prog_uniform.obj : prog_uniform.c
diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c
index cb17aa501ce..8ce2ca39641 100644
--- a/src/mesa/shader/prog_execute.c
+++ b/src/mesa/shader/prog_execute.c
@@ -310,6 +310,8 @@ fetch_texel(GLcontext *ctx,
const GLfloat texcoord[4], GLfloat lodBias,
GLfloat color[4])
{
+ const GLuint unit = machine->Samplers[inst->TexSrcUnit];
+
/* Note: we only have the right derivatives for fragment input attribs.
*/
if (machine->NumDeriv > 0 &&
@@ -320,12 +322,10 @@ fetch_texel(GLcontext *ctx,
machine->FetchTexelDeriv(ctx, texcoord,
machine->DerivX[attr],
machine->DerivY[attr],
- lodBias,
- inst->TexSrcUnit, color);
+ lodBias, unit, color);
}
else {
- machine->FetchTexelLod(ctx, texcoord, lodBias,
- inst->TexSrcUnit, color);
+ machine->FetchTexelLod(ctx, texcoord, lodBias, unit, color);
}
}
@@ -1522,9 +1522,7 @@ _mesa_execute_program(GLcontext * ctx,
default:
_mesa_problem(ctx, "Bad opcode %d in _mesa_execute_program",
inst->Opcode);
- assert(0);
return GL_TRUE; /* return value doesn't matter */
-
}
numExec++;
diff --git a/src/mesa/shader/prog_execute.h b/src/mesa/shader/prog_execute.h
index 3ea0ba1565c..18b13e11a41 100644
--- a/src/mesa/shader/prog_execute.h
+++ b/src/mesa/shader/prog_execute.h
@@ -63,6 +63,8 @@ struct gl_program_machine
GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */
GLint AddressReg[MAX_PROGRAM_ADDRESS_REGS][4];
+ const GLubyte *Samplers; /** Array mapping sampler var to tex unit */
+
GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */
GLuint StackDepth; /**< Index/ptr to top of CallStack[] */
diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c
index d6b5652a276..bea5d0551e4 100644
--- a/src/mesa/shader/prog_instruction.c
+++ b/src/mesa/shader/prog_instruction.c
@@ -119,6 +119,23 @@ _mesa_copy_instructions(struct prog_instruction *dest,
/**
+ * Free an array of instructions
+ */
+void
+_mesa_free_instructions(struct prog_instruction *inst, GLuint count)
+{
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (inst[i].Data)
+ _mesa_free(inst[i].Data);
+ if (inst[i].Comment)
+ _mesa_free((char *) inst[i].Comment);
+ }
+ _mesa_free(inst);
+}
+
+
+/**
* Basic info about each instruction
*/
struct instruction_info
@@ -126,6 +143,7 @@ struct instruction_info
gl_inst_opcode Opcode;
const char *Name;
GLuint NumSrcRegs;
+ GLuint NumDstRegs;
};
/**
@@ -133,91 +151,91 @@ struct instruction_info
* \note Opcode should equal array index!
*/
static const struct instruction_info InstInfo[MAX_OPCODE] = {
- { OPCODE_NOP, "NOP", 0 },
- { OPCODE_ABS, "ABS", 1 },
- { OPCODE_ADD, "ADD", 2 },
- { OPCODE_ARA, "ARA", 1 },
- { OPCODE_ARL, "ARL", 1 },
- { OPCODE_ARL_NV, "ARL", 1 },
- { OPCODE_ARR, "ARL", 1 },
- { OPCODE_BGNLOOP,"BGNLOOP", 0 },
- { OPCODE_BGNSUB, "BGNSUB", 0 },
- { OPCODE_BRA, "BRA", 0 },
- { OPCODE_BRK, "BRK", 0 },
- { OPCODE_CAL, "CAL", 0 },
- { OPCODE_CMP, "CMP", 3 },
- { OPCODE_CONT, "CONT", 0 },
- { OPCODE_COS, "COS", 1 },
- { OPCODE_DDX, "DDX", 1 },
- { OPCODE_DDY, "DDY", 1 },
- { OPCODE_DP3, "DP3", 2 },
- { OPCODE_DP4, "DP4", 2 },
- { OPCODE_DPH, "DPH", 2 },
- { OPCODE_DST, "DST", 2 },
- { OPCODE_ELSE, "ELSE", 0 },
- { OPCODE_END, "END", 0 },
- { OPCODE_ENDIF, "ENDIF", 0 },
- { OPCODE_ENDLOOP,"ENDLOOP", 0 },
- { OPCODE_ENDSUB, "ENDSUB", 0 },
- { OPCODE_EX2, "EX2", 1 },
- { OPCODE_EXP, "EXP", 1 },
- { OPCODE_FLR, "FLR", 1 },
- { OPCODE_FRC, "FRC", 1 },
- { OPCODE_IF, "IF", 0 },
- { OPCODE_INT, "INT", 1 },
- { OPCODE_KIL, "KIL", 1 },
- { OPCODE_KIL_NV, "KIL", 0 },
- { OPCODE_LG2, "LG2", 1 },
- { OPCODE_LIT, "LIT", 1 },
- { OPCODE_LOG, "LOG", 1 },
- { OPCODE_LRP, "LRP", 3 },
- { OPCODE_MAD, "MAD", 3 },
- { OPCODE_MAX, "MAX", 2 },
- { OPCODE_MIN, "MIN", 2 },
- { OPCODE_MOV, "MOV", 1 },
- { OPCODE_MUL, "MUL", 2 },
- { OPCODE_NOISE1, "NOISE1", 1 },
- { OPCODE_NOISE2, "NOISE2", 1 },
- { OPCODE_NOISE3, "NOISE3", 1 },
- { OPCODE_NOISE4, "NOISE4", 1 },
- { OPCODE_PK2H, "PK2H", 1 },
- { OPCODE_PK2US, "PK2US", 1 },
- { OPCODE_PK4B, "PK4B", 1 },
- { OPCODE_PK4UB, "PK4UB", 1 },
- { OPCODE_POW, "POW", 2 },
- { OPCODE_POPA, "POPA", 0 },
- { OPCODE_PRINT, "PRINT", 1 },
- { OPCODE_PUSHA, "PUSHA", 0 },
- { OPCODE_RCC, "RCC", 1 },
- { OPCODE_RCP, "RCP", 1 },
- { OPCODE_RET, "RET", 0 },
- { OPCODE_RFL, "RFL", 1 },
- { OPCODE_RSQ, "RSQ", 1 },
- { OPCODE_SCS, "SCS", 1 },
- { OPCODE_SEQ, "SEQ", 2 },
- { OPCODE_SFL, "SFL", 0 },
- { OPCODE_SGE, "SGE", 2 },
- { OPCODE_SGT, "SGT", 2 },
- { OPCODE_SIN, "SIN", 1 },
- { OPCODE_SLE, "SLE", 2 },
- { OPCODE_SLT, "SLT", 2 },
- { OPCODE_SNE, "SNE", 2 },
- { OPCODE_SSG, "SSG", 1 },
- { OPCODE_STR, "STR", 0 },
- { OPCODE_SUB, "SUB", 2 },
- { OPCODE_SWZ, "SWZ", 1 },
- { OPCODE_TEX, "TEX", 1 },
- { OPCODE_TXB, "TXB", 1 },
- { OPCODE_TXD, "TXD", 3 },
- { OPCODE_TXL, "TXL", 1 },
- { OPCODE_TXP, "TXP", 1 },
- { OPCODE_TXP_NV, "TXP", 1 },
- { OPCODE_UP2H, "UP2H", 1 },
- { OPCODE_UP2US, "UP2US", 1 },
- { OPCODE_UP4B, "UP4B", 1 },
- { OPCODE_UP4UB, "UP4UB", 1 },
- { OPCODE_X2D, "X2D", 3 },
- { OPCODE_XPD, "XPD", 2 }
+ { OPCODE_NOP, "NOP", 0, 0 },
+ { OPCODE_ABS, "ABS", 1, 1 },
+ { OPCODE_ADD, "ADD", 2, 1 },
+ { OPCODE_ARA, "ARA", 1, 1 },
+ { OPCODE_ARL, "ARL", 1, 1 },
+ { OPCODE_ARL_NV, "ARL", 1, 1 },
+ { OPCODE_ARR, "ARL", 1, 1 },
+ { OPCODE_BGNLOOP,"BGNLOOP", 0, 0 },
+ { OPCODE_BGNSUB, "BGNSUB", 0, 0 },
+ { OPCODE_BRA, "BRA", 0, 0 },
+ { OPCODE_BRK, "BRK", 0, 0 },
+ { OPCODE_CAL, "CAL", 0, 0 },
+ { OPCODE_CMP, "CMP", 3, 1 },
+ { OPCODE_CONT, "CONT", 0, 0 },
+ { OPCODE_COS, "COS", 1, 1 },
+ { OPCODE_DDX, "DDX", 1, 1 },
+ { OPCODE_DDY, "DDY", 1, 1 },
+ { OPCODE_DP3, "DP3", 2, 1 },
+ { OPCODE_DP4, "DP4", 2, 1 },
+ { OPCODE_DPH, "DPH", 2, 1 },
+ { OPCODE_DST, "DST", 2, 1 },
+ { OPCODE_ELSE, "ELSE", 0, 0 },
+ { OPCODE_END, "END", 0, 0 },
+ { OPCODE_ENDIF, "ENDIF", 0, 0 },
+ { OPCODE_ENDLOOP,"ENDLOOP", 0, 0 },
+ { OPCODE_ENDSUB, "ENDSUB", 0, 0 },
+ { OPCODE_EX2, "EX2", 1, 1 },
+ { OPCODE_EXP, "EXP", 1, 1 },
+ { OPCODE_FLR, "FLR", 1, 1 },
+ { OPCODE_FRC, "FRC", 1, 1 },
+ { OPCODE_IF, "IF", 1, 0 },
+ { OPCODE_INT, "INT", 1, 1 },
+ { OPCODE_KIL, "KIL", 1, 0 },
+ { OPCODE_KIL_NV, "KIL", 0, 0 },
+ { OPCODE_LG2, "LG2", 1, 1 },
+ { OPCODE_LIT, "LIT", 1, 1 },
+ { OPCODE_LOG, "LOG", 1, 1 },
+ { OPCODE_LRP, "LRP", 3, 1 },
+ { OPCODE_MAD, "MAD", 3, 1 },
+ { OPCODE_MAX, "MAX", 2, 1 },
+ { OPCODE_MIN, "MIN", 2, 1 },
+ { OPCODE_MOV, "MOV", 1, 1 },
+ { OPCODE_MUL, "MUL", 2, 1 },
+ { OPCODE_NOISE1, "NOISE1", 1, 1 },
+ { OPCODE_NOISE2, "NOISE2", 1, 1 },
+ { OPCODE_NOISE3, "NOISE3", 1, 1 },
+ { OPCODE_NOISE4, "NOISE4", 1, 1 },
+ { OPCODE_PK2H, "PK2H", 1, 1 },
+ { OPCODE_PK2US, "PK2US", 1, 1 },
+ { OPCODE_PK4B, "PK4B", 1, 1 },
+ { OPCODE_PK4UB, "PK4UB", 1, 1 },
+ { OPCODE_POW, "POW", 2, 1 },
+ { OPCODE_POPA, "POPA", 0, 0 },
+ { OPCODE_PRINT, "PRINT", 1, 0 },
+ { OPCODE_PUSHA, "PUSHA", 0, 0 },
+ { OPCODE_RCC, "RCC", 1, 1 },
+ { OPCODE_RCP, "RCP", 1, 1 },
+ { OPCODE_RET, "RET", 0, 0 },
+ { OPCODE_RFL, "RFL", 1, 1 },
+ { OPCODE_RSQ, "RSQ", 1, 1 },
+ { OPCODE_SCS, "SCS", 1, 1 },
+ { OPCODE_SEQ, "SEQ", 2, 1 },
+ { OPCODE_SFL, "SFL", 0, 1 },
+ { OPCODE_SGE, "SGE", 2, 1 },
+ { OPCODE_SGT, "SGT", 2, 1 },
+ { OPCODE_SIN, "SIN", 1, 1 },
+ { OPCODE_SLE, "SLE", 2, 1 },
+ { OPCODE_SLT, "SLT", 2, 1 },
+ { OPCODE_SNE, "SNE", 2, 1 },
+ { OPCODE_SSG, "SSG", 1, 1 },
+ { OPCODE_STR, "STR", 0, 1 },
+ { OPCODE_SUB, "SUB", 2, 1 },
+ { OPCODE_SWZ, "SWZ", 1, 1 },
+ { OPCODE_TEX, "TEX", 1, 1 },
+ { OPCODE_TXB, "TXB", 1, 1 },
+ { OPCODE_TXD, "TXD", 3, 1 },
+ { OPCODE_TXL, "TXL", 1, 1 },
+ { OPCODE_TXP, "TXP", 1, 1 },
+ { OPCODE_TXP_NV, "TXP", 1, 1 },
+ { OPCODE_UP2H, "UP2H", 1, 1 },
+ { OPCODE_UP2US, "UP2US", 1, 1 },
+ { OPCODE_UP4B, "UP4B", 1, 1 },
+ { OPCODE_UP4UB, "UP4UB", 1, 1 },
+ { OPCODE_X2D, "X2D", 3, 1 },
+ { OPCODE_XPD, "XPD", 2, 1 }
};
@@ -234,6 +252,29 @@ _mesa_num_inst_src_regs(gl_inst_opcode opcode)
/**
+ * Return the number of dst registers for the given instruction/opcode.
+ */
+GLuint
+_mesa_num_inst_dst_regs(gl_inst_opcode opcode)
+{
+ ASSERT(opcode == InstInfo[opcode].Opcode);
+ ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
+ return InstInfo[opcode].NumDstRegs;
+}
+
+
+GLboolean
+_mesa_is_tex_instruction(gl_inst_opcode opcode)
+{
+ return (opcode == OPCODE_TEX ||
+ opcode == OPCODE_TXB ||
+ opcode == OPCODE_TXD ||
+ opcode == OPCODE_TXL ||
+ opcode == OPCODE_TXP);
+}
+
+
+/**
* Return string name for given program opcode.
*/
const char *
diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h
index c800757aa0f..aca768376a2 100644
--- a/src/mesa/shader/prog_instruction.h
+++ b/src/mesa/shader/prog_instruction.h
@@ -437,9 +437,18 @@ extern struct prog_instruction *
_mesa_copy_instructions(struct prog_instruction *dest,
const struct prog_instruction *src, GLuint n);
+extern void
+_mesa_free_instructions(struct prog_instruction *inst, GLuint count);
+
extern GLuint
_mesa_num_inst_src_regs(gl_inst_opcode opcode);
+extern GLuint
+_mesa_num_inst_dst_regs(gl_inst_opcode opcode);
+
+extern GLboolean
+_mesa_is_tex_instruction(gl_inst_opcode opcode);
+
extern const char *
_mesa_opcode_string(gl_inst_opcode opcode);
diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c
index 3ad7215755d..152bd79f695 100644
--- a/src/mesa/shader/prog_parameter.c
+++ b/src/mesa/shader/prog_parameter.c
@@ -282,6 +282,8 @@ _mesa_add_uniform(struct gl_program_parameter_list *paramList,
* Add a sampler to the parameter list.
* \param name uniform's name
* \param datatype GL_SAMPLER_2D, GL_SAMPLER_2D_RECT_ARB, etc.
+ * \param index the sampler number (as seen in TEX instructions)
+ * \return sampler index (starting at zero) or -1 if error
*/
GLint
_mesa_add_sampler(struct gl_program_parameter_list *paramList,
@@ -292,13 +294,20 @@ _mesa_add_sampler(struct gl_program_parameter_list *paramList,
ASSERT(paramList->Parameters[i].Size == 1);
ASSERT(paramList->Parameters[i].DataType == datatype);
/* already in list */
- return i;
+ return (GLint) paramList->ParameterValues[i][0];
}
else {
const GLint size = 1; /* a sampler is basically a texture unit number */
- i = _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name,
- size, datatype, NULL, NULL);
- return i;
+ GLfloat value;
+ GLint numSamplers = 0;
+ for (i = 0; i < paramList->NumParameters; i++) {
+ if (paramList->Parameters[i].Type == PROGRAM_SAMPLER)
+ numSamplers++;
+ }
+ value = (GLfloat) numSamplers;
+ (void) _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name,
+ size, datatype, &value, NULL);
+ return numSamplers;
}
}
@@ -599,11 +608,46 @@ _mesa_clone_parameter_list(const struct gl_program_parameter_list *list)
}
}
+ clone->StateFlags = list->StateFlags;
+
return clone;
}
/**
+ * Return a new parameter list which is listA + listB.
+ */
+struct gl_program_parameter_list *
+_mesa_combine_parameter_lists(const struct gl_program_parameter_list *listA,
+ const struct gl_program_parameter_list *listB)
+{
+ struct gl_program_parameter_list *list;
+
+ if (listA) {
+ list = _mesa_clone_parameter_list(listA);
+ if (list && listB) {
+ GLuint i;
+ for (i = 0; i < listB->NumParameters; i++) {
+ struct gl_program_parameter *param = listB->Parameters + i;
+ _mesa_add_parameter(list, param->Type, param->Name, param->Size,
+ param->DataType,
+ listB->ParameterValues[i],
+ param->StateIndexes);
+ }
+ }
+ }
+ else if (listB) {
+ list = _mesa_clone_parameter_list(listB);
+ }
+ else {
+ list = NULL;
+ }
+ return list;
+}
+
+
+
+/**
* Find longest name of all uniform parameters in list.
*/
GLuint
diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h
index 09ff851ea73..105f6f24deb 100644
--- a/src/mesa/shader/prog_parameter.h
+++ b/src/mesa/shader/prog_parameter.h
@@ -78,6 +78,16 @@ _mesa_free_parameter_list(struct gl_program_parameter_list *paramList);
extern struct gl_program_parameter_list *
_mesa_clone_parameter_list(const struct gl_program_parameter_list *list);
+extern struct gl_program_parameter_list *
+_mesa_combine_parameter_lists(const struct gl_program_parameter_list *a,
+ const struct gl_program_parameter_list *b);
+
+static INLINE GLuint
+_mesa_num_parameters(const struct gl_program_parameter_list *list)
+{
+ return list ? list->NumParameters : 0;
+}
+
extern GLint
_mesa_add_parameter(struct gl_program_parameter_list *paramList,
enum register_file type, const char *name,
diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index 308cce2206c..1c35ce3fecf 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -320,7 +320,7 @@ _mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended)
if (!extended)
s[i++] = '.';
- if (negateBase & 0x1)
+ if (negateBase & NEGATE_X)
s[i++] = '-';
s[i++] = swz[GET_SWZ(swizzle, 0)];
@@ -328,7 +328,7 @@ _mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended)
s[i++] = ',';
}
- if (negateBase & 0x2)
+ if (negateBase & NEGATE_Y)
s[i++] = '-';
s[i++] = swz[GET_SWZ(swizzle, 1)];
@@ -336,7 +336,7 @@ _mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended)
s[i++] = ',';
}
- if (negateBase & 0x4)
+ if (negateBase & NEGATE_Z)
s[i++] = '-';
s[i++] = swz[GET_SWZ(swizzle, 2)];
@@ -344,7 +344,7 @@ _mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended)
s[i++] = ',';
}
- if (negateBase & 0x8)
+ if (negateBase & NEGATE_W)
s[i++] = '-';
s[i++] = swz[GET_SWZ(swizzle, 3)];
@@ -541,7 +541,7 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent,
_mesa_printf("_SAT");
_mesa_printf(" ");
print_dst_reg(&inst->DstReg, mode, prog);
- _mesa_printf("%s[%d], %s",
+ _mesa_printf(", %s[%d], %s",
file_string((enum register_file) inst->SrcReg[0].File,
mode),
inst->SrcReg[0].Index,
@@ -551,6 +551,7 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent,
break;
case OPCODE_TEX:
case OPCODE_TXP:
+ case OPCODE_TXL:
case OPCODE_TXB:
_mesa_printf("%s", _mesa_opcode_string(inst->Opcode));
if (inst->SaturateMode == SATURATE_ZERO_ONE)
@@ -571,6 +572,23 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent,
}
print_comment(inst);
break;
+
+ case OPCODE_KIL:
+ _mesa_printf("%s", _mesa_opcode_string(inst->Opcode));
+ _mesa_printf(" ");
+ print_src_reg(&inst->SrcReg[0], mode, prog);
+ print_comment(inst);
+ break;
+ case OPCODE_KIL_NV:
+ _mesa_printf("%s", _mesa_opcode_string(inst->Opcode));
+ _mesa_printf(" ");
+ _mesa_printf("%s.%s",
+ _mesa_condcode_string(inst->DstReg.CondMask),
+ _mesa_swizzle_string(inst->DstReg.CondSwizzle,
+ GL_FALSE, GL_FALSE));
+ print_comment(inst);
+ break;
+
case OPCODE_ARL:
_mesa_printf("ARL addr.x, ");
print_src_reg(&inst->SrcReg[0], mode, prog);
@@ -735,6 +753,8 @@ _mesa_print_program_opt(const struct gl_program *prog,
void
_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog)
{
+ GLuint i;
+
_mesa_printf("InputsRead: 0x%x\n", prog->InputsRead);
_mesa_printf("OutputsWritten: 0x%x\n", prog->OutputsWritten);
_mesa_printf("NumInstructions=%d\n", prog->NumInstructions);
@@ -742,9 +762,14 @@ _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog)
_mesa_printf("NumParameters=%d\n", prog->NumParameters);
_mesa_printf("NumAttributes=%d\n", prog->NumAttributes);
_mesa_printf("NumAddressRegs=%d\n", prog->NumAddressRegs);
-
+ _mesa_printf("Samplers=[ ");
+ for (i = 0; i < MAX_SAMPLERS; i++) {
+ _mesa_printf("%d ", prog->SamplerUnits[i]);
+ }
+ _mesa_printf("]\n");
+
_mesa_load_state_parameters(ctx, prog->Parameters);
-
+
#if 0
_mesa_printf("Local Params:\n");
for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){
@@ -762,6 +787,9 @@ _mesa_print_parameter_list(const struct gl_program_parameter_list *list)
const gl_prog_print_mode mode = PROG_PRINT_DEBUG;
GLuint i;
+ if (!list)
+ return;
+
_mesa_printf("param list %p\n", (void *) list);
for (i = 0; i < list->NumParameters; i++){
struct gl_program_parameter *param = list->Parameters + i;
diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c
index 4ae74c1d42b..539057b4382 100644
--- a/src/mesa/shader/prog_statevars.c
+++ b/src/mesa/shader/prog_statevars.c
@@ -253,7 +253,8 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
value[0] = ctx->Fog.Density;
value[1] = ctx->Fog.Start;
value[2] = ctx->Fog.End;
- value[3] = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
+ value[3] = (ctx->Fog.End == ctx->Fog.Start)
+ ? 1.0 : 1.0F / (ctx->Fog.End - ctx->Fog.Start);
return;
case STATE_CLIPPLANE:
{
@@ -278,6 +279,7 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
case STATE_MVP_MATRIX:
case STATE_TEXTURE_MATRIX:
case STATE_PROGRAM_MATRIX:
+ case STATE_COLOR_MATRIX:
{
/* state[0] = modelview, projection, texture, etc. */
/* state[1] = which texture matrix or program matrix */
@@ -311,6 +313,9 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
else if (mat == STATE_PROGRAM_MATRIX) {
matrix = ctx->ProgramMatrixStack[index].Top;
}
+ else if (mat == STATE_COLOR_MATRIX) {
+ matrix = ctx->ColorMatrixStack.Top;
+ }
else {
_mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()");
return;
@@ -420,8 +425,9 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
* exp: 2^-(density/ln(2) * fogcoord)
* exp2: 2^-((density/(ln(2)^2) * fogcoord)^2)
*/
- value[0] = -1.0F / (ctx->Fog.End - ctx->Fog.Start);
- value[1] = ctx->Fog.End / (ctx->Fog.End - ctx->Fog.Start);
+ value[0] = (ctx->Fog.End == ctx->Fog.Start)
+ ? 1.0 : -1.0F / (ctx->Fog.End - ctx->Fog.Start);
+ value[1] = ctx->Fog.End * -value[0];
value[2] = ctx->Fog.Density * ONE_DIV_LN2;
value[3] = ctx->Fog.Density * ONE_DIV_SQRT_LN2;
return;
@@ -434,6 +440,24 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
value[3] = ctx->Light.Light[ln]._CosCutoff;
return;
}
+ case STATE_PT_SCALE:
+ value[0] = ctx->Pixel.RedScale;
+ value[1] = ctx->Pixel.GreenScale;
+ value[2] = ctx->Pixel.BlueScale;
+ value[3] = ctx->Pixel.AlphaScale;
+ break;
+ case STATE_PT_BIAS:
+ value[0] = ctx->Pixel.RedBias;
+ value[1] = ctx->Pixel.GreenBias;
+ value[2] = ctx->Pixel.BlueBias;
+ value[3] = ctx->Pixel.AlphaBias;
+ break;
+ case STATE_PCM_SCALE:
+ COPY_4V(value, ctx->Pixel.PostColorMatrixScale);
+ break;
+ case STATE_PCM_BIAS:
+ COPY_4V(value, ctx->Pixel.PostColorMatrixBias);
+ break;
default:
/* unknown state indexes are silently ignored
* should be handled by the driver.
@@ -492,6 +516,8 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
return _NEW_TEXTURE_MATRIX;
case STATE_PROGRAM_MATRIX:
return _NEW_TRACK_MATRIX;
+ case STATE_COLOR_MATRIX:
+ return _NEW_COLOR_MATRIX;
case STATE_DEPTH_RANGE:
return _NEW_VIEWPORT;
@@ -585,6 +611,9 @@ append_token(char *dst, gl_state_index k)
case STATE_PROGRAM_MATRIX:
append(dst, "matrix.program");
break;
+ case STATE_COLOR_MATRIX:
+ append(dst, "matrix.color");
+ break;
case STATE_MATRIX_INVERSE:
append(dst, ".inverse");
break;
@@ -670,6 +699,18 @@ append_token(char *dst, gl_state_index k)
case STATE_POSITION_NORMALIZED:
append(dst, "(internal)");
break;
+ case STATE_PT_SCALE:
+ append(dst, "PTscale");
+ break;
+ case STATE_PT_BIAS:
+ append(dst, "PTbias");
+ break;
+ case STATE_PCM_SCALE:
+ append(dst, "PCMscale");
+ break;
+ case STATE_PCM_BIAS:
+ append(dst, "PCMbias");
+ break;
default:
;
}
@@ -748,6 +789,7 @@ _mesa_program_state_string(const gl_state_index state[STATE_LENGTH])
case STATE_MVP_MATRIX:
case STATE_TEXTURE_MATRIX:
case STATE_PROGRAM_MATRIX:
+ case STATE_COLOR_MATRIX:
{
/* state[0] = modelview, projection, texture, etc. */
/* state[1] = which texture matrix or program matrix */
@@ -815,10 +857,12 @@ _mesa_load_state_parameters(GLcontext *ctx,
if (!paramList)
return;
+ /*assert(ctx->Driver.NeedFlush == 0);*/
+
for (i = 0; i < paramList->NumParameters; i++) {
if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {
_mesa_fetch_state(ctx,
- paramList->Parameters[i].StateIndexes,
+ (gl_state_index *) paramList->Parameters[i].StateIndexes,
paramList->ParameterValues[i]);
}
}
diff --git a/src/mesa/shader/prog_statevars.h b/src/mesa/shader/prog_statevars.h
index 22bb8e07ad1..64820a5b681 100644
--- a/src/mesa/shader/prog_statevars.h
+++ b/src/mesa/shader/prog_statevars.h
@@ -67,6 +67,7 @@ typedef enum gl_state_index_ {
STATE_MVP_MATRIX,
STATE_TEXTURE_MATRIX,
STATE_PROGRAM_MATRIX,
+ STATE_COLOR_MATRIX,
STATE_MATRIX_INVERSE,
STATE_MATRIX_TRANSPOSE,
STATE_MATRIX_INVTRANS,
@@ -108,6 +109,10 @@ typedef enum gl_state_index_ {
STATE_POSITION_NORMALIZED, /* normalized light position */
STATE_FOG_PARAMS_OPTIMIZED, /* for faster fog calc */
STATE_SPOT_DIR_NORMALIZED, /* pre-normalized spot dir */
+ STATE_PT_SCALE, /**< Pixel transfer RGBA scale */
+ STATE_PT_BIAS, /**< Pixel transfer RGBA bias */
+ STATE_PCM_SCALE, /**< Post color matrix RGBA scale */
+ STATE_PCM_BIAS, /**< Post color matrix RGBA bias */
STATE_INTERNAL_DRIVER /* first available state index for drivers (must be last) */
} gl_state_index;
diff --git a/src/mesa/shader/prog_uniform.c b/src/mesa/shader/prog_uniform.c
new file mode 100644
index 00000000000..20e004b350c
--- /dev/null
+++ b/src/mesa/shader/prog_uniform.c
@@ -0,0 +1,157 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.1
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file prog_uniform.c
+ * Shader uniform functions.
+ * \author Brian Paul
+ */
+
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "prog_uniform.h"
+
+
+struct gl_uniform_list *
+_mesa_new_uniform_list(void)
+{
+ return CALLOC_STRUCT(gl_uniform_list);
+}
+
+
+void
+_mesa_free_uniform_list(struct gl_uniform_list *list)
+{
+ GLuint i;
+ for (i = 0; i < list->NumUniforms; i++) {
+ _mesa_free((void *) list->Uniforms[i].Name);
+ }
+ _mesa_free(list->Uniforms);
+ _mesa_free(list);
+}
+
+
+GLboolean
+_mesa_append_uniform(struct gl_uniform_list *list,
+ const char *name, GLenum target, GLuint progPos)
+{
+ const GLuint oldNum = list->NumUniforms;
+ GLint index;
+
+ assert(target == GL_VERTEX_PROGRAM_ARB ||
+ target == GL_FRAGMENT_PROGRAM_ARB);
+
+ index = _mesa_lookup_uniform(list, name);
+ if (index < 0) {
+ /* not found - append to list */
+
+ if (oldNum + 1 > list->Size) {
+ /* Need to grow the list array (alloc some extra) */
+ list->Size += 4;
+
+ /* realloc arrays */
+ list->Uniforms = (struct gl_uniform *)
+ _mesa_realloc(list->Uniforms,
+ oldNum * sizeof(struct gl_uniform),
+ list->Size * sizeof(struct gl_uniform));
+ }
+
+ if (!list->Uniforms) {
+ /* out of memory */
+ list->NumUniforms = 0;
+ list->Size = 0;
+ return GL_FALSE;
+ }
+
+ list->Uniforms[oldNum].Name = _mesa_strdup(name);
+ list->Uniforms[oldNum].VertPos = -1;
+ list->Uniforms[oldNum].FragPos = -1;
+ index = oldNum;
+ list->NumUniforms++;
+ }
+
+ /* update position for the vertex or fragment program */
+ if (target == GL_VERTEX_PROGRAM_ARB) {
+ if (list->Uniforms[index].VertPos != -1) {
+ /* this uniform is already in the list - that shouldn't happen */
+ return GL_FALSE;
+ }
+ list->Uniforms[index].VertPos = progPos;
+ }
+ else {
+ if (list->Uniforms[index].FragPos != -1) {
+ /* this uniform is already in the list - that shouldn't happen */
+ return GL_FALSE;
+ }
+ list->Uniforms[index].FragPos = progPos;
+ }
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Return the location/index of the named uniform in the uniform list,
+ * or -1 if not found.
+ */
+GLint
+_mesa_lookup_uniform(const struct gl_uniform_list *list, const char *name)
+{
+ GLuint i;
+ for (i = 0; i < list->NumUniforms; i++) {
+ if (!_mesa_strcmp(list->Uniforms[i].Name, name)) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+GLint
+_mesa_longest_uniform_name(const struct gl_uniform_list *list)
+{
+ GLint max = 0;
+ GLuint i;
+ for (i = 0; i < list->NumUniforms; i++) {
+ GLuint len = _mesa_strlen(list->Uniforms[i].Name);
+ if (len > max)
+ max = len;
+ }
+ return max;
+}
+
+
+void
+_mesa_print_uniforms(const struct gl_uniform_list *list)
+{
+ GLuint i;
+ printf("Uniform list %p:\n", (void *) list);
+ for (i = 0; i < list->NumUniforms; i++) {
+ printf("%d: %s %d %d\n",
+ i,
+ list->Uniforms[i].Name,
+ list->Uniforms[i].VertPos,
+ list->Uniforms[i].FragPos);
+ }
+}
diff --git a/src/mesa/shader/prog_uniform.h b/src/mesa/shader/prog_uniform.h
new file mode 100644
index 00000000000..735de28705a
--- /dev/null
+++ b/src/mesa/shader/prog_uniform.h
@@ -0,0 +1,91 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.1
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file prog_uniform.c
+ * Shader uniform functions.
+ * \author Brian Paul
+ */
+
+#ifndef PROG_UNIFORM_H
+#define PROG_UNIFORM_H
+
+#include "main/mtypes.h"
+#include "prog_statevars.h"
+
+
+/**
+ * Shader program uniform variable.
+ * The glGetUniformLocation() and glUniform() commands will use this
+ * information.
+ * Note that a uniform such as "binormal" might be used in both the
+ * vertex shader and the fragment shader. When glUniform() is called to
+ * set the uniform's value, it must be updated in both the vertex and
+ * fragment shaders. The uniform may be in different locations in the
+ * two shaders so we keep track of that here.
+ */
+struct gl_uniform
+{
+ const char *Name; /**< Null-terminated string */
+ GLint VertPos;
+ GLint FragPos;
+#if 0
+ GLenum DataType; /**< GL_FLOAT, GL_FLOAT_VEC2, etc */
+ GLuint Size; /**< Number of components (1..4) */
+#endif
+};
+
+
+/**
+ * List of gl_uniforms
+ */
+struct gl_uniform_list
+{
+ GLuint Size; /**< allocated size of Uniforms array */
+ GLuint NumUniforms; /**< number of uniforms in the array */
+ struct gl_uniform *Uniforms; /**< Array [Size] */
+};
+
+
+extern struct gl_uniform_list *
+_mesa_new_uniform_list(void);
+
+extern void
+_mesa_free_uniform_list(struct gl_uniform_list *list);
+
+extern GLboolean
+_mesa_append_uniform(struct gl_uniform_list *list,
+ const char *name, GLenum target, GLuint progPos);
+
+extern GLint
+_mesa_lookup_uniform(const struct gl_uniform_list *list, const char *name);
+
+extern GLint
+_mesa_longest_uniform_name(const struct gl_uniform_list *list);
+
+extern void
+_mesa_print_uniforms(const struct gl_uniform_list *list);
+
+
+#endif /* PROG_UNIFORM_H */
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index c539b527204..7048770cf74 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -59,9 +59,9 @@ _mesa_init_program(GLcontext *ctx)
ctx->VertexProgram.Enabled = GL_FALSE;
ctx->VertexProgram.PointSizeEnabled = GL_FALSE;
ctx->VertexProgram.TwoSideEnabled = GL_FALSE;
- ctx->VertexProgram.Current = (struct gl_vertex_program *) ctx->Shared->DefaultVertexProgram;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
+ ctx->Shared->DefaultVertexProgram);
assert(ctx->VertexProgram.Current);
- ctx->VertexProgram.Current->Base.RefCount++;
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) {
ctx->VertexProgram.TrackMatrix[i] = GL_NONE;
ctx->VertexProgram.TrackMatrixTransform[i] = GL_IDENTITY_NV;
@@ -70,9 +70,9 @@ _mesa_init_program(GLcontext *ctx)
#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
ctx->FragmentProgram.Enabled = GL_FALSE;
- ctx->FragmentProgram.Current = (struct gl_fragment_program *) ctx->Shared->DefaultFragmentProgram;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
+ ctx->Shared->DefaultFragmentProgram);
assert(ctx->FragmentProgram.Current);
- ctx->FragmentProgram.Current->Base.RefCount++;
#endif
/* XXX probably move this stuff */
@@ -92,18 +92,10 @@ void
_mesa_free_program_data(GLcontext *ctx)
{
#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
- if (ctx->VertexProgram.Current) {
- ctx->VertexProgram.Current->Base.RefCount--;
- if (ctx->VertexProgram.Current->Base.RefCount <= 0)
- ctx->Driver.DeleteProgram(ctx, &(ctx->VertexProgram.Current->Base));
- }
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
#endif
#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
- if (ctx->FragmentProgram.Current) {
- ctx->FragmentProgram.Current->Base.RefCount--;
- if (ctx->FragmentProgram.Current->Base.RefCount <= 0)
- ctx->Driver.DeleteProgram(ctx, &(ctx->FragmentProgram.Current->Base));
- }
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
#endif
/* XXX probably move this stuff */
#if FEATURE_ATI_fragment_shader
@@ -127,25 +119,17 @@ void
_mesa_update_default_objects_program(GLcontext *ctx)
{
#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
- if (ctx->VertexProgram.Current) {
- ctx->VertexProgram.Current->Base.RefCount--;
- if (ctx->VertexProgram.Current->Base.RefCount <= 0)
- ctx->Driver.DeleteProgram(ctx, &(ctx->VertexProgram.Current->Base));
- }
- ctx->VertexProgram.Current = (struct gl_vertex_program *) ctx->Shared->DefaultVertexProgram;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
+ (struct gl_vertex_program *)
+ ctx->Shared->DefaultVertexProgram);
assert(ctx->VertexProgram.Current);
- ctx->VertexProgram.Current->Base.RefCount++;
#endif
#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
- if (ctx->FragmentProgram.Current) {
- ctx->FragmentProgram.Current->Base.RefCount--;
- if (ctx->FragmentProgram.Current->Base.RefCount <= 0)
- ctx->Driver.DeleteProgram(ctx, &(ctx->FragmentProgram.Current->Base));
- }
- ctx->FragmentProgram.Current = (struct gl_fragment_program *) ctx->Shared->DefaultFragmentProgram;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
+ (struct gl_fragment_program *)
+ ctx->Shared->DefaultFragmentProgram);
assert(ctx->FragmentProgram.Current);
- ctx->FragmentProgram.Current->Base.RefCount++;
#endif
/* XXX probably move this stuff */
@@ -230,11 +214,17 @@ _mesa_init_program_struct( GLcontext *ctx, struct gl_program *prog,
{
(void) ctx;
if (prog) {
+ GLuint i;
+ _mesa_bzero(prog, sizeof(*prog));
prog->Id = id;
prog->Target = target;
prog->Resident = GL_TRUE;
prog->RefCount = 1;
prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
+
+ /* default mapping from samplers to texture units */
+ for (i = 0; i < MAX_SAMPLERS; i++)
+ prog->SamplerUnits[i] = i;
}
return prog;
@@ -284,19 +274,23 @@ _mesa_init_vertex_program( GLcontext *ctx, struct gl_vertex_program *prog,
struct gl_program *
_mesa_new_program(GLcontext *ctx, GLenum target, GLuint id)
{
+ struct gl_program *prog;
switch (target) {
case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
- return _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program),
+ prog = _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program),
target, id );
+ break;
case GL_FRAGMENT_PROGRAM_NV:
case GL_FRAGMENT_PROGRAM_ARB:
- return _mesa_init_fragment_program(ctx,
+ prog =_mesa_init_fragment_program(ctx,
CALLOC_STRUCT(gl_fragment_program),
target, id );
+ break;
default:
_mesa_problem(ctx, "bad target in _mesa_new_program");
- return NULL;
+ prog = NULL;
}
+ return prog;
}
@@ -311,6 +305,7 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog)
{
(void) ctx;
ASSERT(prog);
+ ASSERT(prog->RefCount==0);
if (prog == &_mesa_DummyProgram)
return;
@@ -318,16 +313,7 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog)
if (prog->String)
_mesa_free(prog->String);
- if (prog->Instructions) {
- GLuint i;
- for (i = 0; i < prog->NumInstructions; i++) {
- if (prog->Instructions[i].Data)
- _mesa_free(prog->Instructions[i].Data);
- if (prog->Instructions[i].Comment)
- _mesa_free((char *) prog->Instructions[i].Comment);
- }
- _mesa_free(prog->Instructions);
- }
+ _mesa_free_instructions(prog->Instructions, prog->NumInstructions);
if (prog->Parameters) {
_mesa_free_parameter_list(prog->Parameters);
@@ -366,6 +352,63 @@ _mesa_lookup_program(GLcontext *ctx, GLuint id)
/**
+ * Reference counting for vertex/fragment programs
+ */
+void
+_mesa_reference_program(GLcontext *ctx,
+ struct gl_program **ptr,
+ struct gl_program *prog)
+{
+ assert(ptr);
+ if (*ptr && prog) {
+ /* sanity check */
+ ASSERT((*ptr)->Target == prog->Target);
+ }
+ if (*ptr == prog) {
+ return; /* no change */
+ }
+ if (*ptr) {
+ GLboolean deleteFlag;
+
+ /*_glthread_LOCK_MUTEX((*ptr)->Mutex);*/
+#if 0
+ printf("Program %p ID=%u Target=%s Refcount-- to %d\n",
+ *ptr, (*ptr)->Id,
+ ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB ? "VP" : "FP"),
+ (*ptr)->RefCount - 1);
+#endif
+ ASSERT((*ptr)->RefCount > 0);
+ (*ptr)->RefCount--;
+
+ deleteFlag = ((*ptr)->RefCount == 0);
+ /*_glthread_UNLOCK_MUTEX((*ptr)->Mutex);*/
+
+ if (deleteFlag) {
+ ASSERT(ctx);
+ ctx->Driver.DeleteProgram(ctx, *ptr);
+ }
+
+ *ptr = NULL;
+ }
+
+ assert(!*ptr);
+ if (prog) {
+ /*_glthread_LOCK_MUTEX(prog->Mutex);*/
+ prog->RefCount++;
+#if 0
+ printf("Program %p ID=%u Target=%s Refcount++ to %d\n",
+ prog, prog->Id,
+ (prog->Target == GL_VERTEX_PROGRAM_ARB ? "VP" : "FP"),
+ prog->RefCount);
+#endif
+ /*_glthread_UNLOCK_MUTEX(prog->Mutex);*/
+ }
+
+ *ptr = prog;
+}
+
+
+/**
* Return a copy of a program.
* XXX Problem here if the program object is actually OO-derivation
* made by a device driver.
@@ -380,18 +423,20 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
return NULL;
assert(clone->Target == prog->Target);
+ assert(clone->RefCount == 1);
+
clone->String = (GLubyte *) _mesa_strdup((char *) prog->String);
- clone->RefCount = 1;
clone->Format = prog->Format;
clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions);
if (!clone->Instructions) {
- ctx->Driver.DeleteProgram(ctx, clone);
+ _mesa_reference_program(ctx, &clone, NULL);
return NULL;
}
_mesa_copy_instructions(clone->Instructions, prog->Instructions,
prog->NumInstructions);
clone->InputsRead = prog->InputsRead;
clone->OutputsWritten = prog->OutputsWritten;
+ clone->SamplersUsed = prog->SamplersUsed;
memcpy(clone->TexturesUsed, prog->TexturesUsed, sizeof(prog->TexturesUsed));
if (prog->Parameters)
@@ -445,6 +490,236 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
}
+/**
+ * Insert 'count' NOP instructions at 'start' in the given program.
+ * Adjust branch targets accordingly.
+ */
+GLboolean
+_mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count)
+{
+ const GLuint origLen = prog->NumInstructions;
+ const GLuint newLen = origLen + count;
+ struct prog_instruction *newInst;
+ GLuint i;
+
+ /* adjust branches */
+ for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *inst = prog->Instructions + i;
+ if (inst->BranchTarget > 0) {
+ if (inst->BranchTarget >= start) {
+ inst->BranchTarget += count;
+ }
+ }
+ }
+
+ /* Alloc storage for new instructions */
+ newInst = _mesa_alloc_instructions(newLen);
+ if (!newInst) {
+ return GL_FALSE;
+ }
+
+ /* Copy 'start' instructions into new instruction buffer */
+ _mesa_copy_instructions(newInst, prog->Instructions, start);
+
+ /* init the new instructions */
+ _mesa_init_instructions(newInst + start, count);
+
+ /* Copy the remaining/tail instructions to new inst buffer */
+ _mesa_copy_instructions(newInst + start + count,
+ prog->Instructions + start,
+ origLen - start);
+
+ /* free old instructions */
+ _mesa_free_instructions(prog->Instructions, origLen);
+
+ /* install new instructions */
+ prog->Instructions = newInst;
+ prog->NumInstructions = newLen;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Search instructions for registers that match (oldFile, oldIndex),
+ * replacing them with (newFile, newIndex).
+ */
+static void
+replace_registers(struct prog_instruction *inst, GLuint numInst,
+ GLuint oldFile, GLuint oldIndex,
+ GLuint newFile, GLuint newIndex)
+{
+ GLuint i, j;
+ for (i = 0; i < numInst; i++) {
+ /* src regs */
+ for (j = 0; j < _mesa_num_inst_src_regs(inst->Opcode); j++) {
+ if (inst[i].SrcReg[j].File == oldFile &&
+ inst[i].SrcReg[j].Index == oldIndex) {
+ inst[i].SrcReg[j].File = newFile;
+ inst[i].SrcReg[j].Index = newIndex;
+ }
+ }
+ /* dst reg */
+ if (inst[i].DstReg.File == oldFile && inst[i].DstReg.Index == oldIndex) {
+ inst[i].DstReg.File = newFile;
+ inst[i].DstReg.Index = newIndex;
+ }
+ }
+}
+
+
+/**
+ * Search instructions for references to program parameters. When found,
+ * increment the parameter index by 'offset'.
+ * Used when combining programs.
+ */
+static void
+adjust_param_indexes(struct prog_instruction *inst, GLuint numInst,
+ GLuint offset)
+{
+ GLuint i, j;
+ for (i = 0; i < numInst; i++) {
+ for (j = 0; j < _mesa_num_inst_src_regs(inst->Opcode); j++) {
+ GLuint f = inst[i].SrcReg[j].File;
+ if (f == PROGRAM_CONSTANT ||
+ f == PROGRAM_UNIFORM ||
+ f == PROGRAM_STATE_VAR) {
+ inst[i].SrcReg[j].Index += offset;
+ }
+ }
+ }
+}
+
+
+/**
+ * Combine two programs into one. Fix instructions so the outputs of
+ * the first program go to the inputs of the second program.
+ */
+struct gl_program *
+_mesa_combine_programs(GLcontext *ctx,
+ const struct gl_program *progA,
+ const struct gl_program *progB)
+{
+ struct prog_instruction *newInst;
+ struct gl_program *newProg;
+ const GLuint lenA = progA->NumInstructions - 1; /* omit END instr */
+ const GLuint lenB = progB->NumInstructions;
+ const GLuint numParamsA = _mesa_num_parameters(progA->Parameters);
+ const GLuint newLength = lenA + lenB;
+ GLbitfield inputsB;
+ GLuint i;
+
+ ASSERT(progA->Target == progB->Target);
+
+ newInst = _mesa_alloc_instructions(newLength);
+ if (!newInst)
+ return GL_FALSE;
+
+ _mesa_copy_instructions(newInst, progA->Instructions, lenA);
+ _mesa_copy_instructions(newInst + lenA, progB->Instructions, lenB);
+
+ /* adjust branch / instruction addresses for B's instructions */
+ for (i = 0; i < lenB; i++) {
+ newInst[lenA + i].BranchTarget += lenA;
+ }
+
+ newProg = ctx->Driver.NewProgram(ctx, progA->Target, 0);
+ newProg->Instructions = newInst;
+ newProg->NumInstructions = newLength;
+
+ if (newProg->Target == GL_FRAGMENT_PROGRAM_ARB) {
+ struct gl_fragment_program *fprogA, *fprogB, *newFprog;
+ fprogA = (struct gl_fragment_program *) progA;
+ fprogB = (struct gl_fragment_program *) progB;
+ newFprog = (struct gl_fragment_program *) newProg;
+
+ newFprog->UsesKill = fprogA->UsesKill || fprogB->UsesKill;
+
+ /* Connect color outputs of fprogA to color inputs of fprogB, via a
+ * new temporary register.
+ */
+ if ((progA->OutputsWritten & (1 << FRAG_RESULT_COLR)) &&
+ (progB->InputsRead & (1 << FRAG_ATTRIB_COL0))) {
+ GLint tempReg = _mesa_find_free_register(newProg, PROGRAM_TEMPORARY);
+ if (tempReg < 0) {
+ _mesa_problem(ctx, "No free temp regs found in "
+ "_mesa_combine_programs(), using 31");
+ tempReg = 31;
+ }
+ /* replace writes to result.color[0] with tempReg */
+ replace_registers(newInst, lenA,
+ PROGRAM_OUTPUT, FRAG_RESULT_COLR,
+ PROGRAM_TEMPORARY, tempReg);
+ /* replace reads from input.color[0] with tempReg */
+ replace_registers(newInst + lenA, lenB,
+ PROGRAM_INPUT, FRAG_ATTRIB_COL0,
+ PROGRAM_TEMPORARY, tempReg);
+ }
+
+ inputsB = progB->InputsRead;
+ if (progA->OutputsWritten & (1 << FRAG_RESULT_COLR)) {
+ inputsB &= ~(1 << FRAG_ATTRIB_COL0);
+ }
+ newProg->InputsRead = progA->InputsRead | inputsB;
+ newProg->OutputsWritten = progB->OutputsWritten;
+ newProg->SamplersUsed = progA->SamplersUsed | progB->SamplersUsed;
+ }
+ else {
+ /* vertex program */
+ assert(0); /* XXX todo */
+ }
+
+ /*
+ * Merge parameters (uniforms, constants, etc)
+ */
+ newProg->Parameters = _mesa_combine_parameter_lists(progA->Parameters,
+ progB->Parameters);
+
+ adjust_param_indexes(newInst + lenA, lenB, numParamsA);
+
+
+ return newProg;
+}
+
+
+
+
+/**
+ * Scan the given program to find a free register of the given type.
+ * \param regFile - PROGRAM_INPUT, PROGRAM_OUTPUT or PROGRAM_TEMPORARY
+ */
+GLint
+_mesa_find_free_register(const struct gl_program *prog, GLuint regFile)
+{
+ GLboolean used[MAX_PROGRAM_TEMPS];
+ GLuint i, k;
+
+ assert(regFile == PROGRAM_INPUT ||
+ regFile == PROGRAM_OUTPUT ||
+ regFile == PROGRAM_TEMPORARY);
+
+ _mesa_memset(used, 0, sizeof(used));
+
+ for (i = 0; i < prog->NumInstructions; i++) {
+ const struct prog_instruction *inst = prog->Instructions + i;
+ const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
+
+ for (k = 0; k < n; k++) {
+ if (inst->SrcReg[k].File == regFile) {
+ used[inst->SrcReg[k].Index] = GL_TRUE;
+ }
+ }
+ }
+
+ for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
+ if (!used[i])
+ return i;
+ }
+
+ return -1;
+}
+
+
/**
* Mixing ARB and NV vertex/fragment programs can be tricky.
@@ -513,9 +788,9 @@ _mesa_BindProgram(GLenum target, GLuint id)
/* Bind a default program */
newProg = NULL;
if (target == GL_VERTEX_PROGRAM_ARB) /* == GL_VERTEX_PROGRAM_NV */
- newProg = ctx->Shared->DefaultVertexProgram;
+ newProg = &ctx->Shared->DefaultVertexProgram->Base;
else
- newProg = ctx->Shared->DefaultFragmentProgram;
+ newProg = &ctx->Shared->DefaultFragmentProgram->Base;
}
else {
/* Bind a user program */
@@ -543,26 +818,16 @@ _mesa_BindProgram(GLenum target, GLuint id)
return;
}
- /* unbind/delete oldProg */
- if (curProg->Id != 0) {
- /* decrement refcount on previously bound fragment program */
- curProg->RefCount--;
- /* and delete if refcount goes below one */
- if (curProg->RefCount <= 0) {
- /* the program ID was already removed from the hash table */
- ctx->Driver.DeleteProgram(ctx, curProg);
- }
- }
-
/* bind newProg */
if (target == GL_VERTEX_PROGRAM_ARB) { /* == GL_VERTEX_PROGRAM_NV */
- ctx->VertexProgram.Current = (struct gl_vertex_program *) newProg;
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
+ (struct gl_vertex_program *) newProg);
}
else if (target == GL_FRAGMENT_PROGRAM_NV ||
target == GL_FRAGMENT_PROGRAM_ARB) {
- ctx->FragmentProgram.Current = (struct gl_fragment_program *) newProg;
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
+ (struct gl_fragment_program *) newProg);
}
- newProg->RefCount++;
/* Never null pointers */
ASSERT(ctx->VertexProgram.Current);
@@ -620,10 +885,7 @@ _mesa_DeletePrograms(GLsizei n, const GLuint *ids)
}
/* The ID is immediately available for re-use now */
_mesa_HashRemove(ctx->Shared->Programs, ids[i]);
- prog->RefCount--;
- if (prog->RefCount <= 0) {
- ctx->Driver.DeleteProgram(ctx, prog);
- }
+ _mesa_reference_program(ctx, &prog, NULL);
}
}
}
diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h
index ea2c8c30508..f1a69a2c016 100644
--- a/src/mesa/shader/program.h
+++ b/src/mesa/shader/program.h
@@ -86,10 +86,43 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog);
extern struct gl_program *
_mesa_lookup_program(GLcontext *ctx, GLuint id);
+extern void
+_mesa_reference_program(GLcontext *ctx,
+ struct gl_program **ptr,
+ struct gl_program *prog);
+
+static INLINE void
+_mesa_reference_vertprog(GLcontext *ctx,
+ struct gl_vertex_program **ptr,
+ struct gl_vertex_program *prog)
+{
+ _mesa_reference_program(ctx, (struct gl_program **) ptr,
+ (struct gl_program *) prog);
+}
+
+static INLINE void
+_mesa_reference_fragprog(GLcontext *ctx,
+ struct gl_fragment_program **ptr,
+ struct gl_fragment_program *prog)
+{
+ _mesa_reference_program(ctx, (struct gl_program **) ptr,
+ (struct gl_program *) prog);
+}
extern struct gl_program *
_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog);
+extern GLboolean
+_mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count);
+
+extern struct gl_program *
+_mesa_combine_programs(GLcontext *ctx,
+ const struct gl_program *progA,
+ const struct gl_program *progB);
+
+extern GLint
+_mesa_find_free_register(const struct gl_program *prog, GLuint regFile);
+
/*
* API functions common to ARB/NV_vertex/fragment_program
diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c
index fc5b0497fe3..7d560c74a54 100644
--- a/src/mesa/shader/programopt.c
+++ b/src/mesa/shader/programopt.c
@@ -35,6 +35,7 @@
#include "context.h"
#include "prog_parameter.h"
#include "prog_statevars.h"
+#include "program.h"
#include "programopt.h"
#include "prog_instruction.h"
@@ -102,7 +103,7 @@ _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog)
_mesa_copy_instructions (newInst + 4, vprog->Base.Instructions, origLen);
/* free old instructions */
- _mesa_free(vprog->Base.Instructions);
+ _mesa_free_instructions(vprog->Base.Instructions, origLen);
/* install new instructions */
vprog->Base.Instructions = newInst;
@@ -192,13 +193,13 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog)
inst->DstReg.WriteMask = WRITEMASK_X;
inst->SrcReg[0].File = PROGRAM_INPUT;
inst->SrcReg[0].Index = FRAG_ATTRIB_FOGC;
- inst->SrcReg[0].Swizzle = SWIZZLE_X;
+ inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
inst->SrcReg[1].File = PROGRAM_STATE_VAR;
inst->SrcReg[1].Index = fogPRefOpt;
- inst->SrcReg[1].Swizzle = SWIZZLE_X;
+ inst->SrcReg[1].Swizzle = SWIZZLE_XXXX;
inst->SrcReg[2].File = PROGRAM_STATE_VAR;
inst->SrcReg[2].Index = fogPRefOpt;
- inst->SrcReg[2].Swizzle = SWIZZLE_Y;
+ inst->SrcReg[2].Swizzle = SWIZZLE_YYYY;
inst->SaturateMode = SATURATE_ZERO_ONE;
inst++;
}
@@ -214,10 +215,10 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog)
inst->SrcReg[0].File = PROGRAM_STATE_VAR;
inst->SrcReg[0].Index = fogPRefOpt;
inst->SrcReg[0].Swizzle
- = (fprog->FogOption == GL_EXP) ? SWIZZLE_Z : SWIZZLE_W;
+ = (fprog->FogOption == GL_EXP) ? SWIZZLE_ZZZZ : SWIZZLE_WWWW;
inst->SrcReg[1].File = PROGRAM_INPUT;
inst->SrcReg[1].Index = FRAG_ATTRIB_FOGC;
- inst->SrcReg[1].Swizzle = SWIZZLE_X;
+ inst->SrcReg[1].Swizzle = SWIZZLE_XXXX;
inst++;
if (fprog->FogOption == GL_EXP2) {
/* MUL fogFactorTemp.x, fogFactorTemp.x, fogFactorTemp.x; */
@@ -227,10 +228,10 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog)
inst->DstReg.WriteMask = WRITEMASK_X;
inst->SrcReg[0].File = PROGRAM_TEMPORARY;
inst->SrcReg[0].Index = fogFactorTemp;
- inst->SrcReg[0].Swizzle = SWIZZLE_X;
+ inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
inst->SrcReg[1].File = PROGRAM_TEMPORARY;
inst->SrcReg[1].Index = fogFactorTemp;
- inst->SrcReg[1].Swizzle = SWIZZLE_X;
+ inst->SrcReg[1].Swizzle = SWIZZLE_XXXX;
inst++;
}
/* EX2_SAT fogFactorTemp.x, -fogFactorTemp.x; */
@@ -240,8 +241,8 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog)
inst->DstReg.WriteMask = WRITEMASK_X;
inst->SrcReg[0].File = PROGRAM_TEMPORARY;
inst->SrcReg[0].Index = fogFactorTemp;
- inst->SrcReg[0].NegateBase = GL_TRUE;
- inst->SrcReg[0].Swizzle = SWIZZLE_X;
+ inst->SrcReg[0].NegateBase = NEGATE_XYZW;
+ inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
inst->SaturateMode = SATURATE_ZERO_ONE;
inst++;
}
@@ -252,8 +253,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog)
inst->DstReg.WriteMask = WRITEMASK_XYZ;
inst->SrcReg[0].File = PROGRAM_TEMPORARY;
inst->SrcReg[0].Index = fogFactorTemp;
- inst->SrcReg[0].Swizzle
- = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
+ inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
inst->SrcReg[1].File = PROGRAM_TEMPORARY;
inst->SrcReg[1].Index = colorTemp;
inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
@@ -275,7 +275,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog)
inst++;
/* free old instructions */
- _mesa_free(fprog->Base.Instructions);
+ _mesa_free_instructions(fprog->Base.Instructions, origLen);
/* install new instructions */
fprog->Base.Instructions = newInst;
@@ -365,3 +365,94 @@ _mesa_count_texture_instructions(struct gl_program *prog)
}
}
+
+/**
+ * Scan/rewrite program to remove reads of varying (output) registers.
+ * In GLSL vertex shaders, varying vars can be read and written.
+ * Normally, vertex varying vars are implemented as output registers.
+ * On some hardware, trying to read an output register causes trouble.
+ * So, rewrite the program to use a temporary register in this case.
+ */
+void
+_mesa_remove_varying_reads(struct gl_program *prog)
+{
+ GLuint i;
+ GLint outputMap[VERT_RESULT_MAX];
+ GLuint numVaryingReads = 0;
+
+ assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
+
+ for (i = 0; i < VERT_RESULT_MAX; i++)
+ outputMap[i] = -1;
+
+ /* look for instructions which read from varying vars */
+ for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *inst = prog->Instructions + i;
+ const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+ GLuint j;
+ for (j = 0; j < numSrc; j++) {
+ if (inst->SrcReg[j].File == PROGRAM_VARYING) {
+ /* replace the read with a temp reg */
+ const GLuint var = inst->SrcReg[j].Index;
+ if (outputMap[var] == -1) {
+ numVaryingReads++;
+ outputMap[var] = _mesa_find_free_register(prog,
+ PROGRAM_TEMPORARY);
+ }
+ inst->SrcReg[j].File = PROGRAM_TEMPORARY;
+ inst->SrcReg[j].Index = outputMap[var];
+ }
+ }
+ }
+
+ if (numVaryingReads == 0)
+ return; /* nothing to be done */
+
+ /* look for instructions which write to the varying vars identified above */
+ for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *inst = prog->Instructions + i;
+ const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+ GLuint j;
+ for (j = 0; j < numSrc; j++) {
+ if (inst->DstReg.File == PROGRAM_VARYING &&
+ outputMap[inst->DstReg.Index] >= 0) {
+ /* change inst to write to the temp reg, instead of the varying */
+ inst->DstReg.File = PROGRAM_TEMPORARY;
+ inst->DstReg.Index = outputMap[inst->DstReg.Index];
+ }
+ }
+ }
+
+ /* insert new instructions to copy the temp vars to the varying vars */
+ {
+ struct prog_instruction *inst;
+ GLint endPos, var;
+
+ /* Look for END instruction and insert the new varying writes */
+ endPos = -1;
+ for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *inst = prog->Instructions + i;
+ if (inst->Opcode == OPCODE_END) {
+ endPos = i;
+ _mesa_insert_instructions(prog, i, numVaryingReads);
+ break;
+ }
+ }
+
+ assert(endPos >= 0);
+
+ /* insert new MOV instructions here */
+ inst = prog->Instructions + endPos;
+ for (var = 0; var < VERT_RESULT_MAX; var++) {
+ if (outputMap[var] >= 0) {
+ /* MOV VAR[var], TEMP[tmp]; */
+ inst->Opcode = OPCODE_MOV;
+ inst->DstReg.File = PROGRAM_VARYING;
+ inst->DstReg.Index = var;
+ inst->SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst->SrcReg[0].Index = outputMap[var];
+ inst++;
+ }
+ }
+ }
+}
diff --git a/src/mesa/shader/programopt.h b/src/mesa/shader/programopt.h
index ce63644bbf5..47ff2f0c7be 100644
--- a/src/mesa/shader/programopt.h
+++ b/src/mesa/shader/programopt.h
@@ -39,5 +39,7 @@ _mesa_count_texture_indirections(struct gl_program *prog);
extern void
_mesa_count_texture_instructions(struct gl_program *prog);
+extern void
+_mesa_remove_varying_reads(struct gl_program *prog);
#endif /* PROGRAMOPT_H */
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index b0f79c29c1e..0bb96a0d6c0 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -43,6 +43,7 @@
#include "prog_parameter.h"
#include "prog_print.h"
#include "prog_statevars.h"
+#include "prog_uniform.h"
#include "shader/shader_api.h"
#include "shader/slang/slang_compile.h"
#include "shader/slang/slang_link.h"
@@ -52,7 +53,7 @@
/**
* Allocate a new gl_shader_program object, initialize it.
*/
-struct gl_shader_program *
+static struct gl_shader_program *
_mesa_new_shader_program(GLcontext *ctx, GLuint name)
{
struct gl_shader_program *shProg;
@@ -74,26 +75,11 @@ void
_mesa_clear_shader_program_data(GLcontext *ctx,
struct gl_shader_program *shProg)
{
- if (shProg->VertexProgram) {
- if (shProg->VertexProgram->Base.Parameters == shProg->Uniforms) {
- /* to prevent a double-free in the next call */
- shProg->VertexProgram->Base.Parameters = NULL;
- }
- ctx->Driver.DeleteProgram(ctx, &shProg->VertexProgram->Base);
- shProg->VertexProgram = NULL;
- }
-
- if (shProg->FragmentProgram) {
- if (shProg->FragmentProgram->Base.Parameters == shProg->Uniforms) {
- /* to prevent a double-free in the next call */
- shProg->FragmentProgram->Base.Parameters = NULL;
- }
- ctx->Driver.DeleteProgram(ctx, &shProg->FragmentProgram->Base);
- shProg->FragmentProgram = NULL;
- }
+ _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
+ _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
if (shProg->Uniforms) {
- _mesa_free_parameter_list(shProg->Uniforms);
+ _mesa_free_uniform_list(shProg->Uniforms);
shProg->Uniforms = NULL;
}
@@ -177,8 +163,10 @@ _mesa_reference_shader_program(GLcontext *ctx,
ASSERT(old->RefCount > 0);
old->RefCount--;
- /*printf("SHPROG DECR %p (%d) to %d\n",
- (void*) old, old->Name, old->RefCount);*/
+#if 0
+ printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
+ (void *) old, old->Name, old->RefCount);
+#endif
deleteFlag = (old->RefCount == 0);
if (deleteFlag) {
@@ -192,8 +180,10 @@ _mesa_reference_shader_program(GLcontext *ctx,
if (shProg) {
shProg->RefCount++;
- /*printf("SHPROG INCR %p (%d) to %d\n",
- (void*) shProg, shProg->Name, shProg->RefCount);*/
+#if 0
+ printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
+ (void *) shProg, shProg->Name, shProg->RefCount);
+#endif
*ptr = shProg;
}
}
@@ -248,10 +238,8 @@ _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh)
_mesa_free((void *) sh->Source);
if (sh->InfoLog)
_mesa_free(sh->InfoLog);
- for (i = 0; i < sh->NumPrograms; i++) {
- assert(sh->Programs[i]);
- ctx->Driver.DeleteProgram(ctx, sh->Programs[i]);
- }
+ for (i = 0; i < sh->NumPrograms; i++)
+ _mesa_reference_program(ctx, &sh->Programs[i], NULL);
if (sh->Programs)
_mesa_free(sh->Programs);
_mesa_free(sh);
@@ -373,57 +361,9 @@ copy_string(GLchar *dst, GLsizei maxLength, GLsizei *length, const GLchar *src)
/**
- * Return size (in floats) of the given GLSL type.
- * See also _slang_sizeof_type_specifier().
- */
-static GLint
-sizeof_glsl_type(GLenum type)
-{
- switch (type) {
- case GL_BOOL:
- case GL_FLOAT:
- case GL_INT:
- return 1;
- case GL_BOOL_VEC2:
- case GL_FLOAT_VEC2:
- case GL_INT_VEC2:
- return 2;
- case GL_BOOL_VEC3:
- case GL_FLOAT_VEC3:
- case GL_INT_VEC3:
- return 3;
- case GL_BOOL_VEC4:
- case GL_FLOAT_VEC4:
- case GL_INT_VEC4:
- return 4;
- case GL_FLOAT_MAT2:
- return 8; /* 2 rows of 4, actually */
- case GL_FLOAT_MAT3:
- return 12; /* 3 rows of 4, actually */
- case GL_FLOAT_MAT4:
- return 16;
- case GL_FLOAT_MAT2x3:
- return 8; /* 2 rows of 4, actually */
- case GL_FLOAT_MAT2x4:
- return 8;
- case GL_FLOAT_MAT3x2:
- return 12; /* 3 rows of 4, actually */
- case GL_FLOAT_MAT3x4:
- return 12;
- case GL_FLOAT_MAT4x2:
- return 16; /* 4 rows of 4, actually */
- case GL_FLOAT_MAT4x3:
- return 16; /* 4 rows of 4, actually */
- default:
- return 0; /* error */
- }
-}
-
-
-/**
* Called via ctx->Driver.AttachShader()
*/
-void
+static void
_mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
{
struct gl_shader_program *shProg
@@ -464,7 +404,38 @@ _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
}
-void
+static GLint
+_mesa_get_attrib_location(GLcontext *ctx, GLuint program,
+ const GLchar *name)
+{
+ struct gl_shader_program *shProg
+ = _mesa_lookup_shader_program(ctx, program);
+
+ if (!shProg) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttribLocation");
+ return -1;
+ }
+
+ if (!shProg->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetAttribLocation(program not linked)");
+ return -1;
+ }
+
+ if (!name)
+ return -1;
+
+ if (shProg->Attributes) {
+ GLint i = _mesa_lookup_parameter_index(shProg->Attributes, -1, name);
+ if (i >= 0) {
+ return shProg->Attributes->Parameters[i].StateIndexes[0];
+ }
+ }
+ return -1;
+}
+
+
+static void
_mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
const GLchar *name)
{
@@ -510,7 +481,7 @@ _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
}
-GLuint
+static GLuint
_mesa_create_shader(GLcontext *ctx, GLenum type)
{
struct gl_shader *sh;
@@ -534,7 +505,7 @@ _mesa_create_shader(GLcontext *ctx, GLenum type)
}
-GLuint
+static GLuint
_mesa_create_program(GLcontext *ctx)
{
GLuint name;
@@ -555,7 +526,7 @@ _mesa_create_program(GLcontext *ctx)
* Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
* DeleteProgramARB.
*/
-void
+static void
_mesa_delete_program2(GLcontext *ctx, GLuint name)
{
/*
@@ -581,7 +552,7 @@ _mesa_delete_program2(GLcontext *ctx, GLuint name)
}
-void
+static void
_mesa_delete_shader(GLcontext *ctx, GLuint shader)
{
struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
@@ -596,7 +567,7 @@ _mesa_delete_shader(GLcontext *ctx, GLuint shader)
}
-void
+static void
_mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
{
struct gl_shader_program *shProg
@@ -658,7 +629,7 @@ _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
}
-void
+static void
_mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
GLsizei maxLength, GLsizei *length, GLint *size,
GLenum *type, GLchar *nameOut)
@@ -684,64 +655,64 @@ _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
shProg->Attributes->Parameters[index].Name);
sz = shProg->Attributes->Parameters[index].Size;
if (size)
- *size = 1; /* attributes may not be arrays */
- if (type && sz > 0 && sz <= 4) /* XXX this is a temporary hack */
- *type = vec_types[sz - 1];
+ *size = sz;
+ if (type)
+ *type = vec_types[sz]; /* XXX this is a temporary hack */
}
/**
* Called via ctx->Driver.GetActiveUniform().
*/
-void
+static void
_mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
GLsizei maxLength, GLsizei *length, GLint *size,
GLenum *type, GLchar *nameOut)
{
- struct gl_shader_program *shProg
+ const struct gl_shader_program *shProg
= _mesa_lookup_shader_program(ctx, program);
- GLuint ind, j;
+ const struct gl_program *prog;
+ GLint progPos;
if (!shProg) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform");
return;
}
- if (!shProg->Uniforms || index >= shProg->Uniforms->NumParameters) {
+ if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
return;
}
- ind = 0;
- for (j = 0; j < shProg->Uniforms->NumParameters; j++) {
- if (shProg->Uniforms->Parameters[j].Type == PROGRAM_UNIFORM ||
- shProg->Uniforms->Parameters[j].Type == PROGRAM_SAMPLER) {
- if (ind == index) {
- GLuint uSize = shProg->Uniforms->Parameters[j].Size;
- GLenum uType = shProg->Uniforms->Parameters[j].DataType;
- /* found it */
- copy_string(nameOut, maxLength, length,
- shProg->Uniforms->Parameters[j].Name);
- if (size) {
- /* convert from floats to 'type' (eg: sizeof(mat4x4)=1) */
- *size = uSize / sizeof_glsl_type(uType);
- }
- if (type)
- *type = uType;
- return;
- }
- ind++;
+ progPos = shProg->Uniforms->Uniforms[index].VertPos;
+ if (progPos >= 0) {
+ prog = &shProg->VertexProgram->Base;
+ }
+ else {
+ progPos = shProg->Uniforms->Uniforms[index].FragPos;
+ if (progPos >= 0) {
+ prog = &shProg->FragmentProgram->Base;
}
}
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
+ if (!prog || progPos < 0)
+ return; /* should never happen */
+
+ if (nameOut)
+ copy_string(nameOut, maxLength, length,
+ prog->Parameters->Parameters[progPos].Name);
+ if (size)
+ *size = prog->Parameters->Parameters[progPos].Size;
+
+ if (type)
+ *type = prog->Parameters->Parameters[progPos].DataType;
}
/**
* Called via ctx->Driver.GetAttachedShaders().
*/
-void
+static void
_mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
GLsizei *count, GLuint *obj)
{
@@ -761,38 +732,7 @@ _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
}
-GLint
-_mesa_get_attrib_location(GLcontext *ctx, GLuint program,
- const GLchar *name)
-{
- struct gl_shader_program *shProg
- = _mesa_lookup_shader_program(ctx, program);
-
- if (!shProg) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttribLocation");
- return -1;
- }
-
- if (!shProg->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetAttribLocation(program not linked)");
- return -1;
- }
-
- if (!name)
- return -1;
-
- if (shProg->Attributes) {
- GLint i = _mesa_lookup_parameter_index(shProg->Attributes, -1, name);
- if (i >= 0) {
- return shProg->Attributes->Parameters[i].StateIndexes[0];
- }
- }
- return -1;
-}
-
-
-GLuint
+static GLuint
_mesa_get_handle(GLcontext *ctx, GLenum pname)
{
#if 0
@@ -816,7 +756,7 @@ _mesa_get_handle(GLcontext *ctx, GLenum pname)
}
-void
+static void
_mesa_get_programiv(GLcontext *ctx, GLuint program,
GLenum pname, GLint *params)
{
@@ -852,14 +792,10 @@ _mesa_get_programiv(GLcontext *ctx, GLuint program,
PROGRAM_INPUT) + 1;
break;
case GL_ACTIVE_UNIFORMS:
- *params
- = _mesa_num_parameters_of_type(shProg->Uniforms, PROGRAM_UNIFORM)
- + _mesa_num_parameters_of_type(shProg->Uniforms, PROGRAM_SAMPLER);
+ *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
break;
case GL_ACTIVE_UNIFORM_MAX_LENGTH:
- *params = MAX2(
- _mesa_longest_parameter_name(shProg->Uniforms, PROGRAM_UNIFORM),
- _mesa_longest_parameter_name(shProg->Uniforms, PROGRAM_SAMPLER));
+ *params = _mesa_longest_uniform_name(shProg->Uniforms);
if (*params > 0)
(*params)++; /* add one for terminating zero */
break;
@@ -870,7 +806,7 @@ _mesa_get_programiv(GLcontext *ctx, GLuint program,
}
-void
+static void
_mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
{
struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
@@ -903,7 +839,7 @@ _mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
}
-void
+static void
_mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
GLsizei *length, GLchar *infoLog)
{
@@ -917,7 +853,7 @@ _mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
}
-void
+static void
_mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
GLsizei *length, GLchar *infoLog)
{
@@ -933,7 +869,7 @@ _mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
/**
* Called via ctx->Driver.GetShaderSource().
*/
-void
+static void
_mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
GLsizei *length, GLchar *sourceOut)
{
@@ -949,49 +885,34 @@ _mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
/**
* Called via ctx->Driver.GetUniformfv().
*/
-void
+static void
_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
GLfloat *params)
{
struct gl_shader_program *shProg
= _mesa_lookup_shader_program(ctx, program);
if (shProg) {
- GLint i;
- if (location >= 0 && location < shProg->Uniforms->NumParameters) {
- GLuint uSize;
- GLenum uType;
- GLint rows = 0;
- uType = shProg->Uniforms->Parameters[location].DataType;
- uSize = sizeof_glsl_type(uType);
- /* Matrix types need special handling, because they span several
- * parameters, and may also not be fully packed.
- */
- switch (shProg->Uniforms->Parameters[location].DataType) {
- case GL_FLOAT_MAT2:
- case GL_FLOAT_MAT3x2:
- case GL_FLOAT_MAT4x2:
- rows = 2;
- break;
- case GL_FLOAT_MAT2x3:
- case GL_FLOAT_MAT3:
- case GL_FLOAT_MAT4x3:
- rows = 3;
- break;
- case GL_FLOAT_MAT2x4:
- case GL_FLOAT_MAT3x4:
- case GL_FLOAT_MAT4:
- rows = 4;
+ if (location < shProg->Uniforms->NumUniforms) {
+ GLint progPos, i;
+ const struct gl_program *prog = NULL;
+
+ progPos = shProg->Uniforms->Uniforms[location].VertPos;
+ if (progPos >= 0) {
+ prog = &shProg->VertexProgram->Base;
}
- if (rows != 0) {
- GLint r, c;
- for (c = 0, i = 0; c * 4 < uSize; c++)
- for (r = 0; r < rows; r++, i++)
- params[i] = shProg->Uniforms->ParameterValues[location + c][r];
+ else {
+ progPos = shProg->Uniforms->Uniforms[location].FragPos;
+ if (progPos >= 0) {
+ prog = &shProg->FragmentProgram->Base;
+ }
}
- else
- for (i = 0; i < uSize; i++) {
- params[i] = shProg->Uniforms->ParameterValues[location][i];
+
+ ASSERT(prog);
+ if (prog) {
+ for (i = 0; i < prog->Parameters->Parameters[progPos].Size; i++) {
+ params[i] = prog->Parameters->ParameterValues[progPos][i];
}
+ }
}
else {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetUniformfv(location)");
@@ -1006,32 +927,19 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
/**
* Called via ctx->Driver.GetUniformLocation().
*/
-GLint
+static GLint
_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
{
struct gl_shader_program *shProg
= _mesa_lookup_shader_program(ctx, program);
- if (shProg) {
- GLuint loc;
- for (loc = 0; loc < shProg->Uniforms->NumParameters; loc++) {
- const struct gl_program_parameter *u
- = shProg->Uniforms->Parameters + loc;
- /* XXX this is a temporary simplification / short-cut.
- * We need to handle things like "e.c[0].b" as seen in the
- * GLSL orange book, page 189.
- */
- if ((u->Type == PROGRAM_UNIFORM ||
- u->Type == PROGRAM_SAMPLER) && !strcmp(u->Name, name)) {
- return loc;
- }
- }
- }
- return -1;
+ if (!shProg)
+ return -1;
+ return _mesa_lookup_uniform(shProg->Uniforms, name);
}
-GLboolean
+static GLboolean
_mesa_is_program(GLcontext *ctx, GLuint name)
{
struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
@@ -1039,7 +947,7 @@ _mesa_is_program(GLcontext *ctx, GLuint name)
}
-GLboolean
+static GLboolean
_mesa_is_shader(GLcontext *ctx, GLuint name)
{
struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
@@ -1051,7 +959,7 @@ _mesa_is_shader(GLcontext *ctx, GLuint name)
/**
* Called via ctx->Driver.ShaderSource()
*/
-void
+static void
_mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
{
struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
@@ -1072,7 +980,7 @@ _mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
/**
* Called via ctx->Driver.CompileShader()
*/
-void
+static void
_mesa_compile_shader(GLcontext *ctx, GLuint shaderObj)
{
struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
@@ -1089,7 +997,7 @@ _mesa_compile_shader(GLcontext *ctx, GLuint shaderObj)
/**
* Called via ctx->Driver.LinkProgram()
*/
-void
+static void
_mesa_link_program(GLcontext *ctx, GLuint program)
{
struct gl_shader_program *shProg;
@@ -1100,6 +1008,8 @@ _mesa_link_program(GLcontext *ctx, GLuint program)
return;
}
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+
_slang_link(ctx, program, shProg);
}
@@ -1136,55 +1046,121 @@ _mesa_use_program(GLcontext *ctx, GLuint program)
}
+
/**
- * Called via ctx->Driver.Uniform().
+ * Update the vertex and fragment program's TexturesUsed arrays.
*/
-void
-_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
- const GLvoid *values, GLenum type)
+static void
+update_textures_used(struct gl_program *prog)
{
- struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
- GLint elems, i, k;
- GLenum uType;
- GLsizei maxCount;
+ GLuint s;
- if (!shProg || !shProg->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
- return;
- }
+ memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
- if (location == -1)
- return; /* The standard specifies this as a no-op */
-
- /* The spec says this is GL_INVALID_OPERATION, although it seems like it
- * ought to be GL_INVALID_VALUE
- */
- if (location < 0 || location >= (GLint) shProg->Uniforms->NumParameters) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location)");
- return;
+ for (s = 0; s < MAX_SAMPLERS; s++) {
+ if (prog->SamplersUsed & (1 << s)) {
+ GLuint u = prog->SamplerUnits[s];
+ GLuint t = prog->SamplerTargets[s];
+ assert(u < MAX_TEXTURE_IMAGE_UNITS);
+ prog->TexturesUsed[u] |= (1 << t);
+ }
}
+}
- FLUSH_VERTICES(ctx, _NEW_PROGRAM);
- uType = shProg->Uniforms->Parameters[location].DataType;
- /*
- * If we're setting a sampler, we must use glUniformi1()!
- */
- if (shProg->Uniforms->Parameters[location].Type == PROGRAM_SAMPLER) {
- GLint unit;
+/**
+ * Set the value of a program's uniform variable.
+ * \param program the program whose uniform to update
+ * \param location the location/index of the uniform
+ * \param type the datatype of the uniform
+ * \param count the number of uniforms to set
+ * \param elems number of elements per uniform
+ * \param values the new values
+ */
+static void
+set_program_uniform(GLcontext *ctx, struct gl_program *program, GLint location,
+ GLenum type, GLint count, GLint elems, const void *values)
+{
+ if (program->Parameters->Parameters[location].Type == PROGRAM_SAMPLER) {
+ /* This controls which texture unit which is used by a sampler */
+ GLuint texUnit, sampler;
+
+ /* data type for setting samplers must be int */
if (type != GL_INT || count != 1) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glUniform(only glUniform1i can be used "
"to set sampler uniforms)");
return;
}
+
+ sampler = (GLuint) program->Parameters->ParameterValues[location][0];
+ texUnit = ((GLuint *) values)[0];
+
/* check that the sampler (tex unit index) is legal */
- unit = ((GLint *) values)[0];
- if (unit >= ctx->Const.MaxTextureImageUnits) {
+ if (texUnit >= ctx->Const.MaxTextureImageUnits) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glUniform1(invalid sampler/tex unit index)");
return;
}
+
+ /* This maps a sampler to a texture unit: */
+ program->SamplerUnits[sampler] = texUnit;
+ update_textures_used(program);
+
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ }
+ else {
+ /* ordinary uniform variable */
+ GLint k, i;
+
+ if (count * elems > program->Parameters->Parameters[location].Size) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(count too large)");
+ return;
+ }
+
+ for (k = 0; k < count; k++) {
+ GLfloat *uniformVal = program->Parameters->ParameterValues[location + k];
+ if (type == GL_INT ||
+ type == GL_INT_VEC2 ||
+ type == GL_INT_VEC3 ||
+ type == GL_INT_VEC4) {
+ const GLint *iValues = ((const GLint *) values) + k * elems;
+ for (i = 0; i < elems; i++) {
+ uniformVal[i] = (GLfloat) iValues[i];
+ }
+ }
+ else {
+ const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
+ for (i = 0; i < elems; i++) {
+ uniformVal[i] = fValues[i];
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ * Called via ctx->Driver.Uniform().
+ */
+static void
+_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
+ const GLvoid *values, GLenum type)
+{
+ struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+ GLint elems;
+
+ if (!shProg || !shProg->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
+ return;
+ }
+
+ if (location == -1)
+ return; /* The standard specifies this as a no-op */
+
+ if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)");
+ return;
}
if (count < 0) {
@@ -1214,69 +1190,56 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
return;
}
- /* OpenGL requires types to match exactly, except that one can convert
- * float or int array to boolean array.
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+
+ /* A uniform var may be used by both a vertex shader and a fragment
+ * shader. We may need to update one or both shader's uniform here:
*/
- switch (uType)
- {
- case GL_BOOL:
- case GL_BOOL_VEC2:
- case GL_BOOL_VEC3:
- case GL_BOOL_VEC4:
- if (elems != sizeof_glsl_type(uType)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(count mismatch)");
- }
- break;
- case PROGRAM_SAMPLER:
- break;
- default:
- if (shProg->Uniforms->Parameters[location].Type != PROGRAM_SAMPLER
- && uType != type) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
- }
- break;
+ if (shProg->VertexProgram) {
+ GLint loc = shProg->Uniforms->Uniforms[location].VertPos;
+ if (loc >= 0) {
+ set_program_uniform(ctx, &shProg->VertexProgram->Base,
+ loc, type, count, elems, values);
+ }
+ }
+
+ if (shProg->FragmentProgram) {
+ GLint loc = shProg->Uniforms->Uniforms[location].FragPos;
+ if (loc >= 0) {
+ set_program_uniform(ctx, &shProg->FragmentProgram->Base,
+ loc, type, count, elems, values);
+ }
}
+}
+
- /* XXX if this is a base type, then count must equal 1. However, we
- * don't have enough information from the compiler to distinguish a
- * base type from a 1-element array of that type. The standard allows
- * count to overrun an array, in which case the overflow is ignored.
+static void
+set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
+ GLuint location, GLuint rows, GLuint cols,
+ GLboolean transpose, const GLfloat *values)
+{
+ /*
+ * Note: the _columns_ of a matrix are stored in program registers, not
+ * the rows.
*/
- maxCount = shProg->Uniforms->Parameters[location].Size / elems;
- if (count > maxCount) count = maxCount;
-
- for (k = 0; k < count; k++) {
- GLfloat *uniformVal = shProg->Uniforms->ParameterValues[location + k];
- if (type == GL_INT ||
- type == GL_INT_VEC2 ||
- type == GL_INT_VEC3 ||
- type == GL_INT_VEC4) {
- const GLint *iValues = ((const GLint *) values) + k * elems;
- for (i = 0; i < elems; i++) {
- uniformVal[i] = (GLfloat) iValues[i];
+ /* XXXX need to test 3x3 and 2x2 matrices... */
+ if (transpose) {
+ GLuint row, col;
+ for (col = 0; col < cols; col++) {
+ GLfloat *v = program->Parameters->ParameterValues[location + col];
+ for (row = 0; row < rows; row++) {
+ v[row] = values[row * cols + col];
}
}
- else {
- const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
- for (i = 0; i < elems; i++) {
- uniformVal[i] = fValues[i];
+ }
+ else {
+ GLuint row, col;
+ for (col = 0; col < cols; col++) {
+ GLfloat *v = program->Parameters->ParameterValues[location + col];
+ for (row = 0; row < rows; row++) {
+ v[row] = values[col * rows + row];
}
}
- if (uType == GL_BOOL ||
- uType == GL_BOOL_VEC2 ||
- uType == GL_BOOL_VEC3 ||
- uType == GL_BOOL_VEC4) {
- for (i = 0; i < elems; i++)
- uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
- }
- }
-
- if (shProg->Uniforms->Parameters[location].Type == PROGRAM_SAMPLER) {
- if (shProg->VertexProgram)
- _slang_resolve_samplers(shProg, &shProg->VertexProgram->Base);
- if (shProg->FragmentProgram)
- _slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base);
- FLUSH_VERTICES(ctx, _NEW_TEXTURE);
}
}
@@ -1284,72 +1247,52 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
/**
* Called by ctx->Driver.UniformMatrix().
*/
-void
+static void
_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
GLenum matrixType, GLint location, GLsizei count,
GLboolean transpose, const GLfloat *values)
{
- GLsizei maxCount, i;
struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+
if (!shProg || !shProg->LinkStatus) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glUniformMatrix(program not linked)");
return;
}
+
if (location == -1)
return; /* The standard specifies this as a no-op */
- /* The spec says this is GL_INVALID_OPERATION, although it seems like it
- * ought to be GL_INVALID_VALUE
- */
- if (location < 0 || location >= (GLint) shProg->Uniforms->NumParameters) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)");
+
+ if (location < 0 || location >= shProg->Uniforms->NumUniforms) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
return;
}
if (values == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
return;
}
- if (count < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(count < 0)");
- return;
- }
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
- /*
- * Note: the _columns_ of a matrix are stored in program registers, not
- * the rows.
- */
- /* XXXX need to test 3x3 and 2x2 matrices... */
- maxCount = shProg->Uniforms->Parameters[location].Size / (4 * cols);
- if (count > maxCount)
- count = maxCount;
- for (i = 0; i < count; i++) {
- if (transpose) {
- GLuint row, col;
- for (col = 0; col < cols; col++) {
- GLfloat *v = shProg->Uniforms->ParameterValues[location + col];
- for (row = 0; row < rows; row++) {
- v[row] = values[row * cols + col];
- }
- }
+ if (shProg->VertexProgram) {
+ GLint loc = shProg->Uniforms->Uniforms[location].VertPos;
+ if (loc >= 0) {
+ set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
+ loc, rows, cols, transpose, values);
}
- else {
- GLuint row, col;
- for (col = 0; col < cols; col++) {
- GLfloat *v = shProg->Uniforms->ParameterValues[location + col];
- for (row = 0; row < rows; row++) {
- v[row] = values[col * rows + row];
- }
- }
+ }
+
+ if (shProg->FragmentProgram) {
+ GLint loc = shProg->Uniforms->Uniforms[location].FragPos;
+ if (loc >= 0) {
+ set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
+ loc, rows, cols, transpose, values);
}
- location += cols;
- values += rows * cols;
}
}
-void
+static void
_mesa_validate_program(GLcontext *ctx, GLuint program)
{
struct gl_shader_program *shProg;
@@ -1375,3 +1318,40 @@ _mesa_validate_program(GLcontext *ctx, GLuint program)
image units allowed.
*/
}
+
+
+/**
+ * Plug in Mesa's GLSL functions into the device driver function table.
+ */
+void
+_mesa_init_glsl_driver_functions(struct dd_function_table *driver)
+{
+ driver->AttachShader = _mesa_attach_shader;
+ driver->BindAttribLocation = _mesa_bind_attrib_location;
+ driver->CompileShader = _mesa_compile_shader;
+ driver->CreateProgram = _mesa_create_program;
+ driver->CreateShader = _mesa_create_shader;
+ driver->DeleteProgram2 = _mesa_delete_program2;
+ driver->DeleteShader = _mesa_delete_shader;
+ driver->DetachShader = _mesa_detach_shader;
+ driver->GetActiveAttrib = _mesa_get_active_attrib;
+ driver->GetActiveUniform = _mesa_get_active_uniform;
+ driver->GetAttachedShaders = _mesa_get_attached_shaders;
+ driver->GetAttribLocation = _mesa_get_attrib_location;
+ driver->GetHandle = _mesa_get_handle;
+ driver->GetProgramiv = _mesa_get_programiv;
+ driver->GetProgramInfoLog = _mesa_get_program_info_log;
+ driver->GetShaderiv = _mesa_get_shaderiv;
+ driver->GetShaderInfoLog = _mesa_get_shader_info_log;
+ driver->GetShaderSource = _mesa_get_shader_source;
+ driver->GetUniformfv = _mesa_get_uniformfv;
+ driver->GetUniformLocation = _mesa_get_uniform_location;
+ driver->IsProgram = _mesa_is_program;
+ driver->IsShader = _mesa_is_shader;
+ driver->LinkProgram = _mesa_link_program;
+ driver->ShaderSource = _mesa_shader_source;
+ driver->Uniform = _mesa_uniform;
+ driver->UniformMatrix = _mesa_uniform_matrix;
+ driver->UseProgram = _mesa_use_program;
+ driver->ValidateProgram = _mesa_validate_program;
+}
diff --git a/src/mesa/shader/shader_api.h b/src/mesa/shader/shader_api.h
index 27e5870d705..5521c585b53 100644
--- a/src/mesa/shader/shader_api.h
+++ b/src/mesa/shader/shader_api.h
@@ -41,9 +41,10 @@ _mesa_init_shader_state(GLcontext * ctx);
extern void
_mesa_free_shader_state(GLcontext *ctx);
+/*
extern struct gl_shader_program *
_mesa_new_shader_program(GLcontext *ctx, GLuint name);
-
+*/
extern void
_mesa_clear_shader_program_data(GLcontext *ctx,
struct gl_shader_program *shProg);
@@ -78,108 +79,12 @@ extern struct gl_shader *
_mesa_lookup_shader(GLcontext *ctx, GLuint name);
-/**
- * API/Driver functions
- */
-
-extern void
-_mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader);
-
-extern void
-_mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
- const GLchar *name);
-
-extern void
-_mesa_compile_shader(GLcontext *ctx, GLuint shaderObj);
-
-extern GLuint
-_mesa_create_shader(GLcontext *ctx, GLenum type);
-
-extern GLuint
-_mesa_create_program(GLcontext *ctx);
-
-extern void
-_mesa_delete_program2(GLcontext *ctx, GLuint name);
-
-extern void
-_mesa_delete_shader(GLcontext *ctx, GLuint shader);
-
-extern void
-_mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader);
-
-extern void
-_mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
- GLsizei maxLength, GLsizei *length, GLint *size,
- GLenum *type, GLchar *name);
-
-extern void
-_mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
- GLsizei maxLength, GLsizei *length, GLint *size,
- GLenum *type, GLchar *name);
-
-extern void
-_mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
- GLsizei *count, GLuint *obj);
-
-extern GLint
-_mesa_get_attrib_location(GLcontext *ctx, GLuint program,
- const GLchar *name);
-
-extern GLuint
-_mesa_get_handle(GLcontext *ctx, GLenum pname);
-
-extern void
-_mesa_get_programiv(GLcontext *ctx, GLuint program,
- GLenum pname, GLint *params);
-
-extern void
-_mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
- GLsizei *length, GLchar *infoLog);
-
-extern void
-_mesa_get_shaderiv(GLcontext *ctx, GLuint shader, GLenum pname, GLint *params);
-
-extern void
-_mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
- GLsizei *length, GLchar *infoLog);
-
-extern void
-_mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
- GLsizei *length, GLchar *sourceOut);
-
-extern void
-_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
- GLfloat *params);
-
-extern GLint
-_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name);
-
-extern GLboolean
-_mesa_is_program(GLcontext *ctx, GLuint name);
-
-extern GLboolean
-_mesa_is_shader(GLcontext *ctx, GLuint name);
-
-extern void
-_mesa_link_program(GLcontext *ctx, GLuint program);
-
-extern void
-_mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source);
-
-extern void
-_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
- const GLvoid *values, GLenum type);
-
-void
-_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
- GLenum matrixType, GLint location, GLsizei count,
- GLboolean transpose, const GLfloat *values);
-
extern void
_mesa_use_program(GLcontext *ctx, GLuint program);
+
extern void
-_mesa_validate_program(GLcontext *ctx, GLuint program);
+_mesa_init_glsl_driver_functions(struct dd_function_table *driver);
#endif /* SHADER_API_H */
diff --git a/src/mesa/shader/slang/library/Makefile b/src/mesa/shader/slang/library/Makefile
index dc67b590886..0e03fac2ee1 100644
--- a/src/mesa/shader/slang/library/Makefile
+++ b/src/mesa/shader/slang/library/Makefile
@@ -17,7 +17,7 @@ LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
default: syntax builtin
clean:
- rm -f syn_to_c gc_to_bin *_syn.h *_gc.h
+ -rm -f syn_to_c gc_to_bin *_syn.h *_gc.h
syntax: slang_pp_directives_syn.h slang_pp_expression_syn.h slang_shader_syn.h slang_pp_version_syn.h
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index ebead3274e1..d19d5a0abb6 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -1090,7 +1090,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
slang_operation_copy(inlined, fun->body);
/*** XXX review this */
- assert(inlined->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE);
+ assert(inlined->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE);
inlined->type = SLANG_OPER_BLOCK_NEW_SCOPE;
#if 0
@@ -2836,14 +2836,13 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
const GLint texIndex = sampler_to_texture_index(var->type.specifier.type);
if (texIndex != -1) {
- /* Texture sampler:
+ /* This is a texture sampler variable...
* store->File = PROGRAM_SAMPLER
- * store->Index = sampler uniform location
+ * store->Index = sampler number (0..7, typically)
* store->Size = texture type index (1D, 2D, 3D, cube, etc)
*/
- GLint samplerUniform
- = _mesa_add_sampler(prog->Parameters, varName, datatype);
- store = _slang_new_ir_storage(PROGRAM_SAMPLER, samplerUniform, texIndex);
+ GLint sampNum = _mesa_add_sampler(prog->Parameters, varName, datatype);
+ store = _slang_new_ir_storage(PROGRAM_SAMPLER, sampNum, texIndex);
if (dbg) printf("SAMPLER ");
}
else if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c
index 2be89a5ce05..46b5c54bbeb 100644
--- a/src/mesa/shader/slang/slang_compile.c
+++ b/src/mesa/shader/slang/slang_compile.c
@@ -31,6 +31,8 @@
#include "main/imports.h"
#include "main/context.h"
#include "shader/program.h"
+#include "shader/programopt.h"
+#include "shader/prog_print.h"
#include "shader/prog_parameter.h"
#include "shader/grammar/grammar_mesa.h"
#include "slang_codegen.h"
@@ -2180,6 +2182,19 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader)
_slang_delete_mempool((slang_mempool *) ctx->Shader.MemPool);
ctx->Shader.MemPool = NULL;
+ if (shader->Type == GL_VERTEX_SHADER) {
+ /* remove any reads of varying (output) registers */
+#if 0
+ printf("Pre-remove output reads:\n");
+ _mesa_print_program(shader->Programs[0]);
+#endif
+ _mesa_remove_varying_reads(shader->Programs[0]);
+#if 0
+ printf("Post-remove output reads:\n");
+ _mesa_print_program(shader->Programs[0]);
+#endif
+ }
+
return success;
}
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 9c307c6275b..ff63e05dd20 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -79,7 +79,7 @@ new_subroutine(slang_emit_info *emitInfo, GLuint *id)
_mesa_realloc(emitInfo->Subroutines,
n * sizeof(struct gl_program),
(n + 1) * sizeof(struct gl_program));
- emitInfo->Subroutines[n] = _mesa_new_program(ctx, emitInfo->prog->Target, 0);
+ emitInfo->Subroutines[n] = ctx->Driver.NewProgram(ctx, emitInfo->prog->Target, 0);
emitInfo->Subroutines[n]->Parameters = emitInfo->prog->Parameters;
emitInfo->NumSubroutines++;
*id = n;
@@ -922,11 +922,15 @@ emit_tex(slang_emit_info *emitInfo, slang_ir_node *n)
assert(n->Children[0]->Store->Size >= TEXTURE_1D_INDEX);
assert(n->Children[0]->Store->Size <= TEXTURE_RECT_INDEX);
- inst->Sampler = n->Children[0]->Store->Index; /* i.e. uniform's index */
inst->TexSrcTarget = n->Children[0]->Store->Size;
+#if 0
inst->TexSrcUnit = 27; /* Dummy value; the TexSrcUnit will be computed at
* link time, using the sampler uniform's value.
*/
+ inst->Sampler = n->Children[0]->Store->Index; /* i.e. uniform's index */
+#else
+ inst->TexSrcUnit = n->Children[0]->Store->Index; /* i.e. uniform's index */
+#endif
return inst;
}
@@ -1793,7 +1797,7 @@ _slang_resolve_subroutines(slang_emit_info *emitInfo)
sub->NumInstructions);
/* delete subroutine code */
sub->Parameters = NULL; /* prevent double-free */
- _mesa_delete_program(ctx, sub);
+ _mesa_reference_program(ctx, &emitInfo->Subroutines[i], NULL);
}
/* free subroutine list */
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index c8457fc483d..80cd4b6df62 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -37,12 +37,17 @@
#include "shader/prog_parameter.h"
#include "shader/prog_print.h"
#include "shader/prog_statevars.h"
+#include "shader/prog_uniform.h"
#include "shader/shader_api.h"
#include "slang_link.h"
-
+/**
+ * Linking varying vars involves rearranging varying vars so that the
+ * vertex program's output varyings matches the order of the fragment
+ * program's input varyings.
+ */
static GLboolean
link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog)
{
@@ -132,145 +137,65 @@ link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog)
}
-static GLboolean
-is_uniform(GLuint file)
-{
- return (file == PROGRAM_ENV_PARAM ||
- file == PROGRAM_STATE_VAR ||
- file == PROGRAM_NAMED_PARAM ||
- file == PROGRAM_CONSTANT ||
- file == PROGRAM_SAMPLER ||
- file == PROGRAM_UNIFORM);
-}
-
-
-static GLboolean
-link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog)
+/**
+ * Build the shProg->Uniforms list.
+ * This is basically a list/index of all uniforms found in either/both of
+ * the vertex and fragment shaders.
+ */
+static void
+link_uniform_vars(struct gl_shader_program *shProg,
+ struct gl_program *prog,
+ GLuint *numSamplers)
{
- GLuint *map, i;
-
-#if 0
- printf("================ pre link uniforms ===============\n");
- _mesa_print_parameter_list(shProg->Uniforms);
-#endif
-
- map = (GLuint *) malloc(prog->Parameters->NumParameters * sizeof(GLuint));
- if (!map)
- return GL_FALSE;
+ GLuint samplerMap[MAX_SAMPLERS];
+ GLuint i;
- for (i = 0; i < prog->Parameters->NumParameters; /* incr below*/) {
- /* see if this uniform is in the linked uniform list */
+ for (i = 0; i < prog->Parameters->NumParameters; i++) {
const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
- const GLfloat *pVals = prog->Parameters->ParameterValues[i];
- GLint j;
- GLint size;
-
- /* sanity check */
- assert(is_uniform(p->Type));
-
- if (p->Name) {
- j = _mesa_lookup_parameter_index(shProg->Uniforms, -1, p->Name);
- }
- else {
- /*GLuint swizzle;*/
- ASSERT(p->Type == PROGRAM_CONSTANT);
- if (_mesa_lookup_parameter_constant(shProg->Uniforms, pVals,
- p->Size, &j, NULL)) {
- assert(j >= 0);
- }
- else {
- j = -1;
- }
- }
- if (j >= 0) {
- /* already in list, check size XXX check this */
-#if 0
- assert(p->Size == shProg->Uniforms->Parameters[j].Size);
-#endif
- }
- else {
- /* not already in linked list */
- switch (p->Type) {
- case PROGRAM_ENV_PARAM:
- j = _mesa_add_named_parameter(shProg->Uniforms, p->Name, pVals);
- break;
- case PROGRAM_CONSTANT:
- j = _mesa_add_named_constant(shProg->Uniforms, p->Name, pVals, p->Size);
- break;
- case PROGRAM_STATE_VAR:
- j = _mesa_add_state_reference(shProg->Uniforms, p->StateIndexes);
- break;
- case PROGRAM_UNIFORM:
- j = _mesa_add_uniform(shProg->Uniforms, p->Name, p->Size, p->DataType);
- break;
- case PROGRAM_SAMPLER:
- j = _mesa_add_sampler(shProg->Uniforms, p->Name, p->DataType);
- break;
- default:
- _mesa_problem(NULL, "bad parameter type in link_uniform_vars()");
- return GL_FALSE;
- }
+ /*
+ * XXX FIX NEEDED HERE
+ * We should also be adding a uniform if p->Type == PROGRAM_STATE_VAR.
+ * For example, modelview matrix, light pos, etc.
+ * Also, we need to update the state-var name-generator code to
+ * generate GLSL-style names, like "gl_LightSource[0].position".
+ * Furthermore, we'll need to fix the state-var's size/datatype info.
+ */
+
+ if (p->Type == PROGRAM_UNIFORM ||
+ p->Type == PROGRAM_SAMPLER) {
+ _mesa_append_uniform(shProg->Uniforms, p->Name, prog->Target, i);
}
- ASSERT(j >= 0);
-
- size = p->Size;
- while (size > 0) {
- map[i] = j;
- i++;
- j++;
- size -= 4;
+ if (p->Type == PROGRAM_SAMPLER) {
+ /* Allocate a new sampler index */
+ GLuint sampNum = *numSamplers;
+ GLuint oldSampNum = (GLuint) prog->Parameters->ParameterValues[i][0];
+ assert(oldSampNum < MAX_SAMPLERS);
+ samplerMap[oldSampNum] = sampNum;
+ (*numSamplers)++;
}
-
}
-#if 0
- printf("================ post link uniforms ===============\n");
- _mesa_print_parameter_list(shProg->Uniforms);
-#endif
-#if 0
- {
- GLuint i;
- for (i = 0; i < prog->Parameters->NumParameters; i++) {
- printf("map[%d] = %d\n", i, map[i]);
- }
- _mesa_print_parameter_list(shProg->Uniforms);
- }
-#endif
-
- /* OK, now scan the program/shader instructions looking for uniform vars,
+ /* OK, now scan the program/shader instructions looking for sampler vars,
* replacing the old index with the new index.
*/
+ prog->SamplersUsed = 0x0;
for (i = 0; i < prog->NumInstructions; i++) {
struct prog_instruction *inst = prog->Instructions + i;
- GLuint j;
-
- if (is_uniform(inst->DstReg.File)) {
- inst->DstReg.Index = map[ inst->DstReg.Index ];
- }
-
- for (j = 0; j < 3; j++) {
- if (is_uniform(inst->SrcReg[j].File)) {
- inst->SrcReg[j].Index = map[ inst->SrcReg[j].Index ];
- }
- }
-
- if (inst->Opcode == OPCODE_TEX ||
- inst->Opcode == OPCODE_TXB ||
- inst->Opcode == OPCODE_TXP) {
+ if (_mesa_is_tex_instruction(inst->Opcode)) {
/*
printf("====== remap sampler from %d to %d\n",
inst->Sampler, map[ inst->Sampler ]);
*/
- inst->Sampler = map[ inst->Sampler ];
+ /* here, texUnit is really samplerUnit */
+ inst->TexSrcUnit = samplerMap[inst->TexSrcUnit];
+ prog->SamplerTargets[inst->TexSrcUnit] = inst->TexSrcTarget;
+ prog->SamplersUsed |= (1 << inst->TexSrcUnit);
}
}
- free(map);
-
- return GL_TRUE;
}
@@ -329,10 +254,8 @@ _slang_resolve_attributes(struct gl_shader_program *shProg,
* glVertex/position.
*/
for (attr = 1; attr < MAX_VERTEX_ATTRIBS; attr++) {
- if (((1 << attr) & usedAttributes) == 0) {
- usedAttributes |= (1 << attr);
+ if (((1 << attr) & usedAttributes) == 0)
break;
- }
}
if (attr == MAX_VERTEX_ATTRIBS) {
/* too many! XXX record error log */
@@ -406,36 +329,6 @@ _slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib, GLuint newAttr
-/**
- * Scan program for texture instructions, lookup sampler/uniform's value
- * to determine which texture unit to use.
- * Also, update the program's TexturesUsed[] array.
- */
-void
-_slang_resolve_samplers(struct gl_shader_program *shProg,
- struct gl_program *prog)
-{
- GLuint i;
-
- for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
- prog->TexturesUsed[i] = 0;
-
- for (i = 0; i < prog->NumInstructions; i++) {
- struct prog_instruction *inst = prog->Instructions + i;
- if (inst->Opcode == OPCODE_TEX ||
- inst->Opcode == OPCODE_TXB ||
- inst->Opcode == OPCODE_TXP) {
- GLint sampleUnit = (GLint) shProg->Uniforms->ParameterValues[inst->Sampler][0];
- assert(sampleUnit < MAX_TEXTURE_IMAGE_UNITS);
- inst->TexSrcUnit = sampleUnit;
-
- prog->TexturesUsed[inst->TexSrcUnit] |= (1 << inst->TexSrcTarget);
- }
- }
-}
-
-
-
/** cast wrapper */
static struct gl_vertex_program *
vertex_program(struct gl_program *prog)
@@ -476,12 +369,9 @@ link_error(struct gl_shader_program *shProg, const char *msg)
* 2. Varying vars in the two shaders are combined so their locations
* agree between the vertex and fragment stages. They're treated as
* vertex program output attribs and as fragment program input attribs.
- * 3. Uniform vars (including state references, constants, etc) from the
- * vertex and fragment shaders are merged into one group. Recall that
- * GLSL uniforms are shared by all linked shaders.
- * 4. The vertex and fragment programs are cloned and modified to update
- * src/dst register references so they use the new, linked uniform/
- * varying storage locations.
+ * 3. The vertex and fragment programs are cloned and modified to update
+ * src/dst register references so they use the new, linked varying
+ * storage locations.
*/
void
_slang_link(GLcontext *ctx,
@@ -490,11 +380,12 @@ _slang_link(GLcontext *ctx,
{
const struct gl_vertex_program *vertProg;
const struct gl_fragment_program *fragProg;
+ GLuint numSamplers = 0;
GLuint i;
_mesa_clear_shader_program_data(ctx, shProg);
- shProg->Uniforms = _mesa_new_parameter_list();
+ shProg->Uniforms = _mesa_new_uniform_list();
shProg->Varying = _mesa_new_parameter_list();
/**
@@ -515,48 +406,35 @@ _slang_link(GLcontext *ctx,
* Make copies of the vertex/fragment programs now since we'll be
* changing src/dst registers after merging the uniforms and varying vars.
*/
+ _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
if (vertProg) {
- shProg->VertexProgram
- = vertex_program(_mesa_clone_program(ctx, &vertProg->Base));
- }
- else {
- shProg->VertexProgram = NULL;
+ struct gl_vertex_program *linked_vprog =
+ vertex_program(_mesa_clone_program(ctx, &vertProg->Base));
+ shProg->VertexProgram = linked_vprog; /* refcount OK */
+ ASSERT(shProg->VertexProgram->Base.RefCount == 1);
}
+ _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
if (fragProg) {
- shProg->FragmentProgram
- = fragment_program(_mesa_clone_program(ctx, &fragProg->Base));
- }
- else {
- shProg->FragmentProgram = NULL;
+ struct gl_fragment_program *linked_fprog =
+ fragment_program(_mesa_clone_program(ctx, &fragProg->Base));
+ shProg->FragmentProgram = linked_fprog; /* refcount OK */
+ ASSERT(shProg->FragmentProgram->Base.RefCount == 1);
}
+ /* link varying vars */
if (shProg->VertexProgram)
link_varying_vars(shProg, &shProg->VertexProgram->Base);
if (shProg->FragmentProgram)
link_varying_vars(shProg, &shProg->FragmentProgram->Base);
+ /* link uniform vars */
if (shProg->VertexProgram)
- link_uniform_vars(shProg, &shProg->VertexProgram->Base);
+ link_uniform_vars(shProg, &shProg->VertexProgram->Base, &numSamplers);
if (shProg->FragmentProgram)
- link_uniform_vars(shProg, &shProg->FragmentProgram->Base);
-
- /* The vertex and fragment programs share a common set of uniforms now */
- if (shProg->VertexProgram) {
- _mesa_free_parameter_list(shProg->VertexProgram->Base.Parameters);
- shProg->VertexProgram->Base.Parameters = shProg->Uniforms;
- }
- if (shProg->FragmentProgram) {
- _mesa_free_parameter_list(shProg->FragmentProgram->Base.Parameters);
- shProg->FragmentProgram->Base.Parameters = shProg->Uniforms;
- }
+ link_uniform_vars(shProg, &shProg->FragmentProgram->Base, &numSamplers);
- if (shProg->VertexProgram) {
- _slang_resolve_samplers(shProg, &shProg->VertexProgram->Base);
- }
- if (shProg->FragmentProgram) {
- _slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base);
- }
+ /*_mesa_print_uniforms(shProg->Uniforms);*/
if (shProg->VertexProgram) {
if (!_slang_resolve_attributes(shProg, &shProg->VertexProgram->Base)) {
diff --git a/src/mesa/shader/slang/slang_link.h b/src/mesa/shader/slang/slang_link.h
index 606b9e46b16..8ef8a6b4b3e 100644
--- a/src/mesa/shader/slang/slang_link.h
+++ b/src/mesa/shader/slang/slang_link.h
@@ -33,10 +33,6 @@ _slang_link(GLcontext *ctx, GLhandleARB h,
struct gl_shader_program *shProg);
extern void
-_slang_resolve_samplers(struct gl_shader_program *shProg,
- struct gl_program *prog);
-
-extern void
_slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib,
GLuint newAttrib);
diff --git a/src/mesa/sources b/src/mesa/sources
index dbfc01d0edf..054f667a254 100644
--- a/src/mesa/sources
+++ b/src/mesa/sources
@@ -165,6 +165,7 @@ SHADER_SOURCES = \
shader/prog_parameter.c \
shader/prog_print.c \
shader/prog_statevars.c \
+ shader/prog_uniform.c \
shader/programopt.c \
shader/shader_api.c \
diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c
index 81f5caa2706..730798c9084 100644
--- a/src/mesa/swrast/s_drawpix.c
+++ b/src/mesa/swrast/s_drawpix.c
@@ -840,8 +840,10 @@ _swrast_DrawPixels( GLcontext *ctx,
_swrast_validate_derived( ctx );
pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels);
- if (!pixels)
+ if (!pixels) {
+ RENDER_FINISH(swrast,ctx);
return;
+ }
switch (format) {
case GL_STENCIL_INDEX:
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index 2dfc033d501..ecace9c5025 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -33,18 +33,19 @@
/**
- * Fetch a texel.
+ * Fetch a texel with given lod.
+ * Called via machine->FetchTexelLod()
*/
static void
-fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda,
- GLuint unit, GLfloat color[4] )
+fetch_texel_lod( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda,
+ GLuint unit, GLfloat color[4] )
{
GLchan rgba[4];
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
lambda = CLAMP(lambda, texObj->MinLod, texObj->MaxLod);
-
+
/* XXX use a float-valued TextureSample routine here!!! */
swrast->TextureSample[unit](ctx, texObj, 1, (const GLfloat (*)[4]) texcoord,
&lambda, &rgba);
@@ -58,6 +59,7 @@ fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda,
/**
* Fetch a texel with the given partial derivatives to compute a level
* of detail in the mipmap.
+ * Called via machine->FetchTexelDeriv()
*/
static void
fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4],
@@ -117,6 +119,8 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine,
machine->DerivY = (GLfloat (*)[4]) span->attrStepY;
machine->NumDeriv = FRAG_ATTRIB_MAX;
+ machine->Samplers = program->Base.SamplerUnits;
+
/* if running a GLSL program (not ARB_fragment_program) */
if (ctx->Shader.CurrentProgram) {
/* Store front/back facing value in register FOGC.Y */
@@ -134,7 +138,7 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine,
/* init call stack */
machine->StackDepth = 0;
- machine->FetchTexelLod = fetch_texel;
+ machine->FetchTexelLod = fetch_texel_lod;
machine->FetchTexelDeriv = fetch_texel_deriv;
}
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
index 656a90a99a9..4c58f8de876 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -1401,7 +1401,6 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
* Write to renderbuffers
*/
{
- const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
const GLuint numBuffers = fb->_NumColorDrawBuffers;
const GLboolean multiFragOutputs = numBuffers > 1;
GLuint buf;
diff --git a/src/mesa/swrast/s_texstore.c b/src/mesa/swrast/s_texstore.c
index 3f49b40d9c1..547d5b9ea0d 100644
--- a/src/mesa/swrast/s_texstore.c
+++ b/src/mesa/swrast/s_texstore.c
@@ -305,7 +305,7 @@ _swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, target, texUnit, texObj);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
}
@@ -381,7 +381,7 @@ _swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, target, texUnit, texObj);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
}
@@ -450,7 +450,7 @@ _swrast_copy_texsubimage1d( GLcontext *ctx, GLenum target, GLint level,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, target, texUnit, texObj);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
}
@@ -526,7 +526,7 @@ _swrast_copy_texsubimage2d( GLcontext *ctx,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, target, texUnit, texObj);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
}
@@ -599,6 +599,6 @@ _swrast_copy_texsubimage3d( GLcontext *ctx,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, target, texUnit, texObj);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
}
diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h
index baf283ef0f6..1ac508f0330 100644
--- a/src/mesa/tnl/t_context.h
+++ b/src/mesa/tnl/t_context.h
@@ -388,7 +388,7 @@ struct tnl_clipspace
struct tnl_cache_item {
GLuint hash;
void *key;
- void *data;
+ struct gl_vertex_program *prog;
struct tnl_cache_item *next;
};
diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c
index a7fd815a260..46446d48859 100644
--- a/src/mesa/tnl/t_vp_build.c
+++ b/src/mesa/tnl/t_vp_build.c
@@ -1464,21 +1464,22 @@ create_new_program( const struct state_key *key,
build_tnl_program( &p );
}
-static void *search_cache( struct tnl_cache *cache,
- GLuint hash,
- const void *key,
- GLuint keysize)
+
+static struct gl_vertex_program *
+search_cache(struct tnl_cache *cache, GLuint hash,
+ const void *key, GLuint keysize)
{
struct tnl_cache_item *c;
for (c = cache->items[hash % cache->size]; c; c = c->next) {
if (c->hash == hash && _mesa_memcmp(c->key, key, keysize) == 0)
- return c->data;
+ return c->prog;
}
return NULL;
}
+
static void rehash( struct tnl_cache *cache )
{
struct tnl_cache_item **items;
@@ -1501,15 +1502,16 @@ static void rehash( struct tnl_cache *cache )
cache->size = size;
}
-static void cache_item( struct tnl_cache *cache,
+static void cache_item( GLcontext *ctx,
+ struct tnl_cache *cache,
GLuint hash,
void *key,
- void *data )
+ struct gl_vertex_program *prog )
{
- struct tnl_cache_item *c = (struct tnl_cache_item*) _mesa_malloc(sizeof(*c));
+ struct tnl_cache_item *c = CALLOC_STRUCT(tnl_cache_item);
c->hash = hash;
c->key = key;
- c->data = data;
+ _mesa_reference_vertprog(ctx, &c->prog, prog);
if (++cache->n_items > cache->size * 1.5)
rehash(cache);
@@ -1540,6 +1542,8 @@ void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx )
if (!ctx->VertexProgram._Current ||
ctx->VertexProgram._Current == ctx->VertexProgram._TnlProgram) {
+ struct gl_vertex_program *newProg;
+
/* Grab all the relevent state and put it in a single structure:
*/
key = make_state_key(ctx);
@@ -1547,33 +1551,34 @@ void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx )
/* Look for an already-prepared program for this state:
*/
- ctx->VertexProgram._TnlProgram = (struct gl_vertex_program *)
- search_cache( tnl->vp_cache, hash, key, sizeof(*key) );
+ newProg = search_cache( tnl->vp_cache, hash, key, sizeof(*key));
/* OK, we'll have to build a new one:
*/
- if (!ctx->VertexProgram._TnlProgram) {
+ if (!newProg) {
+
if (0)
_mesa_printf("Build new TNL program\n");
- ctx->VertexProgram._TnlProgram = (struct gl_vertex_program *)
+ newProg = (struct gl_vertex_program *)
ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
- create_new_program( key, ctx->VertexProgram._TnlProgram,
- ctx->Const.VertexProgram.MaxTemps );
+ create_new_program( key, newProg, ctx->Const.VertexProgram.MaxTemps );
if (ctx->Driver.ProgramStringNotify)
ctx->Driver.ProgramStringNotify( ctx, GL_VERTEX_PROGRAM_ARB,
- &ctx->VertexProgram._TnlProgram->Base );
+ &newProg->Base );
+
+ cache_item(ctx, tnl->vp_cache, hash, key, newProg);
- cache_item(tnl->vp_cache, hash, key, ctx->VertexProgram._TnlProgram );
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, newProg);
}
else {
FREE(key);
- if (0)
- _mesa_printf("Found existing TNL program for key %x\n", hash);
}
- ctx->VertexProgram._Current = ctx->VertexProgram._TnlProgram;
+
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, newProg);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, newProg);
}
/* Tell the driver about the change. Could define a new target for
@@ -1606,7 +1611,7 @@ void _tnl_ProgramCacheDestroy( GLcontext *ctx )
for (c = tnl->vp_cache->items[i]; c; c = next) {
next = c->next;
FREE(c->key);
- FREE(c->data);
+ _mesa_reference_vertprog(ctx, &c->prog, NULL);
FREE(c);
}
diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c
index 0ef26cdfe36..68ce7ba837d 100644
--- a/src/mesa/vbo/vbo_exec_draw.c
+++ b/src/mesa/vbo/vbo_exec_draw.c
@@ -187,7 +187,7 @@ static void vbo_exec_bind_arrays( GLcontext *ctx )
arrays[attr].BufferObj = exec->vtx.bufferobj; /* NullBufferObj */
arrays[attr]._MaxElement = count; /* ??? */
- data += exec->vtx.attrsz[attr] * sizeof(GLfloat);
+ data += exec->vtx.attrsz[src] * sizeof(GLfloat);
}
}
}
diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
index ee6df226054..bf5c6d4eefe 100644
--- a/src/mesa/vbo/vbo_save_draw.c
+++ b/src/mesa/vbo/vbo_save_draw.c
@@ -146,7 +146,7 @@ static void vbo_bind_vertex_list( GLcontext *ctx,
assert(arrays[attr].BufferObj->Name);
- data += node->attrsz[attr] * sizeof(GLfloat);
+ data += node->attrsz[src] * sizeof(GLfloat);
}
}
}
diff --git a/src/mesa/x86-64/Makefile b/src/mesa/x86-64/Makefile
index 252218ca86b..c6b69bafe86 100644
--- a/src/mesa/x86-64/Makefile
+++ b/src/mesa/x86-64/Makefile
@@ -19,7 +19,7 @@ INCLUDE_DIRS = \
default: matypes.h
clean:
- rm -f matypes.h
+ -rm -f matypes.h
# need some special rules here, unfortunately
diff --git a/src/mesa/x86/Makefile b/src/mesa/x86/Makefile
index 3c6a6b11c06..dc8c7f355eb 100644
--- a/src/mesa/x86/Makefile
+++ b/src/mesa/x86/Makefile
@@ -17,7 +17,7 @@ INCLUDE_DIRS = \
default: gen_matypes matypes.h
clean:
- rm -f matypes.h gen_matypes
+ -rm -f matypes.h gen_matypes
gen_matypes: gen_matypes.c
diff --git a/src/mesa/x86/read_rgba_span_x86.S b/src/mesa/x86/read_rgba_span_x86.S
index 2e5c3be83fe..80144b889c7 100644
--- a/src/mesa/x86/read_rgba_span_x86.S
+++ b/src/mesa/x86/read_rgba_span_x86.S
@@ -434,7 +434,8 @@ _generic_read_RGBA_span_BGRA8888_REV_SSE2:
je .L47
movq (%ebx), %xmm0
-
+ addl $8, %ebx
+
movdqa %xmm0, %xmm3
movdqa %xmm0, %xmm4
andps %xmm1, %xmm0
@@ -448,6 +449,7 @@ _generic_read_RGBA_span_BGRA8888_REV_SSE2:
orps %xmm3, %xmm0
movq %xmm0, (%ecx)
+ addl $8, %ecx
.L47:
testl $1, %edx