[Mesa-dev] [RFCv3 03/11] nir: add helper to calculate type size
Connor Abbott
cwabbott0 at gmail.com
Mon Feb 1 15:35:35 UTC 2016
A few things:
- How much work would it take to actually deduplicate this with the
other vec4 type_size implementations out there? I'm pretty sure no one
would object to it, and if we just leave this as a TODO it probably
won't actually get done.
- Having to include nir_types.h in something that has nothing to do
with NIR doesn't seem so great. It would probably be cleaner to
introduce this as a method in ir_types.h and then wrap it like we do
with everything else. This one isn't as important, though.
On Sun, Jan 31, 2016 at 3:16 PM, Rob Clark <robdclark at gmail.com> wrote:
> 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