[Mesa-dev] [RFCv3 03/11] nir: add helper to calculate type size
Rob Clark
robdclark at gmail.com
Mon Feb 1 15:51:17 UTC 2016
fwiw, I should have mentioned that current home in 'nir_types.cpp' was
somewhat arbitrary.. I just needed to stuff it somewhere and didn't
have a better idea at the time.
As far as de-dup'ing, I think the remaining variant of this is just in
i956? Should be maybe not so hard to remove that one, since the tgsi
version was mostly a superset. Although there were some differences
w/ GLSL_TYPE_SAMPLER/IMAGE/SUBROUTINE, which I wasn't sure how to deal
with. So I punted.
(Note that I almost put this in mesa/st, but I need it from ir3.. I
suppose gallium/aux might be a reasonable home, depending on
resolution of i965 vs gallium sampler/image/subroutine)
BR,
-R
On Mon, Feb 1, 2016 at 10:35 AM, Connor Abbott <cwabbott0 at gmail.com> wrote:
> 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