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?


                 } 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.


+   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.


           }
        }
     } 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];
              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?


     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.

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)) {



--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to