[Mesa-dev] [RFCv3 03/11] nir: add helper to calculate type size
Rob Clark
robdclark at gmail.com
Sun Jan 31 12:16:11 PST 2016
From: Rob Clark <robclark at freedesktop.org>
Currently the vec4 version of this is duplicated in brw and mesa/st
(although the mesa/st version handles 64b types). There is also a
scalar version floating around in brw. We should consolidate all of
these.
Signed-off-by: Rob Clark <robclark at freedesktop.org>
---
src/compiler/nir_types.cpp | 75 ++++++++++++++++++++
src/compiler/nir_types.h | 3 +
src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 107 +++++------------------------
3 files changed, 97 insertions(+), 88 deletions(-)
diff --git a/src/compiler/nir_types.cpp b/src/compiler/nir_types.cpp
index a87dcd8..3ff828a 100644
--- a/src/compiler/nir_types.cpp
+++ b/src/compiler/nir_types.cpp
@@ -190,3 +190,78 @@ glsl_array_type(const glsl_type *base, unsigned elements)
{
return glsl_type::get_array_instance(base, elements);
}
+
+/* TODO dup'd from brw_vec4_vistor.cpp.. what should we do?
+ * TODO probably should copy the scalar version to, and de-dup
+ * equiv fxns from mesa/st and brw..
+ */
+
+int
+glsl_attrib_type_size_vec4(const struct glsl_type *type, bool is_vs_input)
+{
+ unsigned int i;
+ int size;
+
+ switch (type->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_BOOL:
+ if (type->is_matrix()) {
+ return type->matrix_columns;
+ } else {
+ /* Regardless of size of vector, it gets a vec4. This is bad
+ * packing for things like floats, but otherwise arrays become a
+ * mess. Hopefully a later pass over the code can pack scalars
+ * down if appropriate.
+ */
+ return 1;
+ }
+ break;
+ case GLSL_TYPE_DOUBLE:
+ if (type->is_matrix()) {
+ if (type->vector_elements <= 2 || is_vs_input)
+ return type->matrix_columns;
+ else
+ return type->matrix_columns * 2;
+ } else {
+ /* For doubles if we have a double or dvec2 they fit in one
+ * vec4, else they need 2 vec4s.
+ */
+ if (type->vector_elements <= 2 || is_vs_input)
+ return 1;
+ else
+ return 2;
+ }
+ break;
+ case GLSL_TYPE_ARRAY:
+ assert(type->length > 0);
+ return glsl_attrib_type_size_vec4(type->fields.array, is_vs_input) * type->length;
+ case GLSL_TYPE_STRUCT:
+ size = 0;
+ for (i = 0; i < type->length; i++) {
+ size += glsl_attrib_type_size_vec4(type->fields.structure[i].type, is_vs_input);
+ }
+ return size;
+ case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_IMAGE:
+ case GLSL_TYPE_SUBROUTINE:
+ /* Samplers take up one slot in UNIFORMS[], but they're baked in
+ * at link time.
+ */
+ return 1;
+ case GLSL_TYPE_ATOMIC_UINT:
+ case GLSL_TYPE_INTERFACE:
+ case GLSL_TYPE_VOID:
+ case GLSL_TYPE_ERROR:
+ assert(!"Invalid type in type_size");
+ break;
+ }
+ return 0;
+}
+
+int
+glsl_type_size_vec4(const struct glsl_type *type)
+{
+ return glsl_attrib_type_size_vec4(type, false);
+}
diff --git a/src/compiler/nir_types.h b/src/compiler/nir_types.h
index 32fc766..fbf458d 100644
--- a/src/compiler/nir_types.h
+++ b/src/compiler/nir_types.h
@@ -82,6 +82,9 @@ const struct glsl_type *glsl_uint_type(void);
const struct glsl_type *glsl_array_type(const struct glsl_type *base,
unsigned elements);
+int glsl_attrib_type_size_vec4(const struct glsl_type *type, bool is_vs_input);
+int glsl_type_size_vec4(const struct glsl_type *type);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index baf3504..d6459e5 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -34,6 +34,7 @@
#include "compiler/glsl/glsl_parser_extras.h"
#include "compiler/glsl/ir_optimization.h"
+#include "compiler/nir_types.h"
#include "main/errors.h"
#include "main/shaderobj.h"
@@ -1142,76 +1143,6 @@ glsl_to_tgsi_visitor::st_src_reg_for_type(int type, int val)
return st_src_reg_for_float(val);
}
-static int
-attrib_type_size(const struct glsl_type *type, bool is_vs_input)
-{
- unsigned int i;
- int size;
-
- switch (type->base_type) {
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_INT:
- case GLSL_TYPE_FLOAT:
- case GLSL_TYPE_BOOL:
- if (type->is_matrix()) {
- return type->matrix_columns;
- } else {
- /* Regardless of size of vector, it gets a vec4. This is bad
- * packing for things like floats, but otherwise arrays become a
- * mess. Hopefully a later pass over the code can pack scalars
- * down if appropriate.
- */
- return 1;
- }
- break;
- case GLSL_TYPE_DOUBLE:
- if (type->is_matrix()) {
- if (type->vector_elements <= 2 || is_vs_input)
- return type->matrix_columns;
- else
- return type->matrix_columns * 2;
- } else {
- /* For doubles if we have a double or dvec2 they fit in one
- * vec4, else they need 2 vec4s.
- */
- if (type->vector_elements <= 2 || is_vs_input)
- return 1;
- else
- return 2;
- }
- break;
- case GLSL_TYPE_ARRAY:
- assert(type->length > 0);
- return attrib_type_size(type->fields.array, is_vs_input) * type->length;
- case GLSL_TYPE_STRUCT:
- size = 0;
- for (i = 0; i < type->length; i++) {
- size += attrib_type_size(type->fields.structure[i].type, is_vs_input);
- }
- return size;
- case GLSL_TYPE_SAMPLER:
- case GLSL_TYPE_IMAGE:
- case GLSL_TYPE_SUBROUTINE:
- /* Samplers take up one slot in UNIFORMS[], but they're baked in
- * at link time.
- */
- return 1;
- case GLSL_TYPE_ATOMIC_UINT:
- case GLSL_TYPE_INTERFACE:
- case GLSL_TYPE_VOID:
- case GLSL_TYPE_ERROR:
- assert(!"Invalid type in type_size");
- break;
- }
- return 0;
-}
-
-static int
-type_size(const struct glsl_type *type)
-{
- return attrib_type_size(type, false);
-}
-
/**
* If the given GLSL type is an array or matrix or a structure containing
* an array/matrix member, return true. Else return false.
@@ -1262,13 +1193,13 @@ glsl_to_tgsi_visitor::get_temp(const glsl_type *type)
src.file = PROGRAM_ARRAY;
src.index = next_array << 16 | 0x8000;
- array_sizes[next_array] = type_size(type);
+ array_sizes[next_array] = glsl_type_size_vec4(type);
++next_array;
} else {
src.file = PROGRAM_TEMPORARY;
src.index = next_temp;
- next_temp += type_size(type);
+ next_temp += glsl_type_size_vec4(type);
}
if (type->is_array() || type->is_record()) {
@@ -1332,7 +1263,7 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir)
* of the type. However, this had better match the number of state
* elements that we're going to copy into the new temporary.
*/
- assert((int) ir->get_num_state_slots() == type_size(ir->type));
+ assert((int) ir->get_num_state_slots() == glsl_type_size_vec4(ir->type));
dst = st_dst_reg(get_temp(ir->type));
@@ -1371,7 +1302,7 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir)
fail_link(this->shader_program,
"failed to load builtin uniform `%s' (%d/%d regs loaded)\n",
ir->name, dst.index - storage->index,
- type_size(ir->type));
+ glsl_type_size_vec4(ir->type));
}
}
}
@@ -2370,10 +2301,10 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
decl->mesa_index = var->data.location;
decl->array_id = num_input_arrays + 1;
if (is_2d) {
- decl->array_size = type_size(var->type->fields.array);
+ decl->array_size = glsl_type_size_vec4(var->type->fields.array);
decl->array_type = var->type->fields.array->without_array()->base_type;
} else {
- decl->array_size = type_size(var->type);
+ decl->array_size = glsl_type_size_vec4(var->type);
decl->array_type = var->type->without_array()->base_type;
}
num_input_arrays++;
@@ -2399,10 +2330,10 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
decl->mesa_index = var->data.location;
decl->array_id = num_output_arrays + 1;
if (is_2d) {
- decl->array_size = type_size(var->type->fields.array);
+ decl->array_size = glsl_type_size_vec4(var->type->fields.array);
decl->array_type = var->type->fields.array->without_array()->base_type;
} else {
- decl->array_size = type_size(var->type);
+ decl->array_size = glsl_type_size_vec4(var->type);
decl->array_type = var->type->without_array()->base_type;
}
num_output_arrays++;
@@ -2506,7 +2437,7 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array *ir)
{
ir_constant *index;
st_src_reg src;
- int element_size = type_size(ir->type);
+ int element_size = glsl_type_size_vec4(ir->type);
bool is_2D = false;
index = ir->array_index->constant_expression_value();
@@ -2537,7 +2468,7 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array *ir)
if (this->prog->Target == GL_VERTEX_PROGRAM_ARB &&
src.file == PROGRAM_INPUT)
- element_size = attrib_type_size(ir->type, true);
+ element_size = glsl_attrib_type_size_vec4(ir->type, true);
if (is_2D) {
src.index2D = index->value.i[0];
src.has_index2 = true;
@@ -2610,7 +2541,7 @@ glsl_to_tgsi_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 += glsl_type_size_vec4(struct_type->fields.structure[i].type);
}
/* If the type is smaller than a vec4, replicate the last channel out. */
@@ -2911,7 +2842,7 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir)
} else if (ir->rhs->as_expression() &&
this->instructions.get_tail() &&
ir->rhs == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->ir &&
- type_size(ir->lhs->type) == 1 &&
+ glsl_type_size_vec4(ir->lhs->type) == 1 &&
l.writemask == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->dst[0].writemask) {
/* To avoid emitting an extra MOV when assigning an expression to a
* variable, emit the last instruction of the expression again, but
@@ -2950,7 +2881,7 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir)
st_dst_reg temp = st_dst_reg(temp_base);
foreach_in_list(ir_constant, field_value, &ir->components) {
- int size = type_size(field_value->type);
+ int size = glsl_type_size_vec4(field_value->type);
assert(size > 0);
@@ -2971,7 +2902,7 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir)
if (ir->type->is_array()) {
st_src_reg temp_base = get_temp(ir->type);
st_dst_reg temp = st_dst_reg(temp_base);
- int size = type_size(ir->type->fields.array);
+ int size = glsl_type_size_vec4(ir->type->fields.array);
assert(size > 0);
in_array++;
@@ -3394,7 +3325,7 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
l.writemask = WRITEMASK_XYZW;
l.cond_mask = COND_TR;
- for (i = 0; i < type_size(param->type); i++) {
+ for (i = 0; i < glsl_type_size_vec4(param->type); i++) {
emit_asm(ir, TGSI_OPCODE_MOV, l, r);
l.index++;
r.index++;
@@ -3427,7 +3358,7 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
param_rval->accept(this);
st_dst_reg l = st_dst_reg(this->result);
- for (i = 0; i < type_size(param->type); i++) {
+ for (i = 0; i < glsl_type_size_vec4(param->type); i++) {
emit_asm(ir, TGSI_OPCODE_MOV, l, r);
l.index++;
r.index++;
@@ -3562,7 +3493,7 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
const glsl_type *elt_type = ir->offset->type->fields.array;
for (i = 0; i < ir->offset->type->length; i++) {
offset[i] = this->result;
- offset[i].index += i * type_size(elt_type);
+ offset[i].index += i * glsl_type_size_vec4(elt_type);
offset[i].type = elt_type->base_type;
offset[i].swizzle = swizzle_for_size(elt_type->vector_elements);
}
@@ -3778,7 +3709,7 @@ glsl_to_tgsi_visitor::visit(ir_return *ir)
l = st_dst_reg(current_function->return_reg);
- for (i = 0; i < type_size(current_function->sig->return_type); i++) {
+ for (i = 0; i < glsl_type_size_vec4(current_function->sig->return_type); i++) {
emit_asm(ir, TGSI_OPCODE_MOV, l, r);
l.index++;
r.index++;
--
2.5.0
More information about the mesa-dev
mailing list