diff options
Diffstat (limited to 'src/freedreno/ir3/ir3_image.c')
-rw-r--r-- | src/freedreno/ir3/ir3_image.c | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/src/freedreno/ir3/ir3_image.c b/src/freedreno/ir3/ir3_image.c new file mode 100644 index 00000000000..bc564aac402 --- /dev/null +++ b/src/freedreno/ir3/ir3_image.c @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2017-2018 Rob Clark <[email protected]> + * + * 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. + * + * Authors: + * Rob Clark <[email protected]> + */ + +#include "ir3_image.h" + +/* Images get mapped into SSBO/image state (for store/atomic) and texture + * state block (for load). To simplify things, invert the image id and + * map it from end of state block, ie. image 0 becomes num-1, image 1 + * becomes num-2, etc. This potentially avoids needing to re-emit texture + * state when switching shaders. + * + * TODO is max # of samplers and SSBOs the same. This shouldn't be hard- + * coded. Also, since all the gl shader stages (ie. everything but CS) + * share the same SSBO/image state block, this might require some more + * logic if we supported images in anything other than FS.. + */ +unsigned +ir3_get_image_slot(struct ir3_context *ctx, nir_deref_instr *deref) +{ + unsigned int loc = 0; + unsigned inner_size = 1; + + while (deref->deref_type != nir_deref_type_var) { + assert(deref->deref_type == nir_deref_type_array); + nir_const_value *const_index = nir_src_as_const_value(deref->arr.index); + assert(const_index); + + /* Go to the next instruction */ + deref = nir_deref_instr_parent(deref); + + assert(glsl_type_is_array(deref->type)); + const unsigned array_len = glsl_get_length(deref->type); + loc += MIN2(const_index->u32[0], array_len - 1) * inner_size; + + /* Update the inner size */ + inner_size *= array_len; + } + + loc += deref->var->data.driver_location; + + /* TODO figure out real limit per generation, and don't hardcode: */ + const unsigned max_samplers = 16; + return max_samplers - loc - 1; +} + +/* see tex_info() for equiv logic for texture instructions.. it would be + * nice if this could be better unified.. + */ +unsigned +ir3_get_image_coords(const nir_variable *var, unsigned *flagsp) +{ + const struct glsl_type *type = glsl_without_array(var->type); + unsigned coords, flags = 0; + + switch (glsl_get_sampler_dim(type)) { + case GLSL_SAMPLER_DIM_1D: + case GLSL_SAMPLER_DIM_BUF: + coords = 1; + break; + case GLSL_SAMPLER_DIM_2D: + case GLSL_SAMPLER_DIM_RECT: + case GLSL_SAMPLER_DIM_EXTERNAL: + case GLSL_SAMPLER_DIM_MS: + coords = 2; + break; + case GLSL_SAMPLER_DIM_3D: + case GLSL_SAMPLER_DIM_CUBE: + flags |= IR3_INSTR_3D; + coords = 3; + break; + default: + unreachable("bad sampler dim"); + return 0; + } + + if (glsl_sampler_type_is_array(type)) { + /* note: unlike tex_info(), adjust # of coords to include array idx: */ + coords++; + flags |= IR3_INSTR_A; + } + + if (flagsp) + *flagsp = flags; + + return coords; +} + +type_t +ir3_get_image_type(const nir_variable *var) +{ + switch (glsl_get_sampler_result_type(glsl_without_array(var->type))) { + case GLSL_TYPE_UINT: + return TYPE_U32; + case GLSL_TYPE_INT: + return TYPE_S32; + case GLSL_TYPE_FLOAT: + return TYPE_F32; + default: + unreachable("bad sampler type."); + return 0; + } +} + +/* Returns the number of components for the different image formats + * supported by the GLES 3.1 spec, plus those added by the + * GL_NV_image_formats extension. + */ +unsigned +ir3_get_num_components_for_glformat(GLuint format) +{ + switch (format) { + case GL_R32F: + case GL_R32I: + case GL_R32UI: + case GL_R16F: + case GL_R16I: + case GL_R16UI: + case GL_R16: + case GL_R16_SNORM: + case GL_R8I: + case GL_R8UI: + case GL_R8: + case GL_R8_SNORM: + return 1; + + case GL_RG32F: + case GL_RG32I: + case GL_RG32UI: + case GL_RG16F: + case GL_RG16I: + case GL_RG16UI: + case GL_RG16: + case GL_RG16_SNORM: + case GL_RG8I: + case GL_RG8UI: + case GL_RG8: + case GL_RG8_SNORM: + return 2; + + case GL_R11F_G11F_B10F: + return 3; + + case GL_RGBA32F: + case GL_RGBA32I: + case GL_RGBA32UI: + case GL_RGBA16F: + case GL_RGBA16I: + case GL_RGBA16UI: + case GL_RGBA16: + case GL_RGBA16_SNORM: + case GL_RGBA8I: + case GL_RGBA8UI: + case GL_RGBA8: + case GL_RGBA8_SNORM: + case GL_RGB10_A2UI: + case GL_RGB10_A2: + return 4; + + case GL_NONE: + /* Omitting the image format qualifier is allowed on desktop GL + * profiles. Assuming 4 components is always safe. + */ + return 4; + + default: + /* Return 4 components also for all other formats we don't know + * about. The format should have been validated already by + * the higher level API, but drop a debug message just in case. + */ + debug_printf("Unhandled GL format %u while emitting imageStore()\n", + format); + return 4; + } +} |