nir: Print array deref indices as decimal
[mesa.git] / src / compiler / glsl / link_uniform_initializers.cpp
index 7e5b80d5c7e442259b550573bef5a7e9804a5378..61b324592dfc9d2645d5e76883f653a2fb4ed137 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include "main/core.h"
 #include "ir.h"
 #include "linker.h"
 #include "ir_uniform.h"
-#include "util/string_to_uint_map.h"
+#include "string_to_uint_map.h"
+#include "main/mtypes.h"
 
 /* These functions are put in a "private" namespace instead of being marked
  * static so that the unit tests can access them.  See
@@ -33,7 +33,7 @@
  */
 namespace linker {
 
-gl_uniform_storage *
+static gl_uniform_storage *
 get_storage(struct gl_shader_program *prog, const char *name)
 {
    unsigned id;
@@ -81,6 +81,11 @@ copy_constant_to_storage(union gl_constant_value *storage,
       case GLSL_TYPE_SUBROUTINE:
       case GLSL_TYPE_FUNCTION:
       case GLSL_TYPE_ERROR:
+      case GLSL_TYPE_UINT16:
+      case GLSL_TYPE_INT16:
+      case GLSL_TYPE_UINT8:
+      case GLSL_TYPE_INT8:
+      case GLSL_TYPE_FLOAT16:
          /* All other types should have already been filtered by other
           * paths in the caller.
           */
@@ -95,9 +100,10 @@ copy_constant_to_storage(union gl_constant_value *storage,
  * qualifier specified in the shader.  Atomic counters are different because
  * they have no storage and should be handled elsewhere.
  */
-void
+static void
 set_opaque_binding(void *mem_ctx, gl_shader_program *prog,
-                   const glsl_type *type, const char *name, int *binding)
+                   const ir_variable *var, const glsl_type *type,
+                   const char *name, int *binding)
 {
 
    if (type->is_array() && type->fields.array->is_array()) {
@@ -106,7 +112,7 @@ set_opaque_binding(void *mem_ctx, gl_shader_program *prog,
       for (unsigned int i = 0; i < type->length; i++) {
          const char *element_name = ralloc_asprintf(mem_ctx, "%s[%d]", name, i);
 
-         set_opaque_binding(mem_ctx, prog, element_type,
+         set_opaque_binding(mem_ctx, prog, var, element_type,
                             element_name, binding);
       }
    } else {
@@ -117,7 +123,7 @@ set_opaque_binding(void *mem_ctx, gl_shader_program *prog,
 
       const unsigned elements = MAX2(storage->array_elements, 1);
 
-      /* Section 4.4.4 (Opaque-Uniform Layout Qualifiers) of the GLSL 4.20 spec
+      /* Section 4.4.6 (Opaque-Uniform Layout Qualifiers) of the GLSL 4.50 spec
        * says:
        *
        *     "If the binding identifier is used with an array, the first element
@@ -129,21 +135,44 @@ set_opaque_binding(void *mem_ctx, gl_shader_program *prog,
       }
 
       for (int sh = 0; sh < MESA_SHADER_STAGES; sh++) {
-        gl_linked_shader *shader = prog->_LinkedShaders[sh];
+         gl_linked_shader *shader = prog->_LinkedShaders[sh];
+
+         if (!shader)
+            continue;
+         if (!storage->opaque[sh].active)
+            continue;
 
-         if (shader) {
-            if (storage->type->base_type == GLSL_TYPE_SAMPLER &&
-                storage->opaque[sh].active) {
-               for (unsigned i = 0; i < elements; i++) {
-                  const unsigned index = storage->opaque[sh].index + i;
+         if (storage->type->is_sampler()) {
+            for (unsigned i = 0; i < elements; i++) {
+               const unsigned index = storage->opaque[sh].index + i;
+
+               if (var->data.bindless) {
+                  if (index >= shader->Program->sh.NumBindlessSamplers)
+                     break;
+                  shader->Program->sh.BindlessSamplers[index].unit =
+                     storage->storage[i].i;
+                  shader->Program->sh.BindlessSamplers[index].bound = true;
+                  shader->Program->sh.HasBoundBindlessSampler = true;
+               } else {
+                  if (index >= ARRAY_SIZE(shader->Program->SamplerUnits))
+                     break;
                   shader->Program->SamplerUnits[index] =
                      storage->storage[i].i;
                }
+            }
+         } else if (storage->type->is_image()) {
+            for (unsigned i = 0; i < elements; i++) {
+               const unsigned index = storage->opaque[sh].index + i;
+
 
-            } else if (storage->type->is_image() &&
-                    storage->opaque[sh].active) {
-               for (unsigned i = 0; i < elements; i++) {
-                  const unsigned index = storage->opaque[sh].index + i;
+               if (var->data.bindless) {
+                  if (index >= shader->Program->sh.NumBindlessImages)
+                     break;
+                  shader->Program->sh.BindlessImages[index].unit =
+                     storage->storage[i].i;
+                  shader->Program->sh.BindlessImages[index].bound = true;
+                  shader->Program->sh.HasBoundBindlessImage = true;
+               } else {
                   if (index >= ARRAY_SIZE(shader->Program->sh.ImageUnits))
                      break;
                   shader->Program->sh.ImageUnits[index] =
@@ -155,47 +184,23 @@ set_opaque_binding(void *mem_ctx, gl_shader_program *prog,
    }
 }
 
-void
-set_block_binding(gl_shader_program *prog, const char *block_name,
-                  unsigned mode, int binding)
-{
-   unsigned num_blocks = mode == ir_var_uniform ?
-      prog->data->NumUniformBlocks :
-      prog->data->NumShaderStorageBlocks;
-   struct gl_uniform_block *blks = mode == ir_var_uniform ?
-      prog->data->UniformBlocks : prog->data->ShaderStorageBlocks;
-
-   for (unsigned i = 0; i < num_blocks; i++) {
-      if (!strcmp(blks[i].Name, block_name)) {
-         blks[i].Binding = binding;
-         return;
-      }
-   }
-
-   unreachable("Failed to initialize block binding");
-}
-
 void
 set_uniform_initializer(void *mem_ctx, gl_shader_program *prog,
                         const char *name, const glsl_type *type,
                         ir_constant *val, unsigned int boolean_true)
 {
    const glsl_type *t_without_array = type->without_array();
-   if (type->is_record()) {
-      ir_constant *field_constant;
-
-      field_constant = (ir_constant *)val->components.get_head();
-
+   if (type->is_struct()) {
       for (unsigned int i = 0; i < type->length; i++) {
          const glsl_type *field_type = type->fields.structure[i].type;
          const char *field_name = ralloc_asprintf(mem_ctx, "%s.%s", name,
                                             type->fields.structure[i].name);
          set_uniform_initializer(mem_ctx, prog, field_name,
-                                 field_type, field_constant, boolean_true);
-         field_constant = (ir_constant *)field_constant->next;
+                                 field_type, val->get_record_field(i),
+                                 boolean_true);
       }
       return;
-   } else if (t_without_array->is_record() ||
+   } else if (t_without_array->is_struct() ||
               (type->is_array() && type->fields.array->is_array())) {
       const glsl_type *const element_type = type->fields.array;
 
@@ -203,7 +208,7 @@ set_uniform_initializer(void *mem_ctx, gl_shader_program *prog,
          const char *element_name = ralloc_asprintf(mem_ctx, "%s[%d]", name, i);
 
          set_uniform_initializer(mem_ctx, prog, element_name,
-                                 element_type, val->array_elements[i],
+                                 element_type, val->const_elements[i],
                                  boolean_true);
       }
       return;
@@ -216,15 +221,15 @@ set_uniform_initializer(void *mem_ctx, gl_shader_program *prog,
 
    if (val->type->is_array()) {
       const enum glsl_base_type base_type =
-         val->array_elements[0]->type->base_type;
-      const unsigned int elements = val->array_elements[0]->type->components();
+         val->const_elements[0]->type->base_type;
+      const unsigned int elements = val->const_elements[0]->type->components();
       unsigned int idx = 0;
       unsigned dmul = glsl_base_type_is_64bit(base_type) ? 2 : 1;
 
       assert(val->type->length >= storage->array_elements);
       for (unsigned int i = 0; i < storage->array_elements; i++) {
          copy_constant_to_storage(& storage->storage[idx],
-                                  val->array_elements[i],
+                                  val->const_elements[i],
                                   base_type,
                                   elements,
                                   boolean_true);
@@ -281,46 +286,12 @@ link_set_uniform_initializers(struct gl_shader_program *prog,
             if (type->without_array()->is_sampler() ||
                 type->without_array()->is_image()) {
                int binding = var->data.binding;
-               linker::set_opaque_binding(mem_ctx, prog, var->type,
+               linker::set_opaque_binding(mem_ctx, prog, var, var->type,
                                           var->name, &binding);
             } else if (var->is_in_buffer_block()) {
-               const glsl_type *const iface_type = var->get_interface_type();
-
-               /* If the variable is an array and it is an interface instance,
-                * we need to set the binding for each array element.  Just
-                * checking that the variable is an array is not sufficient.
-                * The variable could be an array element of a uniform block
-                * that lacks an instance name.  For example:
-                *
-                *     uniform U {
-                *         float f[4];
-                *     };
-                *
-                * In this case "f" would pass is_in_buffer_block (above) and
-                * type->is_array(), but it will fail is_interface_instance().
+               /* This case is handled by link_uniform_blocks (at
+                * process_block_array_leaf)
                 */
-               if (var->is_interface_instance() && var->type->is_array()) {
-                  for (unsigned i = 0; i < var->type->length; i++) {
-                     const char *name =
-                        ralloc_asprintf(mem_ctx, "%s[%u]", iface_type->name, i);
-
-                     /* Section 4.4.3 (Uniform Block Layout Qualifiers) of the
-                      * GLSL 4.20 spec says:
-                      *
-                      *     "If the binding identifier is used with a uniform
-                      *     block instanced as an array then the first element
-                      *     of the array takes the specified block binding and
-                      *     each subsequent element takes the next consecutive
-                      *     uniform block binding point."
-                      */
-                     linker::set_block_binding(prog, name, var->data.mode,
-                                               var->data.binding + i);
-                  }
-               } else {
-                  linker::set_block_binding(prog, iface_type->name,
-                                            var->data.mode,
-                                            var->data.binding);
-               }
             } else if (type->contains_atomic()) {
                /* we don't actually need to do anything. */
             } else {
@@ -334,5 +305,7 @@ link_set_uniform_initializers(struct gl_shader_program *prog,
       }
    }
 
+   memcpy(prog->data->UniformDataDefaults, prog->data->UniformDataSlots,
+          sizeof(union gl_constant_value) * prog->data->NumUniformDataSlots);
    ralloc_free(mem_ctx);
 }