glsl: Make a function to express a GLSL version ir human-readable form.
[mesa.git] / src / glsl / link_uniforms.cpp
index 1c975863c0df39d04478190647644b8d92011f4c..aa8a8b3fbd87bac1c475467ea39b4ce4e5795ad2 100644 (file)
@@ -223,7 +223,8 @@ public:
       this->shader_shadow_samplers = 0;
    }
 
-   void set_and_process(struct gl_shader *shader,
+   void set_and_process(struct gl_shader_program *prog,
+                       struct gl_shader *shader,
                        ir_variable *var)
    {
       ubo_var = NULL;
@@ -231,7 +232,16 @@ public:
         struct gl_uniform_block *block =
            &shader->UniformBlocks[var->uniform_block];
 
-        ubo_block_index = var->uniform_block;
+        ubo_block_index = -1;
+        for (unsigned i = 0; i < prog->NumUniformBlocks; i++) {
+           if (!strcmp(prog->UniformBlocks[i].Name,
+                       shader->UniformBlocks[var->uniform_block].Name)) {
+              ubo_block_index = i;
+              break;
+           }
+        }
+        assert(ubo_block_index != -1);
+
         ubo_var_index = var->location;
         ubo_var = &block->Uniforms[var->location];
         ubo_byte_offset = ubo_var->Offset;
@@ -303,7 +313,7 @@ private:
         const gl_texture_index target = base_type->sampler_index();
         const unsigned shadow = base_type->sampler_shadow;
         for (unsigned i = this->uniforms[id].sampler
-                ; i < this->next_sampler
+                ; i < MIN2(this->next_sampler, MAX_SAMPLERS)
                 ; i++) {
            this->targets[i] = target;
            this->shader_samplers_used |= 1U << i;
@@ -490,7 +500,19 @@ link_assign_uniform_block_offsets(struct gl_shader *shader)
         ubo_var->Offset = offset;
         offset += size;
       }
-      block->UniformBufferSize = offset;
+
+      /* From the GL_ARB_uniform_buffer_object spec:
+       *
+       *     "For uniform blocks laid out according to [std140] rules,
+       *      the minimum buffer object size returned by the
+       *      UNIFORM_BLOCK_DATA_SIZE query is derived by taking the
+       *      offset of the last basic machine unit consumed by the
+       *      last uniform of the uniform block (including any
+       *      end-of-array or end-of-structure padding), adding one,
+       *      and rounding up to the next multiple of the base
+       *      alignment required for a vec4."
+       */
+      block->UniformBufferSize = align(offset, 16);
    }
 }
 
@@ -550,8 +572,11 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
 
         /* FINISHME: Update code to process built-in uniforms!
          */
-        if (strncmp("gl_", var->name, 3) == 0)
+        if (strncmp("gl_", var->name, 3) == 0) {
+           uniform_size.num_shader_uniform_components +=
+              var->type->component_slots();
            continue;
+        }
 
         uniform_size.process(var);
       }
@@ -598,7 +623,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
         if (strncmp("gl_", var->name, 3) == 0)
            continue;
 
-        parcel.set_and_process(prog->_LinkedShaders[i], var);
+        parcel.set_and_process(prog, prog->_LinkedShaders[i], var);
       }
 
       prog->_LinkedShaders[i]->active_samplers = parcel.shader_samplers_used;