Merge remote-tracking branch 'mesa-public/master' into vulkan
[mesa.git] / src / mesa / drivers / dri / i965 / brw_vec4_visitor.cpp
index 20b628e91925441b40449c158ab2d8620df37d99..499f6288aeec1295a583ecde6f02951cf215ee99 100644 (file)
@@ -597,8 +597,8 @@ vec4_visitor::visit_instructions(const exec_list *list)
  * This method is useful to calculate how much register space is needed to
  * store a particular type.
  */
-int
-vec4_visitor::type_size(const struct glsl_type *type)
+extern "C" int
+type_size_vec4(const struct glsl_type *type)
 {
    unsigned int i;
    int size;
@@ -620,11 +620,11 @@ vec4_visitor::type_size(const struct glsl_type *type)
       }
    case GLSL_TYPE_ARRAY:
       assert(type->length > 0);
-      return type_size(type->fields.array) * type->length;
+      return type_size_vec4(type->fields.array) * type->length;
    case GLSL_TYPE_STRUCT:
       size = 0;
       for (i = 0; i < type->length; i++) {
-        size += type_size(type->fields.structure[i].type);
+        size += type_size_vec4(type->fields.structure[i].type);
       }
       return size;
    case GLSL_TYPE_SUBROUTINE:
@@ -655,7 +655,7 @@ src_reg::src_reg(class vec4_visitor *v, const struct glsl_type *type)
    init();
 
    this->file = GRF;
-   this->reg = v->alloc.allocate(v->type_size(type));
+   this->reg = v->alloc.allocate(type_size_vec4(type));
 
    if (type->is_array() || type->is_record()) {
       this->swizzle = BRW_SWIZZLE_NOOP;
@@ -673,7 +673,7 @@ src_reg::src_reg(class vec4_visitor *v, const struct glsl_type *type, int size)
    init();
 
    this->file = GRF;
-   this->reg = v->alloc.allocate(v->type_size(type) * size);
+   this->reg = v->alloc.allocate(type_size_vec4(type) * size);
 
    this->swizzle = BRW_SWIZZLE_NOOP;
 
@@ -685,7 +685,7 @@ dst_reg::dst_reg(class vec4_visitor *v, const struct glsl_type *type)
    init();
 
    this->file = GRF;
-   this->reg = v->alloc.allocate(v->type_size(type));
+   this->reg = v->alloc.allocate(type_size_vec4(type));
 
    if (type->is_array() || type->is_record()) {
       this->writemask = WRITEMASK_XYZW;
@@ -697,18 +697,21 @@ dst_reg::dst_reg(class vec4_visitor *v, const struct glsl_type *type)
 }
 
 void
-vec4_visitor::setup_vector_uniform_values(const gl_constant_value *values,
-                                          unsigned n)
+vec4_visitor::setup_vec4_uniform_value(unsigned param_offset,
+                                       const gl_constant_value *values,
+                                       unsigned n)
 {
    static const gl_constant_value zero = { 0 };
 
+   assert(param_offset % 4 == 0);
+
    for (unsigned i = 0; i < n; ++i)
-      stage_prog_data->param[4 * uniforms + i] = &values[i];
+      stage_prog_data->param[param_offset + i] = &values[i];
 
    for (unsigned i = n; i < 4; ++i)
-      stage_prog_data->param[4 * uniforms + i] = &zero;
+      stage_prog_data->param[param_offset + i] = &zero;
 
-   uniform_vector_size[uniforms++] = n;
+   uniform_vector_size[param_offset / 4] = n;
 }
 
 /* Our support for uniforms is piggy-backed on the struct
@@ -744,9 +747,12 @@ vec4_visitor::setup_uniform_values(ir_variable *ir)
                                      storage->type->matrix_columns);
       const unsigned vector_size = storage->type->vector_elements;
 
-      for (unsigned s = 0; s < vector_count; s++)
-         setup_vector_uniform_values(&storage->storage[s * vector_size],
-                                     vector_size);
+      for (unsigned s = 0; s < vector_count; s++) {
+         setup_vec4_uniform_value(uniforms * 4,
+                                  &storage->storage[s * vector_size],
+                                  vector_size);
+         uniforms++;
+      }
    }
 }
 
@@ -1070,7 +1076,7 @@ vec4_visitor::visit(ir_variable *ir)
       assert(ir->data.location != -1);
       reg = new(mem_ctx) dst_reg(this, ir->type);
 
-      for (int i = 0; i < type_size(ir->type); i++) {
+      for (int i = 0; i < type_size_vec4(ir->type); i++) {
         output_reg[ir->data.location + i] = *reg;
         output_reg[ir->data.location + i].reg_offset = i;
         output_reg_annotation[ir->data.location + i] = ir->name;
@@ -1092,14 +1098,14 @@ vec4_visitor::visit(ir_variable *ir)
        * Some uniforms, such as samplers and atomic counters, have no actual
        * storage, so we should ignore them.
        */
-      if (ir->is_in_buffer_block() || type_size(ir->type) == 0)
+      if (ir->is_in_buffer_block() || type_size_vec4(ir->type) == 0)
          return;
 
       /* Track how big the whole uniform variable is, in case we need to put a
        * copy of its data into pull constants for array access.
        */
       assert(this->uniforms < uniform_array_size);
-      this->uniform_size[this->uniforms] = type_size(ir->type);
+      this->uniform_size[this->uniforms] = type_size_vec4(ir->type);
 
       if (!strncmp(ir->name, "gl_", 3)) {
         setup_builtin_uniform_values(ir);
@@ -2052,7 +2058,7 @@ vec4_visitor::compute_array_stride(ir_dereference_array *ir)
    /* Under normal circumstances array elements are stored consecutively, so
     * the stride is equal to the size of the array element.
     */
-   return type_size(ir->type);
+   return type_size_vec4(ir->type);
 }
 
 
@@ -2121,7 +2127,7 @@ vec4_visitor::visit(ir_dereference_record *ir)
    for (i = 0; i < struct_type->length; i++) {
       if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
         break;
-      offset += type_size(struct_type->fields.structure[i].type);
+      offset += type_size_vec4(struct_type->fields.structure[i].type);
    }
 
    /* If the type is smaller than a vec4, replicate the last channel out. */
@@ -2330,7 +2336,7 @@ vec4_visitor::visit(ir_assignment *ir)
       emit_bool_to_cond_code(ir->condition, &predicate);
    }
 
-   for (i = 0; i < type_size(ir->lhs->type); i++) {
+   for (i = 0; i < type_size_vec4(ir->lhs->type); i++) {
       vec4_instruction *inst = emit(MOV(dst, src));
       inst->predicate = predicate;