diff --git a/src/compiler/glsl/serialize.cpp b/src/compiler/glsl/serialize.cpp index fefef8ff28a..08b2040f65d 100644 --- a/src/compiler/glsl/serialize.cpp +++ b/src/compiler/glsl/serialize.cpp @@ -1044,6 +1044,8 @@ write_shader_parameters(struct blob *metadata, sizeof(gl_constant_value) * params->NumParameterValues); blob_write_uint32(metadata, params->StateFlags); + blob_write_uint32(metadata, params->LastUniformIndex); + blob_write_uint32(metadata, params->FirstStateVarIndex); } static void @@ -1078,6 +1080,8 @@ read_shader_parameters(struct blob_reader *metadata, sizeof(gl_constant_value) * params->NumParameterValues); params->StateFlags = blob_read_uint32(metadata); + params->LastUniformIndex = blob_read_uint32(metadata); + params->FirstStateVarIndex = blob_read_uint32(metadata); } static void diff --git a/src/mesa/program/prog_parameter.c b/src/mesa/program/prog_parameter.c index 66f00a9e2c6..803e0dbc01c 100644 --- a/src/mesa/program/prog_parameter.c +++ b/src/mesa/program/prog_parameter.c @@ -135,7 +135,14 @@ lookup_parameter_constant(const struct gl_program_parameter_list *list, struct gl_program_parameter_list * _mesa_new_parameter_list(void) { - return CALLOC_STRUCT(gl_program_parameter_list); + struct gl_program_parameter_list *list = + CALLOC_STRUCT(gl_program_parameter_list); + if (!list) + return NULL; + + list->LastUniformIndex = -1; + list->FirstStateVarIndex = INT_MAX; + return list; } @@ -262,7 +269,7 @@ _mesa_add_parameter(struct gl_program_parameter_list *paramList, bool pad_and_align) { assert(0 < size); - const GLuint oldNum = paramList->NumParameters; + const int oldNum = paramList->NumParameters; unsigned oldValNum = paramList->NumParameterValues; const unsigned padded_size = pad_and_align ? align(size, 4) : size; @@ -325,6 +332,16 @@ _mesa_add_parameter(struct gl_program_parameter_list *paramList, paramList->Parameters[oldNum].StateIndexes[i] = state[i]; } + if (type == PROGRAM_UNIFORM || type == PROGRAM_CONSTANT) { + paramList->LastUniformIndex = + MAX2(paramList->LastUniformIndex, oldNum); + } else if (type == PROGRAM_STATE_VAR) { + paramList->FirstStateVarIndex = + MIN2(paramList->FirstStateVarIndex, oldNum); + } else { + unreachable("invalid parameter type"); + } + return (GLint) oldNum; } @@ -432,3 +449,19 @@ _mesa_add_state_reference(struct gl_program_parameter_list *paramList, { return _mesa_add_sized_state_reference(paramList, stateTokens, 4, true); } + +void +_mesa_recompute_parameter_bounds(struct gl_program_parameter_list *list) +{ + list->FirstStateVarIndex = INT_MAX; + list->LastUniformIndex = -1; + + for (int i = 0; i < (int)list->NumParameters; i++) { + if (list->Parameters[i].Type == PROGRAM_STATE_VAR) { + list->FirstStateVarIndex = MIN2(list->FirstStateVarIndex, i); + } else { + list->LastUniformIndex = MAX2(list->LastUniformIndex, i); + } + } + assert(list->LastUniformIndex < list->FirstStateVarIndex); +} diff --git a/src/mesa/program/prog_parameter.h b/src/mesa/program/prog_parameter.h index 85b8cf39523..edb4b69a151 100644 --- a/src/mesa/program/prog_parameter.h +++ b/src/mesa/program/prog_parameter.h @@ -142,6 +142,12 @@ struct gl_program_parameter_list GLbitfield StateFlags; /**< _NEW_* flags indicating which state changes might invalidate ParameterValues[] */ bool DisallowRealloc; + + /* Parameters are optionally sorted as follows. Uniforms and constants + * are first, then state vars. + */ + int LastUniformIndex; + int FirstStateVarIndex; }; @@ -242,6 +248,9 @@ _mesa_gl_datatype_is_64bit(GLenum datatype) } } +void +_mesa_recompute_parameter_bounds(struct gl_program_parameter_list *list); + #ifdef __cplusplus } #endif diff --git a/src/mesa/program/prog_parameter_layout.c b/src/mesa/program/prog_parameter_layout.c index 0b75c899bd0..91ccb10c3ec 100644 --- a/src/mesa/program/prog_parameter_layout.c +++ b/src/mesa/program/prog_parameter_layout.c @@ -231,6 +231,8 @@ _mesa_layout_parameters(struct asm_parser_state *state) } } + _mesa_recompute_parameter_bounds(layout); + layout->StateFlags = state->prog->Parameters->StateFlags; _mesa_free_parameter_list(state->prog->Parameters); state->prog->Parameters = layout; diff --git a/src/mesa/program/prog_statevars.c b/src/mesa/program/prog_statevars.c index f00081c1fe1..7e496351733 100644 --- a/src/mesa/program/prog_statevars.c +++ b/src/mesa/program/prog_statevars.c @@ -1208,16 +1208,15 @@ void _mesa_load_state_parameters(struct gl_context *ctx, struct gl_program_parameter_list *paramList) { - GLuint i; - if (!paramList) return; - for (i = 0; i < paramList->NumParameters; i++) { - if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) { - unsigned pvo = paramList->ParameterValueOffset[i]; - fetch_state(ctx, paramList->Parameters[i].StateIndexes, - paramList->ParameterValues + pvo); - } + assert(paramList->LastUniformIndex < paramList->FirstStateVarIndex); + int num = paramList->NumParameters; + + for (int i = paramList->FirstStateVarIndex; i < num; i++) { + unsigned pvo = paramList->ParameterValueOffset[i]; + fetch_state(ctx, paramList->Parameters[i].StateIndexes, + paramList->ParameterValues + pvo); } }