From df43fb661b2030d9b833a42dd47b8d7bf58d73aa Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 6 May 2008 23:08:51 -0600 Subject: implement full reference counting for vertex/fragment programs Use _mesa_reference_vert/fragprog() wherever we assign program pointers. Fixes a memory corruption bug found with glean/api2 test. --- src/mesa/shader/program.c | 102 ++++++++++++++++++++++++------------- src/mesa/shader/program.h | 22 ++++++++ src/mesa/shader/shader_api.c | 8 +-- src/mesa/shader/slang/slang_link.c | 14 ++--- 4 files changed, 102 insertions(+), 44 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index c539b52720..8166e7e935 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,7 +70,8 @@ _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 @@ -92,18 +93,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 @@ -365,6 +358,59 @@ _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 %u 0x%x Refcount-- to %d\n", + *ptr, (*ptr)->Id, (*ptr)->Target, (*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 %u 0x%x Refcount++ to %d\n", + prog, prog->Id, prog->Target, 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 @@ -380,8 +426,9 @@ _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) { @@ -513,9 +560,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 +590,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 +657,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 ea2c8c3050..9a6883e6a5 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -86,6 +86,28 @@ _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); diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index b0f79c29c1..c319cef10a 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -79,8 +79,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx, /* to prevent a double-free in the next call */ shProg->VertexProgram->Base.Parameters = NULL; } - ctx->Driver.DeleteProgram(ctx, &shProg->VertexProgram->Base); - shProg->VertexProgram = NULL; + _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); } if (shProg->FragmentProgram) { @@ -88,8 +87,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx, /* 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_fragprog(ctx, &shProg->FragmentProgram, NULL); } if (shProg->Uniforms) { @@ -1100,6 +1098,8 @@ _mesa_link_program(GLcontext *ctx, GLuint program) return; } + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + _slang_link(ctx, program, shProg); } diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index c8457fc483..72fe9997c5 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -516,19 +516,19 @@ _slang_link(GLcontext *ctx, * changing src/dst registers after merging the uniforms and varying vars. */ if (vertProg) { - shProg->VertexProgram - = vertex_program(_mesa_clone_program(ctx, &vertProg->Base)); + _mesa_reference_vertprog(ctx, &shProg->VertexProgram, + vertex_program(_mesa_clone_program(ctx, &vertProg->Base))); } else { - shProg->VertexProgram = NULL; + _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); } if (fragProg) { - shProg->FragmentProgram - = fragment_program(_mesa_clone_program(ctx, &fragProg->Base)); + _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, + fragment_program(_mesa_clone_program(ctx, &fragProg->Base))); } else { - shProg->FragmentProgram = NULL; + _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); } if (shProg->VertexProgram) @@ -545,10 +545,12 @@ _slang_link(GLcontext *ctx, if (shProg->VertexProgram) { _mesa_free_parameter_list(shProg->VertexProgram->Base.Parameters); shProg->VertexProgram->Base.Parameters = shProg->Uniforms; + assert(shProg->Uniforms); } if (shProg->FragmentProgram) { _mesa_free_parameter_list(shProg->FragmentProgram->Base.Parameters); shProg->FragmentProgram->Base.Parameters = shProg->Uniforms; + assert(shProg->Uniforms); } if (shProg->VertexProgram) { -- cgit v1.2.3 From a6464b3cb08b86d5fc537a4907849546a63ae4da Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Wed, 7 May 2008 11:35:23 -0700 Subject: Never fail `make clean' Mostly some pedantic changes such that `make clean' always ignores errors. Also changed the top clean target to do the `touch configs/current' dance instead of realclean. --- Makefile | 8 ++++---- doxygen/Makefile | 4 ++-- progs/Makefile | 2 +- progs/beos/Makefile | 4 ++-- progs/egl/Makefile | 6 +++--- progs/fbdev/Makefile | 4 ++-- progs/fp/Makefile | 6 +++--- progs/miniglx/Makefile | 4 ++-- progs/slang/Makefile | 2 +- progs/tests/Makefile | 6 +++--- progs/trivial/Makefile | 6 +++--- progs/vp/Makefile | 6 +++--- src/Makefile | 2 +- src/egl/Makefile | 2 +- src/egl/drivers/demo/Makefile | 4 ++-- src/egl/drivers/dri/Makefile | 4 ++-- src/egl/main/Makefile | 4 ++-- src/glu/Makefile | 2 +- src/glx/Makefile | 2 +- src/mesa/Makefile | 8 ++++---- src/mesa/drivers/directfb/Makefile | 2 +- src/mesa/drivers/dri/Makefile | 2 +- src/mesa/drivers/dri/common/xmlpool/Makefile | 4 ++-- src/mesa/drivers/glslcompiler/Makefile | 2 +- src/mesa/glapi/Makefile | 4 ++-- src/mesa/shader/slang/library/Makefile | 2 +- src/mesa/x86-64/Makefile | 2 +- src/mesa/x86/Makefile | 2 +- 28 files changed, 53 insertions(+), 53 deletions(-) (limited to 'src/mesa/shader') diff --git a/Makefile b/Makefile index df0a0e91e3..96d3885849 100644 --- a/Makefile +++ b/Makefile @@ -17,16 +17,16 @@ doxygen: cd doxygen && $(MAKE) clean: - @for dir in $(SUBDIRS) ; do \ + -@touch $(TOP)/configs/current + -@for dir in $(SUBDIRS) ; do \ if [ -d $$dir ] ; then \ (cd $$dir && $(MAKE) clean) ; \ fi \ done + -@test -s $(TOP)/configs/current || rm -f $(TOP)/configs/current -realclean: - touch $(TOP)/configs/current - $(MAKE) clean +realclean: clean -rm -rf lib* -rm -f $(TOP)/configs/current -rm -f $(TOP)/configs/autoconf diff --git a/doxygen/Makefile b/doxygen/Makefile index d8dd555b05..15ade4043b 100644 --- a/doxygen/Makefile +++ b/doxygen/Makefile @@ -29,5 +29,5 @@ subset: $(SUBSET:.doxy=.tag) $(foreach FILE,$(SUBSET),doxygen $(FILE);) clean: - rm -rf $(FULL:.doxy=) $(SUBSET:.doxy=) - rm -rf *.tag + -rm -rf $(FULL:.doxy=) $(SUBSET:.doxy=) + -rm -rf *.tag diff --git a/progs/Makefile b/progs/Makefile index 5e705efa7e..c99f4eebcc 100644 --- a/progs/Makefile +++ b/progs/Makefile @@ -25,7 +25,7 @@ subdirs: install: clean: - @for dir in $(SUBDIRS) tests ; do \ + -@for dir in $(SUBDIRS) tests ; do \ if [ -d $$dir ] ; then \ (cd $$dir && $(MAKE) clean) ; \ fi \ diff --git a/progs/beos/Makefile b/progs/beos/Makefile index 491e8e442d..0dc4cdce63 100644 --- a/progs/beos/Makefile +++ b/progs/beos/Makefile @@ -19,8 +19,8 @@ INCLUDES = -I. -I- -I../../include default: demo sample GLInfo clean: - rm -f demo sample GLInfo - rm -f *.o + -rm -f demo sample GLInfo + -rm -f *.o demo: demo.o $(LD) demo.o $(LDFLAGS) $(LIBS) -o $@ diff --git a/progs/egl/Makefile b/progs/egl/Makefile index 07215604d3..416d2c04b2 100644 --- a/progs/egl/Makefile +++ b/progs/egl/Makefile @@ -60,6 +60,6 @@ eglgears.o: eglgears.c $(HEADERS) clean: - rm -f *.o *~ - rm -f *.so - rm -f $(PROGRAMS) + -rm -f *.o *~ + -rm -f *.so + -rm -f $(PROGRAMS) diff --git a/progs/fbdev/Makefile b/progs/fbdev/Makefile index 56daf56f8a..39401243e5 100644 --- a/progs/fbdev/Makefile +++ b/progs/fbdev/Makefile @@ -37,8 +37,8 @@ LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS) default: depend $(PROGS) clean: - rm -f $(PROGS) - rm -f *.o + -rm -f $(PROGS) + -rm -f *.o depend: $(SOURCES) diff --git a/progs/fp/Makefile b/progs/fp/Makefile index a395b734ef..09f22d1a7b 100644 --- a/progs/fp/Makefile +++ b/progs/fp/Makefile @@ -86,9 +86,9 @@ UTIL_FILES = readtex.h readtex.c default: $(UTIL_FILES) $(PROGS) clean: - rm -f $(PROGS) - rm -f *.o - rm -f getproclist.h + -rm -f $(PROGS) + -rm -f *.o + -rm -f getproclist.h # auto code generation diff --git a/progs/miniglx/Makefile b/progs/miniglx/Makefile index 5d0c8eae64..d5258b0a96 100644 --- a/progs/miniglx/Makefile +++ b/progs/miniglx/Makefile @@ -43,8 +43,8 @@ LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS default: depend $(PROGS) clean: - rm -f $(PROGS) - rm -f *.o + -rm -f $(PROGS) + -rm -f *.o depend: $(SOURCES) diff --git a/progs/slang/Makefile b/progs/slang/Makefile index ea1e9b6afd..c93caeab61 100644 --- a/progs/slang/Makefile +++ b/progs/slang/Makefile @@ -24,7 +24,7 @@ tests: default ! ./cltest 2> /dev/null | (grep -e ^[*][*][*]) clean: - rm -f cltest.o sotest.o vstest.o framework.o cltest sotest vstest + -rm -f cltest.o sotest.o vstest.o framework.o cltest sotest vstest # # executables diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 116a19b1f5..cf8e0bfc1e 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -99,9 +99,9 @@ UTIL_FILES = readtex.h readtex.c default: $(UTIL_FILES) $(PROGS) clean: - rm -f $(PROGS) - rm -f *.o - rm -f getproclist.h + -rm -f $(PROGS) + -rm -f *.o + -rm -f getproclist.h ##### RULES ##### diff --git a/progs/trivial/Makefile b/progs/trivial/Makefile index 7610a5df08..6fa51ce2cf 100644 --- a/progs/trivial/Makefile +++ b/progs/trivial/Makefile @@ -102,9 +102,9 @@ UTIL_FILES = readtex.h readtex.c default: $(UTIL_FILES) $(PROGS) clean: - rm -f $(PROGS) - rm -f *.o - rm -f getproclist.h + -rm -f $(PROGS) + -rm -f *.o + -rm -f getproclist.h # auto code generation diff --git a/progs/vp/Makefile b/progs/vp/Makefile index 3349fd5342..28d63237a4 100644 --- a/progs/vp/Makefile +++ b/progs/vp/Makefile @@ -40,9 +40,9 @@ INCLUDES = -I. -I$(TOP)/include -I../samples default: $(PROGS) clean: - rm -f $(PROGS) - rm -f *.o - rm -f getproclist.h + -rm -f $(PROGS) + -rm -f *.o + -rm -f getproclist.h diff --git a/src/Makefile b/src/Makefile index f93987e688..229beeaffa 100644 --- a/src/Makefile +++ b/src/Makefile @@ -33,7 +33,7 @@ $(TOP)/$(LIB_DIR): clean: - @for dir in $(SUBDIRS) ; do \ + -@for dir in $(SUBDIRS) ; do \ if [ -d $$dir ] ; then \ (cd $$dir && $(MAKE) clean) ; \ fi \ diff --git a/src/egl/Makefile b/src/egl/Makefile index 036bf1f01a..fb4db8f9b9 100644 --- a/src/egl/Makefile +++ b/src/egl/Makefile @@ -17,7 +17,7 @@ subdirs: clean: - @for dir in $(SUBDIRS) ; do \ + -@for dir in $(SUBDIRS) ; do \ if [ -d $$dir ] ; then \ (cd $$dir && $(MAKE) clean) ; \ fi \ diff --git a/src/egl/drivers/demo/Makefile b/src/egl/drivers/demo/Makefile index ad2ef38a72..9653c8805c 100644 --- a/src/egl/drivers/demo/Makefile +++ b/src/egl/drivers/demo/Makefile @@ -27,5 +27,5 @@ $(TOP)/$(LIB_DIR)/demodriver.so: $(OBJECTS) clean: - rm -f *.o - rm -f *.so + -rm -f *.o + -rm -f *.so diff --git a/src/egl/drivers/dri/Makefile b/src/egl/drivers/dri/Makefile index 0214cf65a2..52d46cac56 100644 --- a/src/egl/drivers/dri/Makefile +++ b/src/egl/drivers/dri/Makefile @@ -47,8 +47,8 @@ $(TOP)/$(LIB_DIR)/libEGLdri.so: $(OBJECTS) clean: - rm -f *.o - rm -f *.so + -rm -f *.o + -rm -f *.so depend: $(SOURCES) $(HEADERS) @ echo "running $(MKDEP)" diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile index 2a7046fb14..52e16a76e3 100644 --- a/src/egl/main/Makefile +++ b/src/egl/main/Makefile @@ -52,8 +52,8 @@ $(TOP)/$(LIB_DIR)/libEGL.so: $(OBJECTS) clean: - rm -f *.o *.so* - rm -f core.* + -rm -f *.o *.so* + -rm -f core.* depend: $(SOURCES) $(HEADERS) diff --git a/src/glu/Makefile b/src/glu/Makefile index 3ee5cfddd7..23161b5015 100644 --- a/src/glu/Makefile +++ b/src/glu/Makefile @@ -28,6 +28,6 @@ install: glu.pc $(INSTALL) -m 644 glu.pc $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig clean: - @for dir in $(SUBDIRS) ; do \ + -@for dir in $(SUBDIRS) ; do \ (cd $$dir && $(MAKE) clean) ; \ done diff --git a/src/glx/Makefile b/src/glx/Makefile index a96e0dadaa..e0ab4a0240 100644 --- a/src/glx/Makefile +++ b/src/glx/Makefile @@ -8,5 +8,5 @@ default: clean: - cd mini && $(MAKE) clean + -@cd mini && $(MAKE) clean diff --git a/src/mesa/Makefile b/src/mesa/Makefile index d179636c6a..08d723553e 100644 --- a/src/mesa/Makefile +++ b/src/mesa/Makefile @@ -207,10 +207,10 @@ clean: -rm -f */*/*.o -rm -f depend depend.bak libmesa.a -rm -f drivers/*/*.o - (cd drivers/dri && $(MAKE) clean) - (cd drivers/xorg && $(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/directfb/Makefile b/src/mesa/drivers/directfb/Makefile index c515785b2a..dc71b385ca 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 69a8c55394..c6464a2a24 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/xmlpool/Makefile b/src/mesa/drivers/dri/common/xmlpool/Makefile index b077809cd1..62ec919ea6 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/glslcompiler/Makefile b/src/mesa/drivers/glslcompiler/Makefile index 858457ddd4..dc4abd44d4 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/glapi/Makefile b/src/mesa/glapi/Makefile index 6520f75e13..13f5302b16 100644 --- a/src/mesa/glapi/Makefile +++ b/src/mesa/glapi/Makefile @@ -113,5 +113,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/shader/slang/library/Makefile b/src/mesa/shader/slang/library/Makefile index dc67b59088..0e03fac2ee 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/x86-64/Makefile b/src/mesa/x86-64/Makefile index 252218ca86..c6b69bafe8 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 3c6a6b11c0..dc8c7f355e 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 -- cgit v1.2.3 From 5b5c9315275752add1215dba0f86d5f5068d856b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 7 May 2008 18:51:44 -0600 Subject: fix refcounting bugs in tnl/tex program caches --- src/mesa/main/mtypes.h | 12 ++++----- src/mesa/main/texenvprogram.c | 59 ++++++++++++++++++++++++------------------- src/mesa/shader/program.c | 6 ++--- src/mesa/tnl/t_context.h | 2 +- src/mesa/tnl/t_vp_build.c | 51 +++++++++++++++++++------------------ 5 files changed, 68 insertions(+), 62 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 98fab69fd8..001240a14f 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). */ diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index fb68bf0720..68a4db9197 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/shader/program.c b/src/mesa/shader/program.c index 8166e7e935..39784a1416 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -303,7 +303,7 @@ void _mesa_delete_program(GLcontext *ctx, struct gl_program *prog) { (void) ctx; - ASSERT(prog); + ASSERT(prog); assert(prog->RefCount==0); if (prog == &_mesa_DummyProgram) return; @@ -378,7 +378,7 @@ _mesa_reference_program(GLcontext *ctx, GLboolean deleteFlag; /*_glthread_LOCK_MUTEX((*ptr)->Mutex);*/ -#if 0 +#if 01 printf("Program %p %u 0x%x Refcount-- to %d\n", *ptr, (*ptr)->Id, (*ptr)->Target, (*ptr)->RefCount - 1); #endif @@ -400,7 +400,7 @@ _mesa_reference_program(GLcontext *ctx, if (prog) { /*_glthread_LOCK_MUTEX(prog->Mutex);*/ prog->RefCount++; -#if 0 +#if 01 printf("Program %p %u 0x%x Refcount++ to %d\n", prog, prog->Id, prog->Target, prog->RefCount); #endif diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h index baf283ef0f..1ac508f033 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 f254a4d7a4..2b1eefe809 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,34 +1551,31 @@ 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(tnl->vp_cache, hash, key, ctx->VertexProgram._TnlProgram ); - } - else { - FREE(key); - if (0) - _mesa_printf("Found existing TNL program for key %x\n", hash); + cache_item(ctx, tnl->vp_cache, hash, key, newProg); + + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, newProg); } - _mesa_reference_vertprog(ctx, &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 @@ -1607,7 +1608,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); } -- cgit v1.2.3 From b4e75d6c41b2561ca86321fb775ca774c8af44eb Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 8 May 2008 10:59:31 -0600 Subject: disable debug printfs --- src/mesa/shader/program.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 39784a1416..ce64519448 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -378,7 +378,7 @@ _mesa_reference_program(GLcontext *ctx, GLboolean deleteFlag; /*_glthread_LOCK_MUTEX((*ptr)->Mutex);*/ -#if 01 +#if 0 printf("Program %p %u 0x%x Refcount-- to %d\n", *ptr, (*ptr)->Id, (*ptr)->Target, (*ptr)->RefCount - 1); #endif @@ -400,7 +400,7 @@ _mesa_reference_program(GLcontext *ctx, if (prog) { /*_glthread_LOCK_MUTEX(prog->Mutex);*/ prog->RefCount++; -#if 01 +#if 0 printf("Program %p %u 0x%x Refcount++ to %d\n", prog, prog->Id, prog->Target, prog->RefCount); #endif -- cgit v1.2.3 From 57e222d6e5ef5744491d093475e1136aedf81810 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 14 May 2008 12:10:45 -0600 Subject: fix some additional program refcounting bugs --- src/mesa/shader/program.c | 25 +++++++++---------------- src/mesa/shader/shader_api.c | 6 ++---- src/mesa/shader/slang/slang_emit.c | 4 ++-- 3 files changed, 13 insertions(+), 22 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index ce64519448..bde04b9c29 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -120,25 +120,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 */ @@ -303,7 +295,8 @@ void _mesa_delete_program(GLcontext *ctx, struct gl_program *prog) { (void) ctx; - ASSERT(prog); assert(prog->RefCount==0); + ASSERT(prog); + ASSERT(prog->RefCount==0); if (prog == &_mesa_DummyProgram) return; @@ -432,7 +425,7 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog) 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, diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index c319cef10a..65a8c6cc54 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -246,10 +246,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); diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 9c307c6275..d6ec3c5761 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; @@ -1793,7 +1793,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 */ -- cgit v1.2.3 From 450136d368ce7a08cf25992c79b51f51f8a9bb7c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 14 May 2008 12:37:07 -0600 Subject: mesa: added _mesa_free_instructions() cherry-picked from gallium-0.1 --- src/mesa/shader/prog_instruction.c | 17 +++++++++++++++++ src/mesa/shader/prog_instruction.h | 3 +++ 2 files changed, 20 insertions(+) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c index d6b5652a27..329fec3bac 100644 --- a/src/mesa/shader/prog_instruction.c +++ b/src/mesa/shader/prog_instruction.c @@ -118,6 +118,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 */ diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index c800757aa0..ce4daec104 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -437,6 +437,9 @@ 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); -- cgit v1.2.3 From 19ad9cf7741c641bd83d20485b32d11fe27ca8df Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 14 May 2008 12:39:41 -0600 Subject: mesa: added _mesa_insert_instructions() Also, use new _mesa_free_instructions() in a few places. cherry-picked from gallium-0.1 --- src/mesa/shader/program.c | 60 +++++++++++++++++++++++++++++++++++++++-------- src/mesa/shader/program.h | 2 ++ 2 files changed, 52 insertions(+), 10 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index bde04b9c29..92aa6ee44a 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -304,16 +304,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); @@ -485,6 +476,55 @@ _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; +} + /** * Mixing ARB and NV vertex/fragment programs can be tricky. diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index 9a6883e6a5..c5d36c78a0 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -112,6 +112,8 @@ _mesa_reference_fragprog(GLcontext *ctx, 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); /* * API functions common to ARB/NV_vertex/fragment_program -- cgit v1.2.3 From 6ca948a303e1af7ae66ea7082af741f6880887f2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 14 May 2008 12:53:03 -0600 Subject: added _mesa_combine_parameter_lists() cherry-picked from gallium-0.1 --- src/mesa/shader/prog_parameter.c | 33 +++++++++ src/mesa/shader/prog_parameter.h | 10 +++ src/mesa/shader/program.c | 149 +++++++++++++++++++++++++++++++++++++++ src/mesa/shader/program.h | 8 +++ src/mesa/shader/programopt.c | 96 ++++++++++++++++++++++++- src/mesa/shader/programopt.h | 2 + 6 files changed, 296 insertions(+), 2 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index 3ad7215755..500cfbbd87 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -603,6 +603,39 @@ _mesa_clone_parameter_list(const struct gl_program_parameter_list *list) } +/** + * 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. */ diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h index 09ff851ea7..105f6f24de 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/program.c b/src/mesa/shader/program.c index 92aa6ee44a..14e401e571 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -526,6 +526,155 @@ _mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count) } +/** + * 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++) { + 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; + } + } + } +} + + +/** + * 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, + struct gl_program *progA, 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; + 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) { + /* connect color outputs/inputs */ + if ((progA->OutputsWritten & (1 << FRAG_RESULT_COLR)) && + (progB->InputsRead & (1 << FRAG_ATTRIB_COL0))) { + replace_registers(newInst + lenA, lenB, + PROGRAM_INPUT, FRAG_ATTRIB_COL0, + PROGRAM_OUTPUT, FRAG_RESULT_COLR); + } + + newProg->InputsRead = progA->InputsRead; + newProg->InputsRead |= (progB->InputsRead & ~(1 << FRAG_ATTRIB_COL0)); + newProg->OutputsWritten = progB->OutputsWritten; + } + 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. * Note: GL_VERTEX_PROGRAM_ARB == GL_VERTEX_PROGRAM_NV diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index c5d36c78a0..0f0d6060a9 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -115,6 +115,14 @@ _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, + struct gl_program *progA, 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 fc5b0497fe..e6f065a33b 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; @@ -275,7 +276,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 +366,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 ce63644bbf..47ff2f0c7b 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 */ -- cgit v1.2.3 From bff695b926249ead1944eef2aa05b2e0eaf9ba7f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 14 May 2008 13:00:27 -0600 Subject: sync up with gallium-0.1 changes New _mesa_num_inst_dst_regs(), _mesa_is_tex_instruction() functions --- src/mesa/shader/prog_instruction.c | 194 +++++++++++++++++++++---------------- src/mesa/shader/prog_instruction.h | 6 ++ 2 files changed, 115 insertions(+), 85 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c index 329fec3bac..bea5d0551e 100644 --- a/src/mesa/shader/prog_instruction.c +++ b/src/mesa/shader/prog_instruction.c @@ -143,6 +143,7 @@ struct instruction_info gl_inst_opcode Opcode; const char *Name; GLuint NumSrcRegs; + GLuint NumDstRegs; }; /** @@ -150,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 } }; @@ -250,6 +251,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. */ diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index ce4daec104..aca768376a 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -443,6 +443,12 @@ _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); -- cgit v1.2.3 From e0f160663e50d0481afd8a9e1ec90c334be489e1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 14 May 2008 13:01:13 -0600 Subject: clean-up swizzle fields in fog code, fix NegateBase cherry-picked from gallium-0.1 --- src/mesa/shader/programopt.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c index e6f065a33b..7d560c74a5 100644 --- a/src/mesa/shader/programopt.c +++ b/src/mesa/shader/programopt.c @@ -193,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++; } @@ -215,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; */ @@ -228,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; */ @@ -241,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++; } @@ -253,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; -- cgit v1.2.3 From c807c1a23fc918591e9d2f6f26c4e071a725bced Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 14 May 2008 13:12:44 -0600 Subject: mesa: new functions for managing list/index of uniforms cherry-picked from gallium-0.1 --- src/mesa/shader/prog_uniform.c | 157 +++++++++++++++++++++++++++++++++++++++++ src/mesa/shader/prog_uniform.h | 91 ++++++++++++++++++++++++ 2 files changed, 248 insertions(+) create mode 100644 src/mesa/shader/prog_uniform.c create mode 100644 src/mesa/shader/prog_uniform.h (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/prog_uniform.c b/src/mesa/shader/prog_uniform.c new file mode 100644 index 0000000000..20e004b350 --- /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 0000000000..735de28705 --- /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 */ -- cgit v1.2.3 From ade508312c701ce89d3c2cd717994dbbabb4f207 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 14 May 2008 16:09:46 -0600 Subject: Updated GLSL uniform/sampler handling from gallium-0.1 branch Previously, the shader linker combined the uniforms used by the vertex and fragment shaders into a combined set of uniforms. This made the implementation of glUniform*() simple, but was rather inefficient otherwise. Now each shader gets its own set of uniforms (no more modelview matrix showing up in the fragment shader uniforms, for example). cherry-picked by hand from gallium-0.1 branch --- src/mesa/main/config.h | 1 + src/mesa/main/mtypes.h | 14 +- src/mesa/shader/prog_execute.c | 8 +- src/mesa/shader/prog_execute.h | 2 + src/mesa/shader/prog_instruction.h | 3 +- src/mesa/shader/prog_parameter.c | 7 +- src/mesa/shader/prog_parameter.h | 2 +- src/mesa/shader/shader_api.c | 423 ++++++++++++++++----------------- src/mesa/shader/slang/slang_codegen.c | 10 +- src/mesa/shader/slang/slang_compile.c | 18 ++ src/mesa/shader/slang/slang_emit.c | 6 +- src/mesa/shader/slang/slang_link.c | 236 +++++------------- src/mesa/shader/slang/slang_link.h | 4 - src/mesa/shader/slang/slang_typeinfo.h | 1 + src/mesa/sources | 1 + src/mesa/swrast/s_fragprog.c | 14 +- src/mesa/swrast/s_span.c | 1 - 17 files changed, 338 insertions(+), 413 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index ab0f035b45..58a39d11d4 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/mtypes.h b/src/mesa/main/mtypes.h index 001240a14f..04da767ec9 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1863,6 +1863,7 @@ enum register_file /** Vertex and fragment instructions */ struct prog_instruction; struct gl_program_parameter_list; +struct gl_uniform_list; /** @@ -1882,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 */ @@ -1894,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; @@ -2086,7 +2093,7 @@ struct gl_query_state /** - * A GLSL shader object. + * A GLSL vertex or fragment shader object. */ struct gl_shader { @@ -2104,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 { @@ -2119,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 */ diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c index cb17aa501c..d9bde3fc04 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); } } diff --git a/src/mesa/shader/prog_execute.h b/src/mesa/shader/prog_execute.h index 3ea0ba1565..18b13e11a4 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.h b/src/mesa/shader/prog_instruction.h index aca768376a..f8ff33ed30 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -413,12 +413,13 @@ struct prog_instruction */ GLint BranchTarget; +#if 0 /** * For TEX instructions in shaders, the sampler to use for the * texture lookup. */ GLint Sampler; - +#endif const char *Comment; }; diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index 500cfbbd87..0b61bac696 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -282,22 +282,25 @@ _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) */ GLint _mesa_add_sampler(struct gl_program_parameter_list *paramList, - const char *name, GLenum datatype) + const char *name, GLenum datatype, GLuint index) { GLint i = _mesa_lookup_parameter_index(paramList, -1, name); if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) { ASSERT(paramList->Parameters[i].Size == 1); ASSERT(paramList->Parameters[i].DataType == datatype); + ASSERT(paramList->ParameterValues[i][0] == index); /* already in list */ return i; } else { + GLfloat indexf = index; const GLint size = 1; /* a sampler is basically a texture unit number */ i = _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name, - size, datatype, NULL, NULL); + size, datatype, &indexf, NULL); return i; } } diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h index 105f6f24de..d6cc03448c 100644 --- a/src/mesa/shader/prog_parameter.h +++ b/src/mesa/shader/prog_parameter.h @@ -114,7 +114,7 @@ _mesa_add_uniform(struct gl_program_parameter_list *paramList, extern GLint _mesa_add_sampler(struct gl_program_parameter_list *paramList, - const char *name, GLenum datatype); + const char *name, GLenum datatype, GLuint index); extern GLint _mesa_add_varying(struct gl_program_parameter_list *paramList, diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 65a8c6cc54..11450db644 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" @@ -75,23 +76,23 @@ _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; - } + /* Set ptr to NULL since the param list is shared with the + * original/unlinked program. + */ + shProg->VertexProgram->Base.Parameters = NULL; _mesa_reference_vertprog(ctx, &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; - } + /* Set ptr to NULL since the param list is shared with the + * original/unlinked program. + */ + shProg->FragmentProgram->Base.Parameters = 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; } @@ -680,9 +681,9 @@ _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 */ } @@ -696,41 +697,41 @@ _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index, { 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; } @@ -848,14 +849,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; @@ -952,42 +949,24 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, 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 (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]; + if (location < shProg->Uniforms->NumUniforms) { + GLint progPos, i; + const struct gl_program *prog; + + progPos = shProg->Uniforms->Uniforms[location].VertPos; + if (progPos >= 0) { + prog = &shProg->VertexProgram->Base; } - else - for (i = 0; i < uSize; i++) { - params[i] = shProg->Uniforms->ParameterValues[location][i]; + else { + progPos = shProg->Uniforms->Uniforms[location].FragPos; + if (progPos >= 0) { + prog = &shProg->FragmentProgram->Base; } + } + + 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)"); @@ -1007,23 +986,10 @@ _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); } @@ -1134,55 +1100,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(). + */ +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) { @@ -1212,69 +1244,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); } } @@ -1287,62 +1306,42 @@ _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; } } diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index ebead3274e..88baf54d13 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -2836,14 +2836,14 @@ _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); + const GLint sampNum = A->numSamplers++; + _mesa_add_sampler(prog->Parameters, varName, datatype, sampNum); + 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 2be89a5ce0..1449888f9f 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" @@ -1618,6 +1620,7 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, A.program = O->program; A.vartable = O->vartable; A.curFuncEndLabel = NULL; + A.numSamplers = 0; if (!_slang_codegen_global_variable(&A, var, C->type)) return 0; } @@ -1640,6 +1643,7 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, A.space.funcs = O->funs; A.space.structs = O->structs; A.space.vars = O->vars; + A.numSamplers = 0; if (!initialize_global(&A, var)) return 0; } @@ -1773,6 +1777,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, A.program = O->program; A.vartable = O->vartable; A.log = C->L; + A.numSamplers = 0; _slang_codegen_function(&A, *parsed_func_ret); } @@ -2180,6 +2185,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 d6ec3c5761..ff63e05dd2 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -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; } diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 72fe9997c5..8213b7772c 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 + /* + * 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); } - 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; - } - } - - 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(); /** @@ -531,33 +422,30 @@ _slang_link(GLcontext *ctx, _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); } + /* 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); + link_uniform_vars(shProg, &shProg->FragmentProgram->Base, &numSamplers); - /* 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; - assert(shProg->Uniforms); - } - if (shProg->FragmentProgram) { - _mesa_free_parameter_list(shProg->FragmentProgram->Base.Parameters); - shProg->FragmentProgram->Base.Parameters = shProg->Uniforms; - assert(shProg->Uniforms); - } + /*_mesa_print_uniforms(shProg->Uniforms);*/ if (shProg->VertexProgram) { - _slang_resolve_samplers(shProg, &shProg->VertexProgram->Base); + /* Rather than cloning the parameter list here, just share it. + * We need to be careful _mesa_clear_shader_program_data() in + * to avoid double-freeing. + */ + shProg->VertexProgram->Base.Parameters = vertProg->Base.Parameters; } if (shProg->FragmentProgram) { - _slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base); + /* see comment just above */ + shProg->FragmentProgram->Base.Parameters = fragProg->Base.Parameters; } if (shProg->VertexProgram) { diff --git a/src/mesa/shader/slang/slang_link.h b/src/mesa/shader/slang/slang_link.h index 606b9e46b1..8ef8a6b4b3 100644 --- a/src/mesa/shader/slang/slang_link.h +++ b/src/mesa/shader/slang/slang_link.h @@ -32,10 +32,6 @@ extern void _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/shader/slang/slang_typeinfo.h b/src/mesa/shader/slang/slang_typeinfo.h index 587331e8b1..ad5aa3e195 100644 --- a/src/mesa/shader/slang/slang_typeinfo.h +++ b/src/mesa/shader/slang/slang_typeinfo.h @@ -65,6 +65,7 @@ typedef struct slang_assemble_ctx_ struct slang_label_ *curFuncEndLabel; struct slang_ir_node_ *CurLoop; struct slang_function_ *CurFunction; + GLuint numSamplers; } slang_assemble_ctx; diff --git a/src/mesa/sources b/src/mesa/sources index dbfc01d0ed..054f667a25 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_fragprog.c b/src/mesa/swrast/s_fragprog.c index 2dfc033d50..ecace9c502 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 656a90a99a..4c58f8de87 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; -- cgit v1.2.3 From 0639998ee8750083b5e4ad90371c475cb2cca88f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 16 May 2008 13:15:03 -0700 Subject: Fix DRI build --- src/mesa/shader/prog_instruction.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index f8ff33ed30..aca768376a 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -413,13 +413,12 @@ struct prog_instruction */ GLint BranchTarget; -#if 0 /** * For TEX instructions in shaders, the sampler to use for the * texture lookup. */ GLint Sampler; -#endif + const char *Comment; }; -- cgit v1.2.3 From 885cc592dfcc3b46e1896d243f60c38cf18fa54b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 14 May 2008 16:23:46 -0600 Subject: fix assertion typo: s/=/==/ --- src/mesa/shader/slang/slang_codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 88baf54d13..8e4c10ff43 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 -- cgit v1.2.3 From 1af2b14514146d5f0d48a45165a579e88cc7a867 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 14 May 2008 16:44:48 -0600 Subject: init SamplersUsed bits in _mesa_parse_arb_fragment_program --- src/mesa/shader/arbprogparse.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index 74004e9b13..60aaabe679 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; -- cgit v1.2.3 From 6de6999edc41ed5cb8840bfb3265d025b2cbdfe7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 14 May 2008 19:14:10 -0600 Subject: whitespace/formatting --- src/mesa/shader/prog_execute.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c index d9bde3fc04..8ce2ca3964 100644 --- a/src/mesa/shader/prog_execute.c +++ b/src/mesa/shader/prog_execute.c @@ -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++; -- cgit v1.2.3 From eb4271ea8b29cff87f33d3ed9aee43d59986d2d9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 16 May 2008 09:38:33 -0600 Subject: remove stray, left-over RefCount++ --- src/mesa/shader/program.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 14e401e571..63ab4dd67d 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -73,7 +73,6 @@ _mesa_init_program(GLcontext *ctx) _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 */ -- cgit v1.2.3 From a3e86d43e6c99af97c2931c883d552c9714006e8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 16 May 2008 09:56:11 -0600 Subject: minor changes to aid debugging --- src/mesa/shader/program.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 63ab4dd67d..adc7000995 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -268,19 +268,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; } @@ -362,8 +366,10 @@ _mesa_reference_program(GLcontext *ctx, /*_glthread_LOCK_MUTEX((*ptr)->Mutex);*/ #if 0 - printf("Program %p %u 0x%x Refcount-- to %d\n", - *ptr, (*ptr)->Id, (*ptr)->Target, (*ptr)->RefCount - 1); + 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--; @@ -384,8 +390,10 @@ _mesa_reference_program(GLcontext *ctx, /*_glthread_LOCK_MUTEX(prog->Mutex);*/ prog->RefCount++; #if 0 - printf("Program %p %u 0x%x Refcount++ to %d\n", - prog, prog->Id, prog->Target, prog->RefCount); + 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);*/ } -- cgit v1.2.3 From 8bdf5b6e6465ff734a798efb193ab16cd33df36e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 16 May 2008 09:56:59 -0600 Subject: Fix a program refcounting error, don't share program parameter lists. The refcounting bug was causing a memleak (unfreed programs). The old parameter list sharing is not needed since the change in how uniforms are handled. --- src/mesa/shader/shader_api.c | 29 ++++++++++------------------- src/mesa/shader/slang/slang_link.c | 32 ++++++++++---------------------- 2 files changed, 20 insertions(+), 41 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 11450db644..08fa9a7e23 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -75,21 +75,8 @@ void _mesa_clear_shader_program_data(GLcontext *ctx, struct gl_shader_program *shProg) { - if (shProg->VertexProgram) { - /* Set ptr to NULL since the param list is shared with the - * original/unlinked program. - */ - shProg->VertexProgram->Base.Parameters = NULL; - _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); - } - - if (shProg->FragmentProgram) { - /* Set ptr to NULL since the param list is shared with the - * original/unlinked program. - */ - shProg->FragmentProgram->Base.Parameters = NULL; - _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); - } + _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); + _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); if (shProg->Uniforms) { _mesa_free_uniform_list(shProg->Uniforms); @@ -176,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) { @@ -191,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; } } diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 8213b7772c..80cd4b6df6 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -406,20 +406,20 @@ _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) { - _mesa_reference_vertprog(ctx, &shProg->VertexProgram, - vertex_program(_mesa_clone_program(ctx, &vertProg->Base))); - } - else { - _mesa_reference_vertprog(ctx, &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) { - _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, - fragment_program(_mesa_clone_program(ctx, &fragProg->Base))); - } - else { - _mesa_reference_fragprog(ctx, &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 */ @@ -436,18 +436,6 @@ _slang_link(GLcontext *ctx, /*_mesa_print_uniforms(shProg->Uniforms);*/ - if (shProg->VertexProgram) { - /* Rather than cloning the parameter list here, just share it. - * We need to be careful _mesa_clear_shader_program_data() in - * to avoid double-freeing. - */ - shProg->VertexProgram->Base.Parameters = vertProg->Base.Parameters; - } - if (shProg->FragmentProgram) { - /* see comment just above */ - shProg->FragmentProgram->Base.Parameters = fragProg->Base.Parameters; - } - if (shProg->VertexProgram) { if (!_slang_resolve_attributes(shProg, &shProg->VertexProgram->Base)) { /*goto cleanup;*/ -- cgit v1.2.3 From f2632212ad7735c659331b65d3bfe14aef0faccb Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 16 May 2008 10:49:44 -0600 Subject: silence warning, new assertion --- src/mesa/shader/shader_api.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 08fa9a7e23..61d51c3871 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -942,7 +942,7 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, if (shProg) { if (location < shProg->Uniforms->NumUniforms) { GLint progPos, i; - const struct gl_program *prog; + const struct gl_program *prog = NULL; progPos = shProg->Uniforms->Uniforms[location].VertPos; if (progPos >= 0) { @@ -955,8 +955,11 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, } } - for (i = 0; i < prog->Parameters->Parameters[progPos].Size; i++) { - params[i] = prog->Parameters->ParameterValues[progPos][i]; + ASSERT(prog); + if (prog) { + for (i = 0; i < prog->Parameters->Parameters[progPos].Size; i++) { + params[i] = prog->Parameters->ParameterValues[progPos][i]; + } } } else { -- cgit v1.2.3 From 896c0cc8ec3c9489ba36876b8b580dedf85811c8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 16 May 2008 15:47:55 -0600 Subject: bring in fixes/changes from gallium-0.1 --- src/mesa/shader/shader_api.c | 112 +++++++++++++------------------------------ 1 file changed, 32 insertions(+), 80 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 61d51c3871..8bb1600267 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -360,54 +360,6 @@ 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() */ @@ -452,6 +404,37 @@ _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader) } +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; +} + + void _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index, const GLchar *name) @@ -686,7 +669,7 @@ _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); const struct gl_program *prog; GLint progPos; @@ -749,37 +732,6 @@ _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 _mesa_get_handle(GLcontext *ctx, GLenum pname) { -- cgit v1.2.3 From 4b6b0fd526b16d70bb5d1acc8d93af280660c810 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 18 May 2008 15:41:01 -0600 Subject: clean-ups / additions from gallium-0.1 branch --- src/mesa/shader/prog_print.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 308cce2206..1c35ce3fec 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; -- cgit v1.2.3 From 5976a6a75cfa6749db306111a601d99c99cc00a4 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 18 May 2008 15:41:36 -0600 Subject: added div by zero check for Fog.End/Start (from gallium-0.1) --- src/mesa/shader/prog_statevars.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c index 4ae74c1d42..72bdad7654 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: { -- cgit v1.2.3 From 0c78c766e4cb8ffcda44cabfadb8de8e09121034 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 18 May 2008 15:46:26 -0600 Subject: fixes to _mesa_combine_programs(), from gallium-0.1 --- src/mesa/shader/program.c | 49 ++++++++++++++++++++++++++++++++++++++++++----- src/mesa/shader/program.h | 3 ++- 2 files changed, 46 insertions(+), 6 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index adc7000995..044d6449ac 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -214,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; @@ -430,6 +436,7 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog) 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) @@ -544,6 +551,7 @@ replace_registers(struct prog_instruction *inst, GLuint numInst, { 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) { @@ -551,6 +559,11 @@ replace_registers(struct prog_instruction *inst, GLuint numInst, 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; + } } } @@ -584,7 +597,8 @@ adjust_param_indexes(struct prog_instruction *inst, GLuint numInst, */ struct gl_program * _mesa_combine_programs(GLcontext *ctx, - struct gl_program *progA, struct gl_program *progB) + const struct gl_program *progA, + const struct gl_program *progB) { struct prog_instruction *newInst; struct gl_program *newProg; @@ -592,6 +606,7 @@ _mesa_combine_programs(GLcontext *ctx, 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); @@ -613,17 +628,41 @@ _mesa_combine_programs(GLcontext *ctx, newProg->NumInstructions = newLength; if (newProg->Target == GL_FRAGMENT_PROGRAM_ARB) { - /* connect color outputs/inputs */ + 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) { + _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_OUTPUT, FRAG_RESULT_COLR); + PROGRAM_TEMPORARY, tempReg); } - newProg->InputsRead = progA->InputsRead; - newProg->InputsRead |= (progB->InputsRead & ~(1 << FRAG_ATTRIB_COL0)); + 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 */ diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index 0f0d6060a9..f1a69a2c01 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -117,7 +117,8 @@ _mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count); extern struct gl_program * _mesa_combine_programs(GLcontext *ctx, - struct gl_program *progA, struct gl_program *progB); + const struct gl_program *progA, + const struct gl_program *progB); extern GLint _mesa_find_free_register(const struct gl_program *prog, GLuint regFile); -- cgit v1.2.3 From 2f8fc325aca43693aac368ae5781547cc976d387 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 18 May 2008 15:50:20 -0600 Subject: mesa: added internal post color matrix scale/bias vars cherry-picked from gallium-0.1 (302daeb2ec62c59bd28d0c53cdc0fb07dc9d0f58) --- src/mesa/shader/prog_statevars.c | 30 ++++++++++++++++++++++++++++++ src/mesa/shader/prog_statevars.h | 4 ++++ 2 files changed, 34 insertions(+) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c index 72bdad7654..dd3c3a1c8c 100644 --- a/src/mesa/shader/prog_statevars.c +++ b/src/mesa/shader/prog_statevars.c @@ -435,6 +435,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. @@ -671,6 +689,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: ; } diff --git a/src/mesa/shader/prog_statevars.h b/src/mesa/shader/prog_statevars.h index 22bb8e07ad..53529ab243 100644 --- a/src/mesa/shader/prog_statevars.h +++ b/src/mesa/shader/prog_statevars.h @@ -108,6 +108,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; -- cgit v1.2.3 From 6e92968d751ce3006b5ca0fc59eced20c94dc507 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 18 May 2008 15:52:13 -0600 Subject: add state vars for color matrix, pixel transfer scale&bias cherry-picked from gallium-0.1 (068c7bd912283e051a55b2fd5c4568685d10f3ed) --- src/mesa/shader/prog_statevars.c | 4 ++++ src/mesa/shader/prog_statevars.h | 1 + 2 files changed, 5 insertions(+) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c index dd3c3a1c8c..592a63651c 100644 --- a/src/mesa/shader/prog_statevars.c +++ b/src/mesa/shader/prog_statevars.c @@ -279,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 */ @@ -312,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; diff --git a/src/mesa/shader/prog_statevars.h b/src/mesa/shader/prog_statevars.h index 53529ab243..64820a5b68 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, -- cgit v1.2.3 From 88c0a7463328ef47106ea0afbeb148ebd4e6d067 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 18 May 2008 15:55:24 -0600 Subject: additional fog/color matrix changes from gallium-0.1 --- src/mesa/shader/prog_statevars.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c index 592a63651c..539057b438 100644 --- a/src/mesa/shader/prog_statevars.c +++ b/src/mesa/shader/prog_statevars.c @@ -425,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; @@ -515,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; @@ -608,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; @@ -783,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 */ @@ -850,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]); } } -- cgit v1.2.3 From fd59f19cd2388519265dfba3d28e5281df6f4ba0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 18 May 2008 16:04:55 -0600 Subject: Move _mesa_init_glsl_driver_functions() into shader_api.c This allows making a bunch of functions static, and removes a state tracker dependency on driverfuncs.c cherry-picked from gallium-0.1 --- src/mesa/drivers/common/driverfuncs.c | 37 ------------ src/mesa/drivers/common/driverfuncs.h | 4 -- src/mesa/shader/shader_api.c | 93 +++++++++++++++++++++--------- src/mesa/shader/shader_api.h | 103 ++-------------------------------- 4 files changed, 69 insertions(+), 168 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c index 7fe116285c..e61b9f59cf 100644 --- a/src/mesa/drivers/common/driverfuncs.c +++ b/src/mesa/drivers/common/driverfuncs.c @@ -261,43 +261,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. diff --git a/src/mesa/drivers/common/driverfuncs.h b/src/mesa/drivers/common/driverfuncs.h index 6ed23c4520..4c90ed12f6 100644 --- a/src/mesa/drivers/common/driverfuncs.h +++ b/src/mesa/drivers/common/driverfuncs.h @@ -30,10 +30,6 @@ extern void _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/shader/shader_api.c b/src/mesa/shader/shader_api.c index 8bb1600267..0bb96a0d6c 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -53,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; @@ -363,7 +363,7 @@ copy_string(GLchar *dst, GLsizei maxLength, GLsizei *length, const GLchar *src) /** * Called via ctx->Driver.AttachShader() */ -void +static void _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader) { struct gl_shader_program *shProg @@ -404,7 +404,7 @@ _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader) } -GLint +static GLint _mesa_get_attrib_location(GLcontext *ctx, GLuint program, const GLchar *name) { @@ -435,7 +435,7 @@ _mesa_get_attrib_location(GLcontext *ctx, GLuint program, } -void +static void _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index, const GLchar *name) { @@ -481,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; @@ -505,7 +505,7 @@ _mesa_create_shader(GLcontext *ctx, GLenum type) } -GLuint +static GLuint _mesa_create_program(GLcontext *ctx) { GLuint name; @@ -526,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) { /* @@ -552,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); @@ -567,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 @@ -629,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) @@ -664,7 +664,7 @@ _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index, /** * 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) @@ -712,7 +712,7 @@ _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index, /** * Called via ctx->Driver.GetAttachedShaders(). */ -void +static void _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj) { @@ -732,7 +732,7 @@ _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount, } -GLuint +static GLuint _mesa_get_handle(GLcontext *ctx, GLenum pname) { #if 0 @@ -756,7 +756,7 @@ _mesa_get_handle(GLcontext *ctx, GLenum pname) } -void +static void _mesa_get_programiv(GLcontext *ctx, GLuint program, GLenum pname, GLint *params) { @@ -806,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); @@ -839,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) { @@ -853,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) { @@ -869,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) { @@ -885,7 +885,7 @@ _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) { @@ -927,7 +927,7 @@ _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 @@ -939,7 +939,7 @@ _mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name) } -GLboolean +static GLboolean _mesa_is_program(GLcontext *ctx, GLuint name) { struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name); @@ -947,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); @@ -959,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); @@ -980,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); @@ -997,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; @@ -1143,7 +1143,7 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program, GLint location, /** * Called via ctx->Driver.Uniform(). */ -void +static void _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count, const GLvoid *values, GLenum type) { @@ -1247,7 +1247,7 @@ set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program, /** * 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) @@ -1292,7 +1292,7 @@ _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows, } -void +static void _mesa_validate_program(GLcontext *ctx, GLuint program) { struct gl_shader_program *shProg; @@ -1318,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 27e5870d70..5521c585b5 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 */ -- cgit v1.2.3 From e469d78d33feff45f16235871ca1a3d483cdc950 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 19 May 2008 16:03:43 -0600 Subject: fix tempReg test in _mesa_combine_programs() --- src/mesa/shader/program.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 044d6449ac..7048770cf7 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -641,7 +641,7 @@ _mesa_combine_programs(GLcontext *ctx, if ((progA->OutputsWritten & (1 << FRAG_RESULT_COLR)) && (progB->InputsRead & (1 << FRAG_ATTRIB_COL0))) { GLint tempReg = _mesa_find_free_register(newProg, PROGRAM_TEMPORARY); - if (!tempReg) { + if (tempReg < 0) { _mesa_problem(ctx, "No free temp regs found in " "_mesa_combine_programs(), using 31"); tempReg = 31; -- cgit v1.2.3 From b6fb0940c226373ac235a5d327d3fcfd742bc6b9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 20 May 2008 10:59:18 -0600 Subject: fix incorrect sampler numbering/indexing. All samplers indexes were zero. --- src/mesa/shader/prog_parameter.c | 20 +++++++++++++------- src/mesa/shader/prog_parameter.h | 2 +- src/mesa/shader/slang/slang_codegen.c | 3 +-- src/mesa/shader/slang/slang_compile.c | 3 --- src/mesa/shader/slang/slang_typeinfo.h | 1 - 5 files changed, 15 insertions(+), 14 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index 0b61bac696..75cf5023df 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -283,25 +283,31 @@ _mesa_add_uniform(struct gl_program_parameter_list *paramList, * \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, - const char *name, GLenum datatype, GLuint index) + const char *name, GLenum datatype) { GLint i = _mesa_lookup_parameter_index(paramList, -1, name); if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) { ASSERT(paramList->Parameters[i].Size == 1); ASSERT(paramList->Parameters[i].DataType == datatype); - ASSERT(paramList->ParameterValues[i][0] == index); /* already in list */ - return i; + return (GLint) paramList->ParameterValues[i][0]; } else { - GLfloat indexf = index; const GLint size = 1; /* a sampler is basically a texture unit number */ - i = _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name, - size, datatype, &indexf, 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; } } diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h index d6cc03448c..105f6f24de 100644 --- a/src/mesa/shader/prog_parameter.h +++ b/src/mesa/shader/prog_parameter.h @@ -114,7 +114,7 @@ _mesa_add_uniform(struct gl_program_parameter_list *paramList, extern GLint _mesa_add_sampler(struct gl_program_parameter_list *paramList, - const char *name, GLenum datatype, GLuint index); + const char *name, GLenum datatype); extern GLint _mesa_add_varying(struct gl_program_parameter_list *paramList, diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 8e4c10ff43..d19d5a0abb 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -2841,8 +2841,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, * store->Index = sampler number (0..7, typically) * store->Size = texture type index (1D, 2D, 3D, cube, etc) */ - const GLint sampNum = A->numSamplers++; - _mesa_add_sampler(prog->Parameters, varName, datatype, sampNum); + GLint sampNum = _mesa_add_sampler(prog->Parameters, varName, datatype); store = _slang_new_ir_storage(PROGRAM_SAMPLER, sampNum, texIndex); if (dbg) printf("SAMPLER "); } diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index 1449888f9f..46b5c54bbe 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -1620,7 +1620,6 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, A.program = O->program; A.vartable = O->vartable; A.curFuncEndLabel = NULL; - A.numSamplers = 0; if (!_slang_codegen_global_variable(&A, var, C->type)) return 0; } @@ -1643,7 +1642,6 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, A.space.funcs = O->funs; A.space.structs = O->structs; A.space.vars = O->vars; - A.numSamplers = 0; if (!initialize_global(&A, var)) return 0; } @@ -1777,7 +1775,6 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, A.program = O->program; A.vartable = O->vartable; A.log = C->L; - A.numSamplers = 0; _slang_codegen_function(&A, *parsed_func_ret); } diff --git a/src/mesa/shader/slang/slang_typeinfo.h b/src/mesa/shader/slang/slang_typeinfo.h index ad5aa3e195..587331e8b1 100644 --- a/src/mesa/shader/slang/slang_typeinfo.h +++ b/src/mesa/shader/slang/slang_typeinfo.h @@ -65,7 +65,6 @@ typedef struct slang_assemble_ctx_ struct slang_label_ *curFuncEndLabel; struct slang_ir_node_ *CurLoop; struct slang_function_ *CurFunction; - GLuint numSamplers; } slang_assemble_ctx; -- cgit v1.2.3 From b539b6132141b0f583076355ad158852667b79cd Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 20 May 2008 11:29:16 -0600 Subject: copy StateFlags in _mesa_clone_parameter_list() --- src/mesa/shader/prog_parameter.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index 75cf5023df..152bd79f69 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -608,6 +608,8 @@ _mesa_clone_parameter_list(const struct gl_program_parameter_list *list) } } + clone->StateFlags = list->StateFlags; + return clone; } -- cgit v1.2.3 From 0ccffacee268ec80e5ef680d75cbbf8ed9603342 Mon Sep 17 00:00:00 2001 From: Jouk Jansen Date: Tue, 27 May 2008 08:58:39 -0600 Subject: updated for latest sources --- src/mesa/shader/descrip.mms | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/descrip.mms b/src/mesa/shader/descrip.mms index 157c193c79..bdac946efe 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 joukj@hrem.nano.tudelft.nl -# 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 -- cgit v1.2.3