radeon / r200: Pass the API into _mesa_initialize_context
[mesa.git] / src / glsl / link_uniforms.cpp
index 03cbcd1ce202e8409ad7774dfd8502b5acf4854e..1c97e19578191f915d6186e293b55941dc5ccbd0 100644 (file)
@@ -75,7 +75,63 @@ program_resource_visitor::process(ir_variable *var)
     */
 
    /* Only strdup the name if we actually will need to modify it. */
-   if (t->is_record() || (t->is_array() && t->fields.array->is_record())) {
+   if (var->data.from_named_ifc_block_array) {
+      /* lower_named_interface_blocks created this variable by lowering an
+       * interface block array to an array variable.  For example if the
+       * original source code was:
+       *
+       *     out Blk { vec4 bar } foo[3];
+       *
+       * Then the variable is now:
+       *
+       *     out vec4 bar[3];
+       *
+       * We need to visit each array element using the names constructed like
+       * so:
+       *
+       *     Blk[0].bar
+       *     Blk[1].bar
+       *     Blk[2].bar
+       */
+      assert(t->is_array());
+      const glsl_type *ifc_type = var->get_interface_type();
+      char *name = ralloc_strdup(NULL, ifc_type->name);
+      size_t name_length = strlen(name);
+      for (unsigned i = 0; i < t->length; i++) {
+         size_t new_length = name_length;
+         ralloc_asprintf_rewrite_tail(&name, &new_length, "[%u].%s", i,
+                                      var->name);
+         /* Note: row_major is only meaningful for uniform blocks, and
+          * lowering is only applied to non-uniform interface blocks, so we
+          * can safely pass false for row_major.
+          */
+         recursion(var->type, &name, new_length, false, NULL);
+      }
+      ralloc_free(name);
+   } else if (var->data.from_named_ifc_block_nonarray) {
+      /* lower_named_interface_blocks created this variable by lowering a
+       * named interface block (non-array) to an ordinary variable.  For
+       * example if the original source code was:
+       *
+       *     out Blk { vec4 bar } foo;
+       *
+       * Then the variable is now:
+       *
+       *     out vec4 bar;
+       *
+       * We need to visit this variable using the name:
+       *
+       *     Blk.bar
+       */
+      const glsl_type *ifc_type = var->get_interface_type();
+      char *name = ralloc_asprintf(NULL, "%s.%s", ifc_type->name, var->name);
+      /* Note: row_major is only meaningful for uniform blocks, and lowering
+       * is only applied to non-uniform interface blocks, so we can safely
+       * pass false for row_major.
+       */
+      recursion(var->type, &name, strlen(name), false, NULL);
+      ralloc_free(name);
+   } else if (t->is_record() || (t->is_array() && t->fields.array->is_record())) {
       char *name = ralloc_strdup(NULL, var->name);
       recursion(var->type, &name, strlen(name), false, NULL);
       ralloc_free(name);
@@ -140,8 +196,8 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
         /* Append the subscript to the current variable name */
         ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i);
 
-         recursion(t->fields.array, name, new_length,
-                   t->fields.structure[i].row_major, record_type);
+         recursion(t->fields.array, name, new_length, row_major,
+                   record_type);
 
          /* Only the first leaf-field of the record gets called with the
           * record type pointer.
@@ -199,8 +255,8 @@ public:
    {
       this->is_ubo_var = var->is_in_uniform_block();
       if (var->is_interface_instance())
-         program_resource_visitor::process(var->interface_type,
-                                           var->interface_type->name);
+         program_resource_visitor::process(var->get_interface_type(),
+                                           var->get_interface_type()->name);
       else
          program_resource_visitor::process(var);
    }
@@ -300,9 +356,9 @@ public:
    {
    }
 
-   void start_shader(gl_shader_type shader_type)
+   void start_shader(gl_shader_stage shader_type)
    {
-      assert(shader_type < MESA_SHADER_TYPES);
+      assert(shader_type < MESA_SHADER_STAGES);
       this->shader_type = shader_type;
 
       this->shader_samplers_used = 0;
@@ -317,10 +373,10 @@ public:
       ubo_block_index = -1;
       if (var->is_in_uniform_block()) {
          if (var->is_interface_instance() && var->type->is_array()) {
-            unsigned l = strlen(var->interface_type->name);
+            unsigned l = strlen(var->get_interface_type()->name);
 
             for (unsigned i = 0; i < prog->NumUniformBlocks; i++) {
-               if (strncmp(var->interface_type->name,
+               if (strncmp(var->get_interface_type()->name,
                            prog->UniformBlocks[i].Name,
                            l) == 0
                    && prog->UniformBlocks[i].Name[l] == '[') {
@@ -330,7 +386,7 @@ public:
             }
          } else {
             for (unsigned i = 0; i < prog->NumUniformBlocks; i++) {
-               if (strcmp(var->interface_type->name,
+               if (strcmp(var->get_interface_type()->name,
                           prog->UniformBlocks[i].Name) == 0) {
                   ubo_block_index = i;
                   break;
@@ -352,17 +408,18 @@ public:
             const struct gl_uniform_block *const block =
                &prog->UniformBlocks[ubo_block_index];
 
-            assert(var->location != -1);
+            assert(var->data.location != -1);
 
             const struct gl_uniform_buffer_variable *const ubo_var =
-               &block->Uniforms[var->location];
+               &block->Uniforms[var->data.location];
 
             ubo_row_major = ubo_var->RowMajor;
             ubo_byte_offset = ubo_var->Offset;
          }
 
          if (var->is_interface_instance())
-            process(var->interface_type, var->interface_type->name);
+            process(var->get_interface_type(),
+                    var->get_interface_type()->name);
          else
             process(var);
       } else
@@ -372,7 +429,7 @@ public:
    int ubo_block_index;
    int ubo_byte_offset;
    bool ubo_row_major;
-   gl_shader_type shader_type;
+   gl_shader_stage shader_type;
 
 private:
    void handle_samplers(const glsl_type *base_type,
@@ -456,6 +513,7 @@ private:
       this->uniforms[id].num_driver_storage = 0;
       this->uniforms[id].driver_storage = NULL;
       this->uniforms[id].storage = this->values;
+      this->uniforms[id].atomic_buffer_index = -1;
       if (this->ubo_block_index != -1) {
         this->uniforms[id].block_index = this->ubo_block_index;
 
@@ -579,10 +637,10 @@ link_update_uniform_buffer_variables(struct gl_shader *shader)
       if ((var == NULL) || !var->is_in_uniform_block())
         continue;
 
-      assert(var->mode == ir_var_uniform);
+      assert(var->data.mode == ir_var_uniform);
 
       if (var->is_interface_instance()) {
-         var->location = 0;
+         var->data.location = 0;
          continue;
       }
 
@@ -611,13 +669,13 @@ link_update_uniform_buffer_variables(struct gl_shader *shader)
 
                if (strncmp(var->name, begin, l) == 0) {
                   found = true;
-                  var->location = j;
+                  var->data.location = j;
                   break;
                }
             } else if (!strcmp(var->name,
                                shader->UniformBlocks[i].Uniforms[j].Name)) {
               found = true;
-              var->location = j;
+              var->data.location = j;
               break;
            }
         }
@@ -683,7 +741,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
     * glGetUniformLocation.
     */
    count_uniform_size uniform_size(prog->UniformHash);
-   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
       struct gl_shader *sh = prog->_LinkedShaders[i];
 
       if (sh == NULL)
@@ -709,7 +767,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
       foreach_list(node, sh->ir) {
         ir_variable *const var = ((ir_instruction *) node)->as_variable();
 
-        if ((var == NULL) || (var->mode != ir_var_uniform))
+        if ((var == NULL) || (var->data.mode != ir_var_uniform))
            continue;
 
         /* FINISHME: Update code to process built-in uniforms!
@@ -751,16 +809,16 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
 
    parcel_out_uniform_storage parcel(prog->UniformHash, uniforms, data);
 
-   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
       if (prog->_LinkedShaders[i] == NULL)
         continue;
 
-      parcel.start_shader((gl_shader_type)i);
+      parcel.start_shader((gl_shader_stage)i);
 
       foreach_list(node, prog->_LinkedShaders[i]->ir) {
         ir_variable *const var = ((ir_instruction *) node)->as_variable();
 
-        if ((var == NULL) || (var->mode != ir_var_uniform))
+        if ((var == NULL) || (var->data.mode != ir_var_uniform))
            continue;
 
         /* FINISHME: Update code to process built-in uniforms!