[Mesa-dev] [PATCH 03/17] mesa: rework ParameterList to allow packing

Timothy Arceri tarceri at itsqueeze.com
Mon Jun 26 10:46:52 UTC 2017


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.cpp
>> index 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 = &params->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.c
>> index 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, &params->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.cpp
>> index 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.c
>> index 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.cpp
>> index 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 storage
>> diff --git a/src/mesa/program/ir_to_mesa.cpp 
>> b/src/mesa/program/ir_to_mesa.cpp
>> index 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,
>> - &params->ParameterValues[i]);
>> + &params->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 =
>> -                     &params->ParameterValues[i] + j;
>> +                     &params->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 =
>> -                     &params->ParameterValues[i] + j;
>> +                     &params->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.c
>> index 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.c
>> index 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 void
>>   get_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.c
>> index 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(&paramList->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,
> Nicolai
>
>
>>      paramList->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.h
>> index 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 
>> changes
>>                                  might 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.c
>> index 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.c
>> index 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.c
>> index 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,
>> - &paramList->ParameterValues[i][0]);
>> +                           paramList->ParameterValues + pvo);
>>         }
>>      }
>>   }
>> diff --git a/src/mesa/program/prog_to_nir.c 
>> b/src/mesa/program/prog_to_nir.c
>> index 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.y
>> index 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;
>>   }
>>       int
>> diff --git a/src/mesa/state_tracker/st_atifs_to_tgsi.c 
>> b/src/mesa/state_tracker/st_atifs_to_tgsi.c
>> index 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.c
>> index 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.cpp
>> index 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.c
>> index 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)) {
>>
>
>



More information about the mesa-dev mailing list