summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolai Hähnle <nicolai.haehnle@amd.com>2017-06-24 10:14:07 +0200
committerNicolai Hähnle <nicolai.haehnle@amd.com>2017-07-13 13:27:43 +0200
commitddf33754742954b42cb5d964f10b17abecd88d04 (patch)
treeb78c6094929c2e2ad20d19569a27eafa68bdc7c6
parent556f779180cf47a58fd514e4c0775a1441124b2e (diff)
mesa: store uniform location in gl_program_parameter
This avoids name-based lookups after the initial linking, which should help with SPIR-V shaders where names are optional.
-rw-r--r--src/compiler/glsl/shader_cache.cpp20
-rw-r--r--src/mesa/program/ir_to_mesa.cpp19
-rw-r--r--src/mesa/program/prog_parameter.c9
-rw-r--r--src/mesa/program/prog_parameter.h14
-rw-r--r--src/mesa/program/prog_parameter_layout.c17
-rw-r--r--src/mesa/program/prog_print.c2
-rw-r--r--src/mesa/program/prog_statevars.c2
-rw-r--r--src/mesa/state_tracker/st_glsl_to_nir.cpp57
8 files changed, 71 insertions, 69 deletions
diff --git a/src/compiler/glsl/shader_cache.cpp b/src/compiler/glsl/shader_cache.cpp
index cc4d24482d..2989408dd2 100644
--- a/src/compiler/glsl/shader_cache.cpp
+++ b/src/compiler/glsl/shader_cache.cpp
@@ -1085,8 +1085,12 @@ write_shader_parameters(struct blob *metadata,
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));
+ if (param->Type == PROGRAM_STATE_VAR) {
+ blob_write_bytes(metadata, param->u.StateIndexes,
+ sizeof(param->u.StateIndexes));
+ } else {
+ blob_write_uint32(metadata, param->u.Location);
+ }
i += (param->Size + 3) / 4;
}
@@ -1111,11 +1115,17 @@ read_shader_parameters(struct blob_reader *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));
+
+ if (type == PROGRAM_STATE_VAR) {
+ blob_copy_bytes(metadata, (uint8_t *) state_indexes,
+ sizeof(state_indexes));
+ }
_mesa_add_parameter(params, type, name, size, data_type,
- NULL, state_indexes);
+ NULL, type == PROGRAM_STATE_VAR ? state_indexes : NULL);
+
+ if (type != PROGRAM_STATE_VAR)
+ params->Parameters[i].u.Location = blob_read_uint32(metadata);
i += (size + 3) / 4;
}
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 1dfa9fe657..8839ec108e 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -2457,6 +2457,17 @@ add_uniform_to_shader::visit_field(const glsl_type *type, const char *name,
int index = _mesa_add_parameter(params, PROGRAM_UNIFORM, name, size,
type->gl_type, NULL, NULL);
+ unsigned location;
+ const bool found =
+ this->shader_program->UniformHash->get(location, name);
+
+ assert(found);
+ if (!found)
+ return;
+
+ for (unsigned int j = 0; j < size / 4; j++)
+ params->Parameters[index + j].u.Location = location;
+
/* The first part of the uniform that's processed determines the base
* location of the whole uniform (for structures).
*/
@@ -2510,13 +2521,7 @@ _mesa_associate_uniform_storage(struct gl_context *ctx,
if (params->Parameters[i].Type != PROGRAM_UNIFORM)
continue;
- unsigned location;
- const bool found =
- shader_program->UniformHash->get(location, params->Parameters[i].Name);
- assert(found);
-
- if (!found)
- continue;
+ unsigned location = params->Parameters[i].u.Location;
struct gl_uniform_storage *storage =
&shader_program->data->UniformStorage[location];
diff --git a/src/mesa/program/prog_parameter.c b/src/mesa/program/prog_parameter.c
index 40bc47de35..5c50101863 100644
--- a/src/mesa/program/prog_parameter.c
+++ b/src/mesa/program/prog_parameter.c
@@ -286,8 +286,10 @@ _mesa_add_parameter(struct gl_program_parameter_list *paramList,
}
if (state) {
+ assert(type == PROGRAM_STATE_VAR);
+
for (i = 0; i < STATE_LENGTH; i++)
- paramList->Parameters[oldNum].StateIndexes[i] = state[i];
+ paramList->Parameters[oldNum].u.StateIndexes[i] = state[i];
}
return (GLint) oldNum;
@@ -371,7 +373,10 @@ _mesa_add_state_reference(struct gl_program_parameter_list *paramList,
/* Check if the state reference is already in the list */
for (index = 0; index < (GLint) paramList->NumParameters; index++) {
- if (!memcmp(paramList->Parameters[index].StateIndexes,
+ if (paramList->Parameters[index].Type != PROGRAM_STATE_VAR)
+ continue;
+
+ if (!memcmp(paramList->Parameters[index].u.StateIndexes,
stateTokens, STATE_LENGTH * sizeof(gl_state_index))) {
return index;
}
diff --git a/src/mesa/program/prog_parameter.h b/src/mesa/program/prog_parameter.h
index f50e99c8ab..23a06bd06a 100644
--- a/src/mesa/program/prog_parameter.h
+++ b/src/mesa/program/prog_parameter.h
@@ -69,10 +69,16 @@ struct gl_program_parameter
* The next program parameter's Size will be Size-4 of this parameter.
*/
GLuint Size;
- /**
- * A sequence of STATE_* tokens and integers to identify GL state.
- */
- gl_state_index StateIndexes[STATE_LENGTH];
+
+ union {
+ /**
+ * A sequence of STATE_* tokens and integers to identify GL state.
+ */
+ gl_state_index StateIndexes[STATE_LENGTH];
+
+ /** Location of the corresponding uniform */
+ GLuint Location;
+ } u;
};
diff --git a/src/mesa/program/prog_parameter_layout.c b/src/mesa/program/prog_parameter_layout.c
index 282a367ad0..052aceeda0 100644
--- a/src/mesa/program/prog_parameter_layout.c
+++ b/src/mesa/program/prog_parameter_layout.c
@@ -80,13 +80,14 @@ copy_indirect_accessed_array(struct gl_program_parameter_list *src,
if (curr->Type == PROGRAM_CONSTANT) {
j = dst->NumParameters;
- } else {
- for (j = 0; j < dst->NumParameters; j++) {
- if (memcmp(dst->Parameters[j].StateIndexes, curr->StateIndexes,
- sizeof(curr->StateIndexes)) == 0) {
- return -1;
- }
- }
+ } else if (curr->Type == PROGRAM_STATE_VAR) {
+ for (j = 0; j < dst->NumParameters; j++) {
+ if (dst->Parameters[j].Type == PROGRAM_STATE_VAR &&
+ memcmp(dst->Parameters[j].u.StateIndexes, curr->u.StateIndexes,
+ sizeof(curr->u.StateIndexes)) == 0) {
+ return -1;
+ }
+ }
}
assert(j == dst->NumParameters);
@@ -196,7 +197,7 @@ _mesa_layout_parameters(struct asm_parser_state *state)
case PROGRAM_STATE_VAR:
inst->Base.SrcReg[i].Index =
- _mesa_add_state_reference(layout, p->StateIndexes);
+ _mesa_add_state_reference(layout, p->u.StateIndexes);
break;
default:
diff --git a/src/mesa/program/prog_print.c b/src/mesa/program/prog_print.c
index 4f85d14c41..24ea4ca6e7 100644
--- a/src/mesa/program/prog_print.c
+++ b/src/mesa/program/prog_print.c
@@ -401,7 +401,7 @@ reg_string(gl_register_file f, GLint index, gl_prog_print_mode mode,
{
struct gl_program_parameter *param
= prog->Parameters->Parameters + index;
- char *state = _mesa_program_state_string(param->StateIndexes);
+ char *state = _mesa_program_state_string(param->u.StateIndexes);
sprintf(str, "%s", state);
free(state);
}
diff --git a/src/mesa/program/prog_statevars.c b/src/mesa/program/prog_statevars.c
index 91178e395c..b24c473637 100644
--- a/src/mesa/program/prog_statevars.c
+++ b/src/mesa/program/prog_statevars.c
@@ -1076,7 +1076,7 @@ _mesa_load_state_parameters(struct gl_context *ctx,
for (i = 0; i < paramList->NumParameters; i++) {
if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {
_mesa_fetch_state(ctx,
- paramList->Parameters[i].StateIndexes,
+ paramList->Parameters[i].u.StateIndexes,
&paramList->ParameterValues[i][0]);
}
}
diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp
index 8d29aa93d6..56e5694b60 100644
--- a/src/mesa/state_tracker/st_glsl_to_nir.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp
@@ -123,50 +123,25 @@ st_nir_assign_vs_in_locations(struct gl_program *prog, nir_shader *nir)
static int
st_nir_lookup_parameter_index(const struct gl_program_parameter_list *params,
- const char *name)
+ nir_variable *uniform)
{
- int loc = _mesa_lookup_parameter_index(params, name);
-
- /* is there a better way to do this? If we have something like:
- *
- * struct S {
- * float f;
- * vec4 v;
- * };
- * uniform S color;
- *
- * Then what we get in prog->Parameters looks like:
- *
- * 0: Name=color.f, Type=6, DataType=1406, Size=1
- * 1: Name=color.v, Type=6, DataType=8b52, Size=4
- *
- * So the name doesn't match up and _mesa_lookup_parameter_index()
- * fails. In this case just find the first matching "color.*"..
- *
- * Note for arrays you could end up w/ color[n].f, for example.
- *
- * glsl_to_tgsi works slightly differently in this regard. It is
- * emitting something more low level, so it just translates the
- * params list 1:1 to CONST[] regs. Going from GLSL IR to TGSI,
- * it just calculates the additional offset of struct field members
- * in glsl_to_tgsi_visitor::visit(ir_dereference_record *ir) or
- * glsl_to_tgsi_visitor::visit(ir_dereference_array *ir). It never
- * needs to work backwards to get base var loc from the param-list
- * which already has them separated out.
- */
- if (loc < 0) {
- int namelen = strlen(name);
- for (unsigned i = 0; i < params->NumParameters; i++) {
- struct gl_program_parameter *p = &params->Parameters[i];
- if ((strncmp(p->Name, name, namelen) == 0) &&
- ((p->Name[namelen] == '.') || (p->Name[namelen] == '['))) {
- loc = i;
- break;
- }
+ assert(uniform->data.mode == nir_var_uniform);
+ assert(uniform->data.location >= 0 || strncmp(uniform->name, "state.", 6) == 0);
+
+ for (unsigned int i = 0; i < params->NumParameters; ++i) {
+ const struct gl_program_parameter *param = &params->Parameters[i];
+
+ if (uniform->data.location >= 0) {
+ if ((param->Type == PROGRAM_SAMPLER || param->Type == PROGRAM_UNIFORM) &&
+ param->u.Location == (unsigned)uniform->data.location)
+ return i;
+ } else if (param->Type == PROGRAM_STATE_VAR &&
+ strcmp(uniform->name, param->Name) == 0) {
+ return i;
}
}
- return loc;
+ return -1;
}
static void
@@ -205,7 +180,7 @@ st_nir_assign_uniform_locations(struct gl_program *prog,
*/
loc = _mesa_add_state_reference(prog->Parameters, stateTokens);
} else {
- loc = st_nir_lookup_parameter_index(prog->Parameters, uniform->name);
+ loc = st_nir_lookup_parameter_index(prog->Parameters, uniform);
}
uniform->data.driver_location = loc;