[Mesa-dev] [PATCH 06/78] i965/nir/vec4: Add setup of uniform variables
Eduardo Lima Mitev
elima at igalia.com
Fri Jun 26 01:06:22 PDT 2015
From: Iago Toral Quiroga <itoral at igalia.com>
This is based on similar code existing in vec4_visitor. It builds the
uniform register file iterating through each uniform variable. It
also stores the index of each register at the corresponding offset
in a map. This map will later be used by load_uniform intrinsic
instructions to build the correct UNIFORM source register.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89580
---
src/mesa/drivers/dri/i965/brw_vec4.h | 2 +
src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 115 ++++++++++++++++++++++++++++-
2 files changed, 114 insertions(+), 3 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 673df4e..6535f19 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -414,6 +414,8 @@ public:
src_reg *nir_inputs;
int *nir_outputs;
brw_reg_type *nir_output_types;
+ unsigned *nir_uniform_offset;
+ unsigned *nir_uniform_driver_location;
protected:
void emit_vertex();
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
index 2d457a6..40ec66f 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
@@ -106,19 +106,128 @@ vec4_visitor::nir_setup_outputs(nir_shader *shader)
void
vec4_visitor::nir_setup_uniforms(nir_shader *shader)
{
- /* @TODO: Not yet implemented */
+ uniforms = 0;
+
+ nir_uniform_offset =
+ rzalloc_array(mem_ctx, unsigned, this->uniform_array_size);
+ memset(nir_uniform_offset, 0, this->uniform_array_size * sizeof(unsigned));
+
+ nir_uniform_driver_location =
+ rzalloc_array(mem_ctx, unsigned, this->uniform_array_size);
+ memset(nir_uniform_driver_location, 0,
+ this->uniform_array_size * sizeof(unsigned));
+
+ if (shader_prog) {
+ foreach_list_typed(nir_variable, var, node, &shader->uniforms) {
+ /* UBO's, atomics and samplers don't take up space in the
+ uniform file */
+ if (var->interface_type != NULL || var->type->contains_atomic() ||
+ type_size(var->type) == 0) {
+ continue;
+ }
+
+ assert(uniforms < uniform_array_size);
+ this->uniform_size[uniforms] = type_size(var->type);
+
+ if (strncmp(var->name, "gl_", 3) == 0)
+ nir_setup_builtin_uniform(var);
+ else
+ nir_setup_uniform(var);
+ }
+ } else {
+ /* ARB_vertex_program is not supported yet */
+ assert("Not implemented");
+ }
}
void
vec4_visitor::nir_setup_uniform(nir_variable *var)
{
- /* @TODO: Not yet implemented */
+ int namelen = strlen(var->name);
+
+ /* The data for our (non-builtin) uniforms is stored in a series of
+ * gl_uniform_driver_storage structs for each subcomponent that
+ * glGetUniformLocation() could name. We know it's been set up in the same
+ * order we'd walk the type, so walk the list of storage and find anything
+ * with our name, or the prefix of a component that starts with our name.
+ */
+ unsigned offset = 0;
+ for (unsigned u = 0; u < shader_prog->NumUniformStorage; u++) {
+ struct gl_uniform_storage *storage = &shader_prog->UniformStorage[u];
+
+ if (storage->builtin)
+ continue;
+
+ if (strncmp(var->name, storage->name, namelen) != 0 ||
+ (storage->name[namelen] != 0 &&
+ storage->name[namelen] != '.' &&
+ storage->name[namelen] != '[')) {
+ continue;
+ }
+
+ gl_constant_value *components = storage->storage;
+ unsigned vector_count = (MAX2(storage->array_elements, 1) *
+ storage->type->matrix_columns);
+
+ for (unsigned s = 0; s < vector_count; s++) {
+ assert(uniforms < uniform_array_size);
+ uniform_vector_size[uniforms] = storage->type->vector_elements;
+
+ int i;
+ for (i = 0; i < uniform_vector_size[uniforms]; i++) {
+ stage_prog_data->param[uniforms * 4 + i] = components;
+ components++;
+ }
+ for (; i < 4; i++) {
+ static gl_constant_value zero = { 0.0 };
+ stage_prog_data->param[uniforms * 4 + i] = &zero;
+ }
+
+ int uniform_offset = var->data.driver_location + offset;
+ nir_uniform_offset[uniform_offset] = uniforms;
+ offset++;
+
+ nir_uniform_driver_location[uniforms] = var->data.driver_location;
+ uniforms++;
+ }
+ }
}
void
vec4_visitor::nir_setup_builtin_uniform(nir_variable *var)
{
- /* @TODO: Not yet implemented */
+ const nir_state_slot *const slots = var->state_slots;
+ assert(var->state_slots != NULL);
+
+ unsigned offset = 0;
+ for (unsigned int i = 0; i < var->num_state_slots; i++) {
+ /* This state reference has already been setup by ir_to_mesa,
+ * but we'll get the same index back here. We can reference
+ * ParameterValues directly, since unlike brw_fs.cpp, we never
+ * add new state references during compile.
+ */
+ int index = _mesa_add_state_reference(this->prog->Parameters,
+ (gl_state_index *)slots[i].tokens);
+ gl_constant_value *values =
+ &this->prog->Parameters->ParameterValues[index][0];
+
+ assert(this->uniforms < uniform_array_size);
+
+ for (unsigned j = 0; j < 4; j++)
+ stage_prog_data->param[this->uniforms * 4 + j] =
+ &values[GET_SWZ(slots[i].swizzle, j)];
+
+ this->uniform_vector_size[this->uniforms] =
+ (var->type->is_scalar() || var->type->is_vector() ||
+ var->type->is_matrix() ? var->type->vector_elements : 4);
+
+ int uniform_offset = var->data.driver_location + offset;
+ nir_uniform_offset[uniform_offset] = uniforms;
+ offset++;
+
+ nir_uniform_driver_location[uniforms] = var->data.driver_location;
+ this->uniforms++;
+ }
}
void
--
2.1.4
More information about the mesa-dev
mailing list