On 26/06/17 19:17, Nicolai Hähnle wrote:
On 25.06.2017 03:31, Timothy Arceri wrote:Currently everything is padded to 4 elements. Making the list more flexible will allow us to do uniform packing.This change requires us to remove the existing packing in _mesa_add_typed_unnamed_constant() in order to avoid regressions. This packing will no longer be required once we add full packing support in the folling patches anyway. --- src/compiler/glsl/shader_cache.cpp | 14 ++++++-- src/mesa/drivers/dri/i915/i915_fragprog.c | 9 +++--- src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp | 6 ++-- src/mesa/drivers/dri/r200/r200_vertprog.c | 10 +++--- src/mesa/main/uniform_query.cpp | 14 ++++---- src/mesa/program/ir_to_mesa.cpp | 11 ++++--- src/mesa/program/prog_execute.c | 6 ++-- src/mesa/program/prog_opt_constant_fold.c | 3 +-src/mesa/program/prog_parameter.c | 44 ++++++++++++++++++--------src/mesa/program/prog_parameter.h | 9 ++++-- src/mesa/program/prog_parameter_layout.c | 21 +++++++++--- src/mesa/program/prog_print.c | 4 ++- src/mesa/program/prog_statevars.c | 3 +- src/mesa/program/prog_to_nir.c | 3 +- src/mesa/program/program_parse.y | 2 +- src/mesa/state_tracker/st_atifs_to_tgsi.c | 6 ++-- src/mesa/state_tracker/st_atom_constbuf.c | 5 +-- src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 4 ++- src/mesa/state_tracker/st_mesa_to_tgsi.c | 8 +++-- 19 files changed, 121 insertions(+), 61 deletions(-)diff --git a/src/compiler/glsl/shader_cache.cpp b/src/compiler/glsl/shader_cache.cppindex 1293246..ff81de1 100644 --- a/src/compiler/glsl/shader_cache.cpp +++ b/src/compiler/glsl/shader_cache.cpp@@ -1069,66 +1069,74 @@ read_program_resource_list(struct blob_reader *metadata, (uint8_t *) &prog->data->ProgramResourceList[i].StageReferences,sizeof(prog->data->ProgramResourceList[i].StageReferences)); } } static void write_shader_parameters(struct blob *metadata, struct gl_program_parameter_list *params) { blob_write_uint32(metadata, params->NumParameters); + blob_write_uint32(metadata, params->NumParameterValues); uint32_t i = 0; while (i < params->NumParameters) { struct gl_program_parameter *param = ¶ms->Parameters[i]; blob_write_uint32(metadata, param->Type); blob_write_string(metadata, param->Name); blob_write_uint32(metadata, param->Size); blob_write_uint32(metadata, param->DataType); blob_write_bytes(metadata, param->StateIndexes, sizeof(param->StateIndexes)); i++; } blob_write_bytes(metadata, params->ParameterValues,- sizeof(gl_constant_value) * 4 * params->NumParameters); + sizeof(gl_constant_value) * params->NumParameterValues);+ + blob_write_bytes(metadata, params->ParameterValueOffset, + sizeof(uint32_t) * params->NumParameters); blob_write_uint32(metadata, params->StateFlags); } static void read_shader_parameters(struct blob_reader *metadata, struct gl_program_parameter_list *params) { gl_state_index state_indexes[STATE_LENGTH]; uint32_t i = 0; uint32_t num_parameters = blob_read_uint32(metadata); + uint32_t num_parameters_values = blob_read_uint32(metadata); _mesa_reserve_parameter_storage(params, num_parameters); while (i < num_parameters) {gl_register_file type = (gl_register_file) blob_read_uint32(metadata);const char *name = blob_read_string(metadata); unsigned size = blob_read_uint32(metadata); unsigned data_type = blob_read_uint32(metadata); blob_copy_bytes(metadata, (uint8_t *) state_indexes, sizeof(state_indexes)); _mesa_add_parameter(params, type, name, size, data_type, - NULL, state_indexes); + NULL, state_indexes, false); i++; } blob_copy_bytes(metadata, (uint8_t *) params->ParameterValues,- sizeof(gl_constant_value) * 4 * params->NumParameters);+ sizeof(gl_constant_value) * num_parameters_values); + + blob_copy_bytes(metadata, (uint8_t *) params->ParameterValueOffset, + sizeof(uint32_t) * num_parameters); params->StateFlags = blob_read_uint32(metadata); } static void write_shader_metadata(struct blob *metadata, gl_linked_shader *shader) { assert(shader->Program); struct gl_program *glprog = shader->Program; unsigned i;diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.cindex 2e04319..6493ab9 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -177,25 +177,26 @@ src_vector(struct i915_fragment_program *p, i915_program_error(p, "Bad source->Index: %d", source->Index); return 0; } break; /* Various paramters and env values. All emitted to * hardware as program constants. */ case PROGRAM_CONSTANT: case PROGRAM_STATE_VAR: - case PROGRAM_UNIFORM: - src = i915_emit_param4fv(p, - &program->Parameters->ParameterValues[source->Index][0].f); + case PROGRAM_UNIFORM: { + struct gl_program_parameter_list *params = program->Parameters; + unsigned offset = params->ParameterValueOffset[source->Index]; + src = i915_emit_param4fv(p, ¶ms->ParameterValues[offset].f); break; - + } default: i915_program_error(p, "Bad source->File: %d", source->File); return 0; } src = swizzle(src, GET_SWZ(source->Swizzle, 0), GET_SWZ(source->Swizzle, 1),GET_SWZ(source->Swizzle, 2), GET_SWZ(source->Swizzle, 3)); diff --git a/src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp b/src/mesa/drivers/dri/i965/brw_nir_uniforms.cppindex f0bccac..c23c961 100644 --- a/src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp +++ b/src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp@@ -39,35 +39,36 @@ brw_nir_setup_glsl_builtin_uniform(nir_variable *var,* get the same index back here. */ int index = _mesa_add_state_reference(prog->Parameters, (gl_state_index *)slots[i].tokens);/* Add each of the unique swizzles of the element as a parameter.* This'll end up matching the expected layout of the * array/matrix/structure we're trying to fill in. */ int last_swiz = -1; + unsigned offset = prog->Parameters->ParameterValueOffset[index]; for (unsigned j = 0; j < 4; j++) { int swiz = GET_SWZ(slots[i].swizzle, j);/* If we hit a pair of identical swizzles, this means we've hit the * end of the builtin variable. In scalar mode, we should just quit * and move on to the next one. In vec4, we need to continue and pad* it out to 4 components. */ if (swiz == last_swiz && is_scalar) break; last_swiz = swiz; stage_prog_data->param[uniform_index++] = - &prog->Parameters->ParameterValues[index][swiz]; + &prog->Parameters->ParameterValues[offset + swiz]; } } } static void setup_vec4_uniform_value(const gl_constant_value **params, const gl_constant_value *values, unsigned n) { static const gl_constant_value zero = { 0 };@@ -216,19 +217,20 @@ brw_nir_setup_arb_uniforms(nir_shader *shader, struct gl_program *prog,assert(shader->uniforms.length() <= 2); for (unsigned p = 0; p < plist->NumParameters; p++) { /* Parameters should be either vec4 uniforms or single component* constants; matrices and other larger types should have been broken* down earlier. */ assert(plist->Parameters[p].Size <= 4); unsigned i; + unsigned o = plist->ParameterValueOffset[p]; for (i = 0; i < plist->Parameters[p].Size; i++) {- stage_prog_data->param[4 * p + i] = &plist->ParameterValues[p][i]; + stage_prog_data->param[4 * p + i] = &plist->ParameterValues[o + i];} for (; i < 4; i++) { static const gl_constant_value zero = { 0.0 }; stage_prog_data->param[4 * p + i] = &zero; } } }diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.cindex bb85503..5385b19 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c@@ -113,28 +113,30 @@ static GLboolean r200VertexProgUpdateParams(struct gl_context *ctx, struct r200_assert(mesa_vp->Parameters); _mesa_load_state_parameters(ctx, mesa_vp->Parameters); paramList = mesa_vp->Parameters; if(paramList->NumParameters > R200_VSF_MAX_PARAM){ fprintf(stderr, "%s:Params exhausted\n", __func__); return GL_FALSE; } for(pi = 0; pi < paramList->NumParameters; pi++) { + unsigned pvo = paramList->ParameterValueOffset[pi]; + switch(paramList->Parameters[pi].Type) { case PROGRAM_STATE_VAR: //fprintf(stderr, "%s", vp->Parameters->Parameters[pi].Name); case PROGRAM_CONSTANT: - *fcmd++ = paramList->ParameterValues[pi][0].f; - *fcmd++ = paramList->ParameterValues[pi][1].f; - *fcmd++ = paramList->ParameterValues[pi][2].f; - *fcmd++ = paramList->ParameterValues[pi][3].f; + *fcmd++ = paramList->ParameterValues[pvo + 0].f; + *fcmd++ = paramList->ParameterValues[pvo + 1].f; + *fcmd++ = paramList->ParameterValues[pvo + 2].f; + *fcmd++ = paramList->ParameterValues[pvo + 3].f; break; default: _mesa_problem(NULL, "Bad param type in %s", __func__); break; } if (pi == 95) { fcmd = (GLfloat *)&rmesa->hw.vpp[1].cmd[VPP_CMD_0 + 1]; } }/* hack up the cmd_size so not the whole state atom is emitted always. */ diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cppindex 9683fa8..5755b40 100644 --- a/src/mesa/main/uniform_query.cpp +++ b/src/mesa/main/uniform_query.cpp@@ -715,27 +715,29 @@ log_program_parameters(const struct gl_shader_program *shProg){ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (shProg->_LinkedShaders[i] == NULL) continue;const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program;printf("Program %d %s shader parameters:\n", shProg->Name, _mesa_shader_stage_to_string(i)); for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) { - printf("%s: %p %f %f %f %f\n", + unsigned pvo = prog->Parameters->ParameterValueOffset[j]; + printf("%s: %u %p %f %f %f %f\n", prog->Parameters->Parameters[j].Name, - prog->Parameters->ParameterValues[j], - prog->Parameters->ParameterValues[j][0].f, - prog->Parameters->ParameterValues[j][1].f, - prog->Parameters->ParameterValues[j][2].f, - prog->Parameters->ParameterValues[j][3].f); + pvo, + prog->Parameters->ParameterValues + pvo, + prog->Parameters->ParameterValues[pvo].f, + prog->Parameters->ParameterValues[pvo + 1].f, + prog->Parameters->ParameterValues[pvo + 2].f, + prog->Parameters->ParameterValues[pvo + 3].f); } } fflush(stdout); } #endif /*** Propagate some values from uniform backing storage to driver storage* * Values propagated from uniform backing storage to driver storagediff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cppindex dd757c6..3fb5a24 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp@@ -2461,21 +2461,21 @@ add_uniform_to_shader::visit_field(const glsl_type *type, const char *name,bool is_dual_slot = type->without_array()->is_dual_slot(); if (is_dual_slot) num_params *= 2; _mesa_reserve_parameter_storage(params, num_params); index = params->NumParameters; for (unsigned i = 0; i < num_params; i++) { unsigned comps = 4; _mesa_add_parameter(params, PROGRAM_UNIFORM, name, comps, - type->gl_type, NULL, NULL); + type->gl_type, NULL, NULL, false); } }/* The first part of the uniform that's processed determines the base* location of the whole uniform (for structures). */ if (this->idx < 0) this->idx = index; }@@ -2586,44 +2586,45 @@ _mesa_associate_uniform_storage(struct gl_context *ctx,case GLSL_TYPE_ARRAY: case GLSL_TYPE_VOID: case GLSL_TYPE_STRUCT: case GLSL_TYPE_ERROR: case GLSL_TYPE_INTERFACE: case GLSL_TYPE_FUNCTION: assert(!"Should not get here."); break; }- _mesa_uniform_attach_driver_storage(storage, dmul * columns, dmul,+ unsigned pvo = params->ParameterValueOffset[i];+ _mesa_uniform_attach_driver_storage(storage, dmul * columns, dmul,Spurious whitespace change.format, - ¶ms->ParameterValues[i]); + ¶ms->ParameterValues[pvo]);/* When a bindless sampler/image is bound to a texture/image unit, we * have to overwrite the constant value by the resident handle * directly in the constant buffer before the next draw. One solution* is to keep track a pointer to the base of the data. */ if (storage->is_bindless && (prog->sh.NumBindlessSamplers || prog->sh.NumBindlessImages)) {unsigned array_elements = MAX2(1, storage->array_elements);for (unsigned j = 0; j < array_elements; ++j) { unsigned unit = storage->opaque[shader_type].index + j; if (storage->type->without_array()->is_sampler()) {assert(unit >= 0 && unit < prog->sh.NumBindlessSamplers);prog->sh.BindlessSamplers[unit].data = - ¶ms->ParameterValues[i] + j; + ¶ms->ParameterValues[pvo] + j;Should this be 4 * j?
I think it should be 2 * j but yes I think this is wrong. You might have found why bindless was hanging my machine. Thanks!
} else if (storage->type->without_array()->is_image()) { assert(unit >= 0 && unit < prog->sh.NumBindlessImages);prog->sh.BindlessImages[unit].data = - ¶ms->ParameterValues[i] + j; + ¶ms->ParameterValues[pvo] + j;Dito.} } }/* After attaching the driver's storage to the uniform, propagate any * data from the linker's backing store. This will cause values from* initializers in the source code to be copied over. */ if (propagate_to_storage) {unsigned array_elements = MAX2(1, storage->array_elements); diff --git a/src/mesa/program/prog_execute.c b/src/mesa/program/prog_execute.cindex 1268476..5cea484 100644 --- a/src/mesa/program/prog_execute.c +++ b/src/mesa/program/prog_execute.c@@ -110,25 +110,27 @@ get_src_register_pointer(const struct prog_src_register *source,case PROGRAM_OUTPUT: if (reg >= MAX_PROGRAM_OUTPUTS) return ZeroVec; return machine->Outputs[reg]; case PROGRAM_STATE_VAR: /* Fallthrough */ case PROGRAM_CONSTANT: /* Fallthrough */ - case PROGRAM_UNIFORM: + case PROGRAM_UNIFORM: { if (reg >= (GLint) prog->Parameters->NumParameters) return ZeroVec; - return (GLfloat *) prog->Parameters->ParameterValues[reg]; + unsigned pvo = prog->Parameters->ParameterValueOffset[reg]; + return (GLfloat *) prog->Parameters->ParameterValues + pvo; + } case PROGRAM_SYSTEM_VALUE: assert(reg < (GLint) ARRAY_SIZE(machine->SystemValues)); return machine->SystemValues[reg]; default: _mesa_problem(NULL, "Invalid src register file %d in get_src_register_pointer()", source->File); return ZeroVec; }diff --git a/src/mesa/program/prog_opt_constant_fold.c b/src/mesa/program/prog_opt_constant_fold.cindex ba4a954..638bdbd 100644 --- a/src/mesa/program/prog_opt_constant_fold.c +++ b/src/mesa/program/prog_opt_constant_fold.c @@ -83,22 +83,23 @@ src_regs_are_same(const struct prog_src_register *a, && (a->Index == b->Index) && (a->Swizzle == b->Swizzle) && (a->Negate == b->Negate) && (a->RelAddr == 0) && (b->RelAddr == 0); } static voidget_value(struct gl_program *prog, struct prog_src_register *r, float *data){ + unsigned pvo = prog->Parameters->ParameterValueOffset[r->Index]; const gl_constant_value *const value = - prog->Parameters->ParameterValues[r->Index]; + prog->Parameters->ParameterValues + pvo; data[0] = value[GET_SWZ(r->Swizzle, 0)].f; data[1] = value[GET_SWZ(r->Swizzle, 1)].f; data[2] = value[GET_SWZ(r->Swizzle, 2)].f; data[3] = value[GET_SWZ(r->Swizzle, 3)].f; if (r->Negate & 0x01) { data[0] = -data[0]; }diff --git a/src/mesa/program/prog_parameter.c b/src/mesa/program/prog_parameter.cindex 81609f5..a677493 100644 --- a/src/mesa/program/prog_parameter.c +++ b/src/mesa/program/prog_parameter.c@@ -59,58 +59,60 @@ lookup_parameter_constant(const struct gl_program_parameter_list *list,assert(vSize >= 1); assert(vSize <= 4); if (!list) { *posOut = -1; return GL_FALSE; } for (i = 0; i < list->NumParameters; i++) { if (list->Parameters[i].Type == PROGRAM_CONSTANT) { + unsigned offset = list->ParameterValueOffset[i]; + if (!swizzleOut) { /* swizzle not allowed */ GLuint j, match = 0; for (j = 0; j < vSize; j++) { - if (v[j].u == list->ParameterValues[i][j].u) + if (v[j].u == list->ParameterValues[offset + j].u) match++; } if (match == vSize) { *posOut = i; return GL_TRUE; } } else { /* try matching w/ swizzle */ if (vSize == 1) { /* look for v[0] anywhere within float[4] value */ GLuint j; for (j = 0; j < list->Parameters[i].Size; j++) { - if (list->ParameterValues[i][j].u == v[0].u) { + if (list->ParameterValues[offset + j].u == v[0].u) { /* found it */ *posOut = i; *swizzleOut = MAKE_SWIZZLE4(j, j, j, j); return GL_TRUE; } } } else if (vSize <= list->Parameters[i].Size) {/* see if we can match this constant (with a swizzle) */GLuint swz[4]; GLuint match = 0, j, k; for (j = 0; j < vSize; j++) { - if (v[j].u == list->ParameterValues[i][j].u) { + if (v[j].u == list->ParameterValues[offset + j].u) { swz[j] = j; match++; } else { for (k = 0; k < list->Parameters[i].Size; k++) { - if (v[j].u == list->ParameterValues[i][k].u) {+ if (v[j].u == list->ParameterValues[offset + k].u) {swz[j] = k; match++; break; } } } } /* smear last value to remaining positions */ for (; j < 4; j++) swz[j] = swz[j-1]; @@ -142,21 +144,23 @@ _mesa_new_parameter_list_sized(unsigned size) { struct gl_program_parameter_list *p = _mesa_new_parameter_list(); if ((p != NULL) && (size != 0)) { p->Size = size; /* alloc arrays */ p->Parameters = (struct gl_program_parameter *) calloc(size, sizeof(struct gl_program_parameter)); - p->ParameterValues = (gl_constant_value (*)[4])+ p->ParameterValueOffset = (unsigned *) calloc(size, sizeof(unsigned));+ + p->ParameterValues = (gl_constant_value *) _mesa_align_malloc(size * 4 *sizeof(gl_constant_value), 16);if ((p->Parameters == NULL) || (p->ParameterValues == NULL)) {free(p->Parameters); _mesa_align_free(p->ParameterValues); free(p); p = NULL; } }@@ -196,21 +200,25 @@ _mesa_reserve_parameter_storage(struct gl_program_parameter_list *paramList,if (oldNum + reserve_slots > paramList->Size) { /* Need to grow the parameter list array (alloc some extra) */ paramList->Size = paramList->Size + 4 * reserve_slots; /* realloc arrays */ paramList->Parameters = realloc(paramList->Parameters,paramList->Size * sizeof(struct gl_program_parameter));- paramList->ParameterValues = (gl_constant_value (*)[4]) + paramList->ParameterValueOffset = + realloc(paramList->ParameterValueOffset, + paramList->Size * sizeof(unsigned)); + + paramList->ParameterValues = (gl_constant_value *) _mesa_align_realloc(paramList->ParameterValues, /* old buf */oldNum * 4 * sizeof(gl_constant_value),/* old sz */paramList->Size*4*sizeof(gl_constant_value),/*new*/ 16); } } /** * Add a new parameter to a parameter list.@@ -225,59 +233,66 @@ _mesa_reserve_parameter_storage(struct gl_program_parameter_list *paramList, * \param datatype GL_FLOAT, GL_FLOAT_VECx, GL_INT, GL_INT_VECx or GL_NONE. * \param values initial parameter value, up to 4 gl_constant_values, or NULL* \param state state indexes, or NULL* \return index of new parameter in the list, or -1 if error (out of mem)*/ GLint _mesa_add_parameter(struct gl_program_parameter_list *paramList, gl_register_file type, const char *name, GLuint size, GLenum datatype, const gl_constant_value *values, - const gl_state_index state[STATE_LENGTH]) + const gl_state_index state[STATE_LENGTH], + bool pad_and_align) { assert(0 < size && size <=4); const GLuint oldNum = paramList->NumParameters; + unsigned oldValNum = pad_and_align ?+ align(paramList->NumParameterValues, 4) : paramList->NumParameterValues;_mesa_reserve_parameter_storage(paramList, 1); - if (!paramList->Parameters || + if (!paramList->Parameters || !paramList->ParameterValueOffset || !paramList->ParameterValues) { /* out of memory */ paramList->NumParameters = 0; paramList->Size = 0; return -1; } paramList->NumParameters = oldNum + 1; + unsigned pad = pad_and_align && size < 4 ? align(size, 4) : size;Simplify to just pad_and_align ? align(size, 4) : size.
Yeah this was required before I wrote the proceeding patch i.e when we still had to deal with doubles. Will change.
+ paramList->NumParameterValues = oldValNum + pad; + memset(¶mList->Parameters[oldNum], 0, sizeof(struct gl_program_parameter)); struct gl_program_parameter *p = paramList->Parameters + oldNum; p->Name = strdup(name ? name : ""); p->Type = type; p->Size = size; p->DataType = datatype; + paramList->ParameterValueOffset[oldNum] = oldValNum; if (values) { if (size >= 4) { - COPY_4V(paramList->ParameterValues[oldNum], values); + COPY_4V(paramList->ParameterValues + oldValNum, values); } else { /* copy 1, 2 or 3 values */ assert(size < 4); for (unsigned j = 0; j < size; j++) { - paramList->ParameterValues[oldNum][j].f = values[j].f; + paramList->ParameterValues[oldValNum + j].f = values[j].f;I think you may want to 0-initialize the padding space here (when it exists) -- otherwise you may get valgrind errors in the disk cache.
Sure.
} } } else { for (unsigned j = 0; j < 4; j++) { - paramList->ParameterValues[oldNum][j].f = 0; + paramList->ParameterValues[oldValNum + j].f = 0; } } if (state) { for (unsigned i = 0; i < STATE_LENGTH; i++) paramList->Parameters[oldNum].StateIndexes[i] = state[i]; } return (GLint) oldNum; }@@ -309,35 +324,36 @@ _mesa_add_typed_unnamed_constant(struct gl_program_parameter_list *paramList,return pos; } /* Look for empty space in an already unnamed constant parameter * to add this constant. This will only work for single-element * constants because we rely on smearing (i.e. .yyyy or .zzzz). */ if (size == 1 && swizzleOut) { for (pos = 0; pos < (GLint) paramList->NumParameters; pos++) { struct gl_program_parameter *p = paramList->Parameters + pos; + unsigned offset = paramList->ParameterValueOffset[pos]; if (p->Type == PROGRAM_CONSTANT && p->Size + size <= 4) { /* ok, found room */ - gl_constant_value *pVal = paramList->ParameterValues[pos];+ gl_constant_value *pVal = paramList->ParameterValues + offset;GLuint swz = p->Size; /* 1, 2 or 3 for Y, Z, W */ pVal[p->Size] = values[0]; slack p->Size++; *swizzleOut = MAKE_SWIZZLE4(swz, swz, swz, swz); return pos; } } } /* add a new parameter to store this constant */ pos = _mesa_add_parameter(paramList, PROGRAM_CONSTANT, NULL, - size, datatype, values, NULL); + size, datatype, values, NULL, size < 4);Why not just "true" as the pad_and_align parameter?
Sure, not much diff either way will change :)
if (pos >= 0 && swizzleOut) { if (size == 1) *swizzleOut = SWIZZLE_XXXX; else *swizzleOut = SWIZZLE_NOOP; } return pos; }@@ -362,18 +378,18 @@ _mesa_add_state_reference(struct gl_program_parameter_list *paramList, for (index = 0; index < (GLint) paramList->NumParameters; index++) {if (!memcmp(paramList->Parameters[index].StateIndexes,stateTokens, STATE_LENGTH * sizeof(gl_state_index))) {return index; } } name = _mesa_program_state_string(stateTokens); index = _mesa_add_parameter(paramList, PROGRAM_STATE_VAR, name, size, GL_NONE, - NULL, (gl_state_index *) stateTokens);+ NULL, (gl_state_index *) stateTokens, false);I'd prefer a "true" here as the pad_and_align parameter. It doesn't really matter since size == 4 is hardcoded, but it makes the compatibility requirement with non-packing drivers more obvious.Actually, I'd like this to be changed at all call sites of _mesa_add_parameter, except perhaps in the disk cache where the offsets are overwritten anyway.
Sure makes sense :)
Cheers, NicolaiparamList->StateFlags |= _mesa_program_state_flags(stateTokens);/* free name string here since we duplicated it in add_parameter() */free(name); return index; }diff --git a/src/mesa/program/prog_parameter.h b/src/mesa/program/prog_parameter.hindex f50e99c..e5f3b39 100644 --- a/src/mesa/program/prog_parameter.h +++ b/src/mesa/program/prog_parameter.h @@ -75,23 +75,25 @@ struct gl_program_parameter gl_state_index StateIndexes[STATE_LENGTH]; }; /** * List of gl_program_parameter instances. */ struct gl_program_parameter_list {GLuint Size; /**< allocated size of Parameters, ParameterValues */- GLuint NumParameters; /**< number of parameters in arrays */ + GLuint NumParameters; /**< number of used parameters in array */+ unsigned NumParameterValues; /**< number of used parameter values array */struct gl_program_parameter *Parameters; /**< Array [Size] */- gl_constant_value (*ParameterValues)[4]; /**< Array [Size] of constant[4] */+ unsigned *ParameterValueOffset;+ gl_constant_value *ParameterValues; /**< Array [Size] of gl_constant_value */ GLbitfield StateFlags; /**< _NEW_* flags indicating which state changesmight invalidate ParameterValues[] */ }; extern struct gl_program_parameter_list * _mesa_new_parameter_list(void); extern struct gl_program_parameter_list * _mesa_new_parameter_list_sized(unsigned size);@@ -101,21 +103,22 @@ _mesa_free_parameter_list(struct gl_program_parameter_list *paramList);extern void_mesa_reserve_parameter_storage(struct gl_program_parameter_list *paramList,unsigned reserve_slots); extern GLint _mesa_add_parameter(struct gl_program_parameter_list *paramList, gl_register_file type, const char *name, GLuint size, GLenum datatype, const gl_constant_value *values, - const gl_state_index state[STATE_LENGTH]); + const gl_state_index state[STATE_LENGTH], + bool pad_and_align); extern GLint_mesa_add_typed_unnamed_constant(struct gl_program_parameter_list *paramList, const gl_constant_value values[4], GLuint size,GLenum datatype, GLuint *swizzleOut); static inline GLint_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, const gl_constant_value values[4], GLuint size,GLuint *swizzleOut)diff --git a/src/mesa/program/prog_parameter_layout.c b/src/mesa/program/prog_parameter_layout.cindex 282a367..d28a667 100644 --- a/src/mesa/program/prog_parameter_layout.c +++ b/src/mesa/program/prog_parameter_layout.c@@ -85,24 +85,34 @@ copy_indirect_accessed_array(struct gl_program_parameter_list *src, if (memcmp(dst->Parameters[j].StateIndexes, curr->StateIndexes,sizeof(curr->StateIndexes)) == 0) { return -1; } } } assert(j == dst->NumParameters); /* copy src parameter [i] to dest parameter [j] */ - memcpy(& dst->Parameters[j], curr, + memcpy(&dst->Parameters[j], curr, sizeof(dst->Parameters[j])); - memcpy(dst->ParameterValues[j], src->ParameterValues[i], - sizeof(GLfloat) * 4); + + dst->ParameterValueOffset[j] = dst->NumParameterValues; + + gl_constant_value *pv_dst = + dst->ParameterValues + dst->ParameterValueOffset[j]; + gl_constant_value *pv_src = + src->ParameterValues + src->ParameterValueOffset[i]; + + memcpy(pv_dst, pv_src, MIN2(src->Parameters[i].Size, 4) * + sizeof(GLfloat)); + dst->NumParameterValues += MIN2(dst->Parameters[j].Size, 4); +/* Pointer to the string name was copied. Null-out src param name* to prevent double free later. */ curr->Name = NULL; dst->NumParameters++; } return base;@@ -176,22 +186,23 @@ _mesa_layout_parameters(struct asm_parser_state *state)if ((inst->SrcReg[i].Base.File <= PROGRAM_OUTPUT) || (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) { continue; } inst->Base.SrcReg[i] = inst->SrcReg[i].Base; p = & state->prog->Parameters->Parameters[idx]; switch (p->Type) { case PROGRAM_CONSTANT: { - const gl_constant_value *const v = - state->prog->Parameters->ParameterValues[idx];+ unsigned pvo = state->prog->Parameters->ParameterValueOffset[idx];+ const gl_constant_value *const v = + state->prog->Parameters->ParameterValues + pvo; inst->Base.SrcReg[i].Index = _mesa_add_unnamed_constant(layout, v, p->Size, & swizzle); inst->Base.SrcReg[i].Swizzle =_mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle);break; } case PROGRAM_STATE_VAR:diff --git a/src/mesa/program/prog_print.c b/src/mesa/program/prog_print.cindex 4f85d14..3bc69fd 100644 --- a/src/mesa/program/prog_print.c +++ b/src/mesa/program/prog_print.c @@ -913,21 +913,23 @@ _mesa_fprint_parameter_list(FILE *f, GLuint i; if (!list) return; if (0) fprintf(f, "param list %p\n", (void *) list); fprintf(f, "dirty state flags: 0x%x\n", list->StateFlags); for (i = 0; i < list->NumParameters; i++){ struct gl_program_parameter *param = list->Parameters + i; - const GLfloat *v = (GLfloat *) list->ParameterValues[i]; + unsigned pvo = list->ParameterValueOffset[i]; + const GLfloat *v = (GLfloat *) list->ParameterValues + pvo; + fprintf(f, "param[%d] sz=%d %s %s = {%.3g, %.3g, %.3g, %.3g}", i, param->Size, _mesa_register_file_name(list->Parameters[i].Type), param->Name, v[0], v[1], v[2], v[3]); fprintf(f, "\n"); } } /**diff --git a/src/mesa/program/prog_statevars.c b/src/mesa/program/prog_statevars.cindex 91178e3..db370fe 100644 --- a/src/mesa/program/prog_statevars.c +++ b/src/mesa/program/prog_statevars.c @@ -1068,16 +1068,17 @@ 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]; _mesa_fetch_state(ctx, paramList->Parameters[i].StateIndexes, - ¶mList->ParameterValues[i][0]); + paramList->ParameterValues + pvo); } } }diff --git a/src/mesa/program/prog_to_nir.c b/src/mesa/program/prog_to_nir.cindex 851b3f2..b49616c 100644 --- a/src/mesa/program/prog_to_nir.c +++ b/src/mesa/program/prog_to_nir.c@@ -154,21 +154,22 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)* constants. */ struct gl_program_parameter_list *plist = c->prog->Parameters; gl_register_file file = prog_src->RelAddr ? prog_src->File : plist->Parameters[prog_src->Index].Type; switch (file) { case PROGRAM_CONSTANT: if ((c->prog->arb.IndirectRegisterFiles & (1 << PROGRAM_CONSTANT)) == 0) {- float *v = (float *) plist->ParameterValues[prog_src->Index]; + unsigned pvo = plist->ParameterValueOffset[prog_src->Index];+ float *v = (float *) plist->ParameterValues + pvo;src.src = nir_src_for_ssa(nir_imm_vec4(b, v[0], v[1], v[2], v[3]));break; } /* FALLTHROUGH */ case PROGRAM_STATE_VAR: { assert(c->parameters != NULL); nir_intrinsic_instr *load =nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var);nir_ssa_dest_init(&load->instr, &load->dest, 4, 32, NULL);diff --git a/src/mesa/program/program_parse.y b/src/mesa/program/program_parse.yindex f3adea6..e18637d 100644 --- a/src/mesa/program/program_parse.y +++ b/src/mesa/program/program_parse.y@@ -2285,21 +2285,21 @@ declare_variable(struct asm_parser_state *state, char *name, enum asm_type t, int add_state_reference(struct gl_program_parameter_list *param_list,const gl_state_index tokens[STATE_LENGTH]) { const GLuint size = 4; /* XXX fix */ char *name; GLint index; name = _mesa_program_state_string(tokens); index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name, - size, GL_NONE, NULL, tokens); + size, GL_NONE, NULL, tokens, false); param_list->StateFlags |= _mesa_program_state_flags(tokens);/* free name string here since we duplicated it in add_parameter() */free(name); return index; } intdiff --git a/src/mesa/state_tracker/st_atifs_to_tgsi.c b/src/mesa/state_tracker/st_atifs_to_tgsi.cindex 338ced5..34d4378 100644 --- a/src/mesa/state_tracker/st_atifs_to_tgsi.c +++ b/src/mesa/state_tracker/st_atifs_to_tgsi.c @@ -470,29 +470,31 @@ st_translate_atifs_program( */ if (program->Parameters) { t->constants = calloc(program->Parameters->NumParameters, sizeof t->constants[0]); if (t->constants == NULL) { ret = PIPE_ERROR_OUT_OF_MEMORY; goto out; } for (i = 0; i < program->Parameters->NumParameters; i++) { + unsigned pvo = program->Parameters->ParameterValueOffset[i]; + switch (program->Parameters->Parameters[i].Type) { case PROGRAM_STATE_VAR: case PROGRAM_UNIFORM: t->constants[i] = ureg_DECL_constant(ureg, i); break; case PROGRAM_CONSTANT: t->constants[i] = ureg_DECL_immediate(ureg,- (const float*)program->Parameters->ParameterValues[i], + (const float*)program->Parameters->ParameterValues + pvo,4); break; default: break; } } } /* texture samplers */ for (i = 0; i < MAX_NUM_FRAGMENT_REGISTERS_ATI; i++) {@@ -595,21 +597,21 @@ st_init_atifs_prog(struct gl_context *ctx, struct gl_program *prog)} } } } /* we may need fog */ prog->info.inputs_read |= BITFIELD64_BIT(VARYING_SLOT_FOGC); /* we always have the ATI_fs constants, and the fog params */ for (i = 0; i < MAX_NUM_FRAGMENT_CONSTANTS_ATI; i++) { _mesa_add_parameter(prog->Parameters, PROGRAM_UNIFORM, - NULL, 4, GL_FLOAT, NULL, NULL); + NULL, 4, GL_FLOAT, NULL, NULL, false); } _mesa_add_state_reference(prog->Parameters, fog_params_state); _mesa_add_state_reference(prog->Parameters, fog_color); prog->arb.NumInstructions = 0;prog->arb.NumTemporaries = MAX_NUM_FRAGMENT_REGISTERS_ATI + 3; /* 3 input temps for arith ops */ prog->arb.NumParameters = MAX_NUM_FRAGMENT_CONSTANTS_ATI + 2; /* 2 state variables for fog */}diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.cindex e4b5851..7f17546 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c@@ -64,25 +64,26 @@ void st_upload_constants(struct st_context *st, struct gl_program *prog)shader_type == PIPE_SHADER_TESS_CTRL || shader_type == PIPE_SHADER_TESS_EVAL || shader_type == PIPE_SHADER_COMPUTE); /* update the ATI constants before rendering */ if (shader_type == PIPE_SHADER_FRAGMENT && st->fp->ati_fs) { struct ati_fragment_shader *ati_fs = st->fp->ati_fs; unsigned c; for (c = 0; c < MAX_NUM_FRAGMENT_CONSTANTS_ATI; c++) { + unsigned offset = params->ParameterValueOffset[c]; if (ati_fs->LocalConstDef & (1 << c)) - memcpy(params->ParameterValues[c], + memcpy(params->ParameterValues + offset, ati_fs->Constants[c], sizeof(GLfloat) * 4); else - memcpy(params->ParameterValues[c], + memcpy(params->ParameterValues + offset, st->ctx->ATIFragmentShader.GlobalConstants[c], sizeof(GLfloat) * 4); } }/* Make all bindless samplers/images bound texture/image units resident in* the context. */ st_make_bound_samplers_resident(st, prog); st_make_bound_images_resident(st, prog);diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cppindex 7852941..1998852 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -6631,38 +6631,40 @@ st_translate_program( if (proginfo->Parameters) { t->constants = (struct ureg_src *)calloc(proginfo->Parameters->NumParameters, sizeof(t->constants[0]));if (t->constants == NULL) { ret = PIPE_ERROR_OUT_OF_MEMORY; goto out; } t->num_constants = proginfo->Parameters->NumParameters; for (i = 0; i < proginfo->Parameters->NumParameters; i++) { + unsigned pvo = proginfo->Parameters->ParameterValueOffset[i]; + switch (proginfo->Parameters->Parameters[i].Type) { case PROGRAM_STATE_VAR: case PROGRAM_UNIFORM: t->constants[i] = ureg_DECL_constant(ureg, i); break;/* Emit immediates for PROGRAM_CONSTANT only when there's no indirect* addressing of the const buffer. * FIXME: Be smarter and recognize param arrays: * indirect addressing is only valid within the referenced * array. */ case PROGRAM_CONSTANT: if (program->indirect_addr_consts) t->constants[i] = ureg_DECL_constant(ureg, i); else t->constants[i] = emit_immediate(t, - proginfo->Parameters->ParameterValues[i], + proginfo->Parameters->ParameterValues + pvo, proginfo->Parameters->Parameters[i].DataType, 4); break; default: break; } } } for (i = 0; i < proginfo->info.num_ubos; i++) {diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.cindex 984ff92..640e175 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -991,40 +991,42 @@ st_translate_mesa_program( */ if (program->Parameters) { t->constants = calloc( program->Parameters->NumParameters, sizeof t->constants[0] ); if (t->constants == NULL) { ret = PIPE_ERROR_OUT_OF_MEMORY; goto out; } for (i = 0; i < program->Parameters->NumParameters; i++) { + unsigned pvo = program->Parameters->ParameterValueOffset[i]; + switch (program->Parameters->Parameters[i].Type) { case PROGRAM_STATE_VAR: case PROGRAM_UNIFORM: t->constants[i] = ureg_DECL_constant( ureg, i ); break;/* Emit immediates only when there's no indirect addressing of* the const buffer. * FIXME: Be smarter and recognize param arrays: * indirect addressing is only valid within the referenced * array. */ case PROGRAM_CONSTANT:if (program->arb.IndirectRegisterFiles & PROGRAM_ANY_CONST)t->constants[i] = ureg_DECL_constant( ureg, i ); else t->constants[i] = - ureg_DECL_immediate( ureg,- (const float*) program->Parameters->ParameterValues[i],- 4 ); + ureg_DECL_immediate(ureg,+ (const float*) program->Parameters->ParameterValues + pvo,+ 4); break; default: break; } } } /* texture samplers */for (i = 0; i < ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; i++) {if (program->SamplersUsed & (1u << i)) {
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev