diff options
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r-- | src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 16 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_glsl_types.cpp | 105 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_glsl_types.h | 44 |
3 files changed, 163 insertions, 2 deletions
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index e8f7ecac929..f4f3092fe02 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -49,6 +49,7 @@ #include "tgsi/tgsi_info.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "st_glsl_types.h" #include "st_program.h" #include "st_mesa_to_tgsi.h" #include "st_format.h" @@ -2832,8 +2833,16 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array *ir) { ir_constant *index; st_src_reg src; - int element_size = type_size(ir->type); bool is_2D = false; + ir_variable *var = ir->variable_referenced(); + + /* We only need the logic provided by st_glsl_storage_type_size() + * for arrays of structs. Indirect sampler and image indexing is handled + * elsewhere. + */ + int element_size = ir->type->without_array()->is_record() ? + st_glsl_storage_type_size(ir->type, var->data.bindless) : + type_size(ir->type); index = ir->array_index->constant_expression_value(ralloc_parent(ir)); @@ -2923,15 +2932,18 @@ glsl_to_tgsi_visitor::visit(ir_dereference_record *ir) { unsigned int i; const glsl_type *struct_type = ir->record->type; + ir_variable *var = ir->record->variable_referenced(); int offset = 0; ir->record->accept(this); assert(ir->field_idx >= 0); + assert(var); for (i = 0; i < struct_type->length; i++) { if (i == (unsigned) ir->field_idx) break; - offset += type_size(struct_type->fields.structure[i].type); + const glsl_type *member_type = struct_type->fields.structure[i].type; + offset += st_glsl_storage_type_size(member_type, var->data.bindless); } /* If the type is smaller than a vec4, replicate the last channel out. */ diff --git a/src/mesa/state_tracker/st_glsl_types.cpp b/src/mesa/state_tracker/st_glsl_types.cpp new file mode 100644 index 00000000000..50936025d9f --- /dev/null +++ b/src/mesa/state_tracker/st_glsl_types.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. + * Copyright (C) 2008 VMware, Inc. All Rights Reserved. + * Copyright © 2010 Intel Corporation + * Copyright © 2011 Bryan Cain + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "st_glsl_types.h" + +/** + * Returns the number of places to offset the uniform index, given the type of + * a struct member. We use this because samplers and images have backing + * storeage only when they are bindless. + */ +int +st_glsl_storage_type_size(const struct glsl_type *type, bool is_bindless) +{ + 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) + 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) + return 1; + else + return 2; + } + break; + case GLSL_TYPE_UINT64: + case GLSL_TYPE_INT64: + if (type->vector_elements <= 2) + return 1; + else + return 2; + case GLSL_TYPE_ARRAY: + assert(type->length > 0); + return st_glsl_storage_type_size(type->fields.array, is_bindless) * + type->length; + case GLSL_TYPE_STRUCT: + size = 0; + for (i = 0; i < type->length; i++) { + size += st_glsl_storage_type_size(type->fields.structure[i].type, + is_bindless); + } + return size; + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: + if (!is_bindless) + return 0; + /* fall through */ + case GLSL_TYPE_SUBROUTINE: + return 1; + case GLSL_TYPE_ATOMIC_UINT: + case GLSL_TYPE_INTERFACE: + case GLSL_TYPE_VOID: + case GLSL_TYPE_ERROR: + case GLSL_TYPE_FUNCTION: + assert(!"Invalid type in type_size"); + break; + } + return 0; +} diff --git a/src/mesa/state_tracker/st_glsl_types.h b/src/mesa/state_tracker/st_glsl_types.h new file mode 100644 index 00000000000..915816d1fa0 --- /dev/null +++ b/src/mesa/state_tracker/st_glsl_types.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. + * Copyright (C) 2008 VMware, Inc. All Rights Reserved. + * Copyright © 2010 Intel Corporation + * Copyright © 2011 Bryan Cain + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __ST_GLSL_TYPES_H__ +#define __ST_GLSL_TYPES_H__ + +#include "compiler/glsl_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int st_glsl_storage_type_size(const struct glsl_type *type, + bool is_bindless); + + +#ifdef __cplusplus +} +#endif + +#endif /* __ST_GLSL_TYPES_H__ */ |