From de0e62e1065e2d9172acf3ab7c70bba0160125c8 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Tue, 1 Aug 2017 17:35:07 +1000 Subject: [PATCH] st/mesa: correctly calculate the storage offset When generating the storage offset for struct members we need to skip opaque types as they no longer have backing storage. Fixes: fcbb93e86024 ("mesa: stop assigning unused storage for non-bindless opaque types") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101983 Reviewed-by: Dave Airlie --- src/mesa/Makefile.sources | 2 + src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 16 ++++- src/mesa/state_tracker/st_glsl_types.cpp | 105 +++++++++++++++++++++++++++++ src/mesa/state_tracker/st_glsl_types.h | 44 ++++++++++++ 4 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 src/mesa/state_tracker/st_glsl_types.cpp create mode 100644 src/mesa/state_tracker/st_glsl_types.h diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources index b38e858..e65b091 100644 --- a/src/mesa/Makefile.sources +++ b/src/mesa/Makefile.sources @@ -511,6 +511,8 @@ STATETRACKER_FILES = \ state_tracker/st_glsl_to_nir.cpp \ state_tracker/st_glsl_to_tgsi.cpp \ state_tracker/st_glsl_to_tgsi.h \ + state_tracker/st_glsl_types.cpp \ + state_tracker/st_glsl_types.h \ state_tracker/st_manager.c \ state_tracker/st_manager.h \ state_tracker/st_mesa_to_tgsi.c \ diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index e8f7eca..f4f3092 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 0000000..5093602 --- /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 0000000..915816d --- /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__ */ -- 2.7.4