glsl: link buffer variables and shader storage buffer interface blocks
authorKristian Høgsberg <krh@bitplanet.net>
Wed, 13 May 2015 09:17:23 +0000 (11:17 +0200)
committerSamuel Iglesias Gonsalvez <siglesias@igalia.com>
Tue, 14 Jul 2015 05:04:03 +0000 (07:04 +0200)
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
src/glsl/link_interface_blocks.cpp
src/glsl/link_uniform_initializers.cpp
src/glsl/link_uniforms.cpp
src/glsl/linker.cpp

index 07f5b4223a8220bc2bd728a8bd29f48c3208f8c6..f9ddb13cd566b88d2feb58e10d5447dd38df7745 100644 (file)
@@ -112,7 +112,8 @@ intrastage_match(interface_block_definition *a,
     * it's not clear from the spec whether they need to match, but
     * Mesa's implementation relies on them matching.
     */
-   if (a->instance_name != NULL && mode != ir_var_uniform &&
+   if (a->instance_name != NULL &&
+       mode != ir_var_uniform && mode != ir_var_shader_storage &&
        strcmp(a->instance_name, b->instance_name) != 0) {
       return false;
    }
@@ -253,6 +254,7 @@ validate_intrastage_interface_blocks(struct gl_shader_program *prog,
    interface_block_definitions in_interfaces;
    interface_block_definitions out_interfaces;
    interface_block_definitions uniform_interfaces;
+   interface_block_definitions buffer_interfaces;
 
    for (unsigned int i = 0; i < num_shaders; i++) {
       if (shader_list[i] == NULL)
@@ -279,6 +281,9 @@ validate_intrastage_interface_blocks(struct gl_shader_program *prog,
          case ir_var_uniform:
             definitions = &uniform_interfaces;
             break;
+         case ir_var_shader_storage:
+            definitions = &buffer_interfaces;
+            break;
          default:
             /* Only in, out, and uniform interfaces are legal, so we should
              * never get here.
@@ -361,7 +366,9 @@ validate_interstage_uniform_blocks(struct gl_shader_program *prog,
       const gl_shader *stage = stages[i];
       foreach_in_list(ir_instruction, node, stage->ir) {
          ir_variable *var = node->as_variable();
-         if (!var || !var->get_interface_type() || var->data.mode != ir_var_uniform)
+         if (!var || !var->get_interface_type() ||
+             (var->data.mode != ir_var_uniform &&
+              var->data.mode != ir_var_shader_storage))
             continue;
 
          interface_block_definition *old_def =
@@ -374,7 +381,9 @@ validate_interstage_uniform_blocks(struct gl_shader_program *prog,
              * uniform matchin rules (for uniforms, it is as though all
              * shaders are in the same shader stage).
              */
-            if (!intrastage_match(old_def, &new_def, ir_var_uniform, prog)) {
+            if (!intrastage_match(old_def, &new_def,
+                                  (ir_variable_mode) var->data.mode,
+                                  prog)) {
                linker_error(prog, "definitions of interface block `%s' do not "
                             "match\n", var->get_interface_type()->name);
                return;
index d1f904e99722e742d349ab74b91535413880576f..6322a2d52cc0e440f0a49f502d59942caf6577ae 100644 (file)
@@ -256,7 +256,8 @@ link_set_uniform_initializers(struct gl_shader_program *prog,
       foreach_in_list(ir_instruction, node, shader->ir) {
         ir_variable *const var = node->as_variable();
 
-        if (!var || var->data.mode != ir_var_uniform)
+        if (!var || (var->data.mode != ir_var_uniform &&
+            var->data.mode != ir_var_shader_storage))
            continue;
 
         if (!mem_ctx)
index 5fdf25e0a6680ca186339925a2483bf249a5c1ab..e786ddcaa90f54dffffbc16aaefd8d48f1900617 100644 (file)
@@ -766,7 +766,8 @@ link_update_uniform_buffer_variables(struct gl_shader *shader)
       if ((var == NULL) || !var->is_in_buffer_block())
         continue;
 
-      assert(var->data.mode == ir_var_uniform);
+      assert(var->data.mode == ir_var_uniform ||
+             var->data.mode == ir_var_shader_storage);
 
       if (var->is_interface_instance()) {
          var->data.location = 0;
@@ -943,7 +944,8 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
       foreach_in_list(ir_instruction, node, sh->ir) {
         ir_variable *const var = node->as_variable();
 
-        if ((var == NULL) || (var->data.mode != ir_var_uniform))
+        if ((var == NULL) || (var->data.mode != ir_var_uniform &&
+                              var->data.mode != ir_var_shader_storage))
            continue;
 
         uniform_size.process(var);
@@ -987,7 +989,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
       foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]->ir) {
         ir_variable *const var = node->as_variable();
 
-        if ((var == NULL) || (var->data.mode != ir_var_uniform))
+        if ((var == NULL) || (var->data.mode != ir_var_uniform && var->data.mode != ir_var_shader_storage))
            continue;
 
         parcel.set_and_process(prog, var);
index 3005b70a4f674efc91fcc1dc22da5b8d2e2ba694..28ad2f38e0edcd0531ba0c024fb8174e5242fba7 100644 (file)
@@ -777,7 +777,7 @@ cross_validate_globals(struct gl_shader_program *prog,
         if (var == NULL)
            continue;
 
-        if (uniforms_only && (var->data.mode != ir_var_uniform))
+        if (uniforms_only && (var->data.mode != ir_var_uniform && var->data.mode != ir_var_shader_storage))
            continue;
 
         /* Don't cross validate temporaries that are at global scope.  These
@@ -2574,7 +2574,7 @@ check_explicit_uniform_locations(struct gl_context *ctx,
 
       foreach_in_list(ir_instruction, node, sh->ir) {
          ir_variable *var = node->as_variable();
-         if ((var && var->data.mode == ir_var_uniform) &&
+         if (var && (var->data.mode == ir_var_uniform || var->data.mode == ir_var_shader_storage) &&
              var->data.explicit_location) {
             if (!reserve_explicit_locations(prog, uniform_map, var)) {
                delete uniform_map;