summaryrefslogtreecommitdiffstats
path: root/src/freedreno/ir3/ir3_image.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/freedreno/ir3/ir3_image.c')
-rw-r--r--src/freedreno/ir3/ir3_image.c197
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;
+ }
+}