From: Marek Olšák <marek.ol...@amd.com> --- src/mesa/main/shaderapi.c | 8 ++++++-- src/mesa/main/uniform_query.cpp | 21 +++++++++++++++++++-- src/mesa/main/uniforms.h | 4 ++++ src/mesa/state_tracker/st_context.c | 3 --- 4 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 9f0122a..5a71240 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -2579,27 +2579,33 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count, _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); return; } if (count != p->sh.NumSubroutineUniformRemapTable) { _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name); return; } i = 0; + bool flushed = false; do { struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i]; if (uni == NULL) { i++; continue; } + if (!flushed) { + _mesa_flush_vertices_for_uniforms(ctx, uni); + flushed = true; + } + int uni_count = uni->array_elements ? uni->array_elements : 1; int j, k, f; for (j = i; j < i + uni_count; j++) { struct gl_subroutine_function *subfn = NULL; if (indices[j] > p->sh.MaxSubroutineFunctionIndex) { _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name); return; } @@ -2618,22 +2624,20 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count, } if (k == subfn->num_compat_types) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); return; } ctx->SubroutineIndex[p->info.stage].IndexPtr[j] = indices[j]; } i += uni_count; } while(i < count); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); } GLvoid GLAPIENTRY _mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location, GLuint *params) { GET_CURRENT_CONTEXT(ctx); const char *api_name = "glGetUniformSubroutineuiv"; gl_shader_stage stage; diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp index e6c78bf..f9ea492 100644 --- a/src/mesa/main/uniform_query.cpp +++ b/src/mesa/main/uniform_query.cpp @@ -991,20 +991,37 @@ validate_uniform(GLint location, GLsizei count, const GLvoid *values, "glUniform1i(invalid image unit index for uniform %d)", location); return NULL; } } } return uni; } +void +_mesa_flush_vertices_for_uniforms(struct gl_context *ctx, + const struct gl_uniform_storage *uni) +{ + uint64_t new_driver_state = 0; + unsigned mask = uni->active_shader_mask; + + while (mask) { + unsigned index = u_bit_scan(&mask); + + assert(index < MESA_SHADER_STAGES); + new_driver_state |= ctx->DriverFlags.NewShaderConstants[index]; + } + + FLUSH_VERTICES(ctx, new_driver_state ? 0 : _NEW_PROGRAM_CONSTANTS); + ctx->NewDriverState |= new_driver_state; +} /** * Called via glUniform*() functions. */ extern "C" void _mesa_uniform(GLint location, GLsizei count, const GLvoid *values, struct gl_context *ctx, struct gl_shader_program *shProg, enum glsl_base_type basicType, unsigned src_components) { unsigned offset; @@ -1045,21 +1062,21 @@ _mesa_uniform(GLint location, GLsizei count, const GLvoid *values, * element that exceeds the highest array element index used, as * reported by GetActiveUniform, will be ignored by the GL." * * Clamp 'count' to a valid value. Note that for non-arrays a count > 1 * will have already generated an error. */ if (uni->array_elements != 0) { count = MIN2(count, (int) (uni->array_elements - offset)); } - FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); + _mesa_flush_vertices_for_uniforms(ctx, uni); /* Store the data in the "actual type" backing storage for the uniform. */ if (!uni->type->is_boolean()) { memcpy(&uni->storage[size_mul * components * offset], values, sizeof(uni->storage[0]) * components * count * size_mul); } else { const union gl_constant_value *src = (const union gl_constant_value *) values; union gl_constant_value *dst = &uni->storage[components * offset]; @@ -1222,21 +1239,21 @@ _mesa_uniform_matrix(GLint location, GLsizei count, * element that exceeds the highest array element index used, as * reported by GetActiveUniform, will be ignored by the GL." * * Clamp 'count' to a valid value. Note that for non-arrays a count > 1 * will have already generated an error. */ if (uni->array_elements != 0) { count = MIN2(count, (int) (uni->array_elements - offset)); } - FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); + _mesa_flush_vertices_for_uniforms(ctx, uni); /* Store the data in the "actual type" backing storage for the uniform. */ const unsigned elements = components * vectors; if (!transpose) { memcpy(&uni->storage[size_mul * elements * offset], values, sizeof(uni->storage[0]) * elements * count * size_mul); } else if (basicType == GLSL_TYPE_FLOAT) { /* Copy and transpose the matrix. diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h index 21d8571..7fd1aac 100644 --- a/src/mesa/main/uniforms.h +++ b/src/mesa/main/uniforms.h @@ -463,20 +463,24 @@ _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, extern void _mesa_update_shader_textures_used(struct gl_shader_program *shProg, struct gl_program *prog); extern bool _mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg, char *errMsg, size_t errMsgLength); extern bool _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *); +extern void +_mesa_flush_vertices_for_uniforms(struct gl_context *ctx, + const struct gl_uniform_storage *uni); + struct gl_builtin_uniform_element { const char *field; int tokens[STATE_LENGTH]; int swizzle; }; struct gl_builtin_uniform_desc { const char *name; const struct gl_builtin_uniform_element *elements; unsigned int num_elements; diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index e676a48..a81b2c2 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -236,23 +236,20 @@ st_invalidate_state(struct gl_context * ctx) if (new_state & _NEW_TEXTURE_OBJECT) { st->dirty |= st->active_states & (ST_NEW_SAMPLER_VIEWS | ST_NEW_SAMPLERS | ST_NEW_IMAGE_UNITS); if (ctx->FragmentProgram._Current && ctx->FragmentProgram._Current->ExternalSamplersUsed) { st->dirty |= ST_NEW_FS_STATE; } } - - if (new_state & _NEW_PROGRAM_CONSTANTS) - st->dirty |= st->active_states & ST_NEW_CONSTANTS; } static void st_destroy_context_priv(struct st_context *st, bool destroy_pipe) { uint shader, i; st_destroy_atoms( st ); st_destroy_draw( st ); -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev