diff options
-rw-r--r-- | src/mesa/main/mtypes.h | 10 | ||||
-rw-r--r-- | src/mesa/main/pipelineobj.c | 2 | ||||
-rw-r--r-- | src/mesa/main/shaderapi.c | 78 | ||||
-rw-r--r-- | src/mesa/main/shaderapi.h | 3 |
4 files changed, 61 insertions, 32 deletions
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 5b02fadf3cd..10f52349c91 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -4315,6 +4315,15 @@ struct gl_atomic_buffer_binding }; /** + * Shader subroutines storage + */ +struct gl_subroutine_index_binding +{ + GLuint NumIndex; + GLuint *IndexPtr; +}; + +/** * Mesa rendering context. * * This is the central context data structure for Mesa. Almost all @@ -4552,6 +4561,7 @@ struct gl_context */ struct gl_image_unit ImageUnits[MAX_IMAGE_UNITS]; + struct gl_subroutine_index_binding SubroutineIndex[MESA_SHADER_STAGES]; /*@}*/ struct gl_meta_state *Meta; /**< for "meta" operations */ diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c index cd8b0a775b6..82298409ee1 100644 --- a/src/mesa/main/pipelineobj.c +++ b/src/mesa/main/pipelineobj.c @@ -469,7 +469,7 @@ _mesa_bind_pipeline(struct gl_context *ctx, FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); for (i = 0; i < MESA_SHADER_STAGES; i++) - _mesa_shader_program_init_subroutine_defaults(ctx->_Shader->CurrentProgram[i]); + _mesa_shader_program_init_subroutine_defaults(ctx, ctx->_Shader->CurrentProgram[i]); } } diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 4f29cd974d0..6631f1ea479 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -65,6 +65,7 @@ #define PATH_MAX _MAX_PATH #endif +static void _mesa_shader_write_subroutine_index(struct gl_context *ctx, struct gl_linked_shader *sh); /** * Return mask of GLSL_x flags by examining the MESA_GLSL env var. */ @@ -1208,7 +1209,7 @@ use_shader_program(struct gl_context *ctx, gl_shader_stage stage, shProg = NULL; if (shProg) - _mesa_shader_program_init_subroutine_defaults(shProg); + _mesa_shader_program_init_subroutine_defaults(ctx, shProg); if (*target != shProg) { /* Program is current, flush it */ @@ -2648,27 +2649,15 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count, _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); return; } + + ctx->SubroutineIndex[sh->Stage].IndexPtr[j] = indices[j]; } i += uni_count; } while(i < count); FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); - i = 0; - do { - struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i]; - if (uni == NULL) { - i++; - continue; - } - - int uni_count = uni->array_elements ? uni->array_elements : 1; - - memcpy(&uni->storage[0], &indices[i], - sizeof(GLuint) * uni_count); - _mesa_propagate_uniforms_to_driver_storage(uni, 0, uni_count); - i += uni_count; - } while(i < count); + _mesa_shader_write_subroutine_index(ctx, sh); } @@ -2710,12 +2699,7 @@ _mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location, return; } - { - struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[location]; - int offset = location - uni->opaque[stage].index; - memcpy(params, &uni->storage[offset], - sizeof(GLuint)); - } + *params = ctx->SubroutineIndex[sh->Stage].IndexPtr[location]; } @@ -2824,29 +2808,63 @@ find_compat_subroutine(struct gl_linked_shader *sh, } static void -_mesa_shader_init_subroutine_defaults(struct gl_linked_shader *sh) +_mesa_shader_write_subroutine_index(struct gl_context *ctx, + struct gl_linked_shader *sh) { int i, j; - for (i = 0; i < sh->NumSubroutineUniformRemapTable; i++) { + if (sh->NumSubroutineUniformRemapTable == 0) + return; + + i = 0; + do { struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i]; int uni_count; int val; - if (!uni) + if (!uni) { + i++; continue; - uni_count = uni->array_elements ? uni->array_elements : 1; - val = find_compat_subroutine(sh, uni->type); + } - for (j = 0; j < uni_count; j++) + uni_count = uni->array_elements ? uni->array_elements : 1; + for (j = 0; j < uni_count; j++) { + val = ctx->SubroutineIndex[sh->Stage].IndexPtr[i + j]; memcpy(&uni->storage[j], &val, sizeof(int)); + } _mesa_propagate_uniforms_to_driver_storage(uni, 0, uni_count); + i += uni_count; + } while(i < sh->NumSubroutineUniformRemapTable); +} + +static void +_mesa_shader_init_subroutine_defaults(struct gl_context *ctx, + struct gl_linked_shader *sh) +{ + int i; + struct gl_subroutine_index_binding *binding = &ctx->SubroutineIndex[sh->Stage]; + if (binding->NumIndex != sh->NumSubroutineUniformRemapTable) { + binding->IndexPtr = realloc(binding->IndexPtr, + sh->NumSubroutineUniformRemapTable * (sizeof(GLuint))); + binding->NumIndex = sh->NumSubroutineUniformRemapTable; + } + + for (i = 0; i < sh->NumSubroutineUniformRemapTable; i++) { + struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i]; + + if (!uni) + continue; + + binding->IndexPtr[i] = find_compat_subroutine(sh, uni->type); } + + _mesa_shader_write_subroutine_index(ctx, sh); } void -_mesa_shader_program_init_subroutine_defaults(struct gl_shader_program *shProg) +_mesa_shader_program_init_subroutine_defaults(struct gl_context *ctx, + struct gl_shader_program *shProg) { int i; @@ -2857,6 +2875,6 @@ _mesa_shader_program_init_subroutine_defaults(struct gl_shader_program *shProg) if (!shProg->_LinkedShaders[i]) continue; - _mesa_shader_init_subroutine_defaults(shProg->_LinkedShaders[i]); + _mesa_shader_init_subroutine_defaults(ctx, shProg->_LinkedShaders[i]); } } diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h index 09b9525e402..b3de5fab1e7 100644 --- a/src/mesa/main/shaderapi.h +++ b/src/mesa/main/shaderapi.h @@ -286,7 +286,8 @@ _mesa_PatchParameterfv(GLenum pname, const GLfloat *values); /* GL_ARB_shader_subroutine */ void -_mesa_shader_program_init_subroutine_defaults(struct gl_shader_program *shProg); +_mesa_shader_program_init_subroutine_defaults(struct gl_context *ctx, + struct gl_shader_program *shProg); extern GLint GLAPIENTRY _mesa_GetSubroutineUniformLocation(GLuint program, GLenum shadertype, |