Module: Mesa
Branch: master
Commit: 8e6ed9948eb410fb9df441affc4ff289e4129a49
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=8e6ed9948eb410fb9df441affc4ff289e4129a49

Author: Danylo Piliaiev <[email protected]>
Date:   Mon Mar  8 18:31:09 2021 +0200

freedreno/a5xx: port handling of PIPE_BUFFER textures from a6xx

Otherwise, we won't be able to use OPC_GETBUF to get their size.

After this change we also could get rid of the hack for OPC_GETSIZE
which scaled the size for texture buffers.

Signed-off-by: Danylo Piliaiev <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9391>

---

 src/freedreno/ir3/ir3_compiler_nir.c             | 23 -------
 src/freedreno/registers/adreno/a5xx.xml          |  9 +++
 src/gallium/drivers/freedreno/a5xx/fd5_image.c   | 85 ++++++++++++++----------
 src/gallium/drivers/freedreno/a5xx/fd5_texture.c |  7 +-
 4 files changed, 62 insertions(+), 62 deletions(-)

diff --git a/src/freedreno/ir3/ir3_compiler_nir.c 
b/src/freedreno/ir3/ir3_compiler_nir.c
index 5178313d803..7ae85ce74cc 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -1270,29 +1270,6 @@ emit_intrinsic_image_size_tex(struct ir3_context *ctx, 
nir_intrinsic_instr *intr
 
        ir3_split_dest(b, tmp, sam, 0, 4);
 
-       /* get_size instruction returns size in bytes instead of texels
-        * for imageBuffer, so we need to divide it by the pixel size
-        * of the image format.
-        *
-        * TODO: This is at least true on a5xx. Check other gens.
-        */
-       if (nir_intrinsic_image_dim(intr) == GLSL_SAMPLER_DIM_BUF) {
-               /* Since all the possible values the divisor can take are
-                * power-of-two (4, 8, or 16), the division is implemented
-                * as a shift-right.
-                * During shader setup, the log2 of the image format's
-                * bytes-per-pixel should have been emitted in 2nd slot of
-                * image_dims. See ir3_shader::emit_image_dims().
-                */
-               const struct ir3_const_state *const_state =
-                               ir3_const_state(ctx->so);
-               unsigned cb = regid(const_state->offsets.image_dims, 0) +
-                       
const_state->image_dims.off[nir_src_as_uint(intr->src[0])];
-               struct ir3_instruction *aux = create_uniform(b, cb + 1);
-
-               tmp[0] = ir3_SHR_B(b, tmp[0], 0, aux, 0);
-       }
-
        for (unsigned i = 0; i < ncoords; i++)
                dst[i] = tmp[i];
 
diff --git a/src/freedreno/registers/adreno/a5xx.xml 
b/src/freedreno/registers/adreno/a5xx.xml
index e298c15bd16..e4991f270d3 100644
--- a/src/freedreno/registers/adreno/a5xx.xml
+++ b/src/freedreno/registers/adreno/a5xx.xml
@@ -2905,11 +2905,20 @@ different border-color states per texture..  Looks 
something like:
                <bitfield name="HEIGHT" low="15" high="29" type="uint"/>
        </reg32>
        <reg32 offset="2" name="2">
+               <!--
+               b4 and b31 set for buffer/ssbo case, in which case low 15 bits
+               of size encoded in WIDTH, and high 15 bits encoded in HEIGHT
+
+               b31 is probably the 'BUFFER' bit.. it is the one that changes
+               behavior of texture in 
dEQP-GLES31.functional.texture.texture_buffer.render.as_fragment_texture.buffer_size_131071
+                -->
+               <bitfield name="UNK4" pos="4" type="boolean"/>
                <!-- minimum pitch (for mipmap levels): log2(pitchalign / 64) 
-->
                <bitfield name="PITCHALIGN" low="0" high="3" type="uint"/>
                <doc>Pitch in bytes (so actually stride)</doc>
                <bitfield name="PITCH" low="7" high="28" type="uint"/>
                <bitfield name="TYPE" low="29" high="30" type="a5xx_tex_type"/>
+               <bitfield name="UNK31" pos="31" type="boolean"/>
        </reg32>
        <reg32 offset="3" name="3">
                <!--
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_image.c 
b/src/gallium/drivers/freedreno/a5xx/fd5_image.c
index bec6909f946..6c2bb490d3a 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_image.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_image.c
@@ -54,6 +54,7 @@ struct fd5_image {
        uint32_t array_pitch;
        struct fd_bo *bo;
        uint32_t offset;
+       bool buffer;
 };
 
 static void translate_image(struct fd5_image *img, struct pipe_image_view 
*pimg)
@@ -61,7 +62,6 @@ static void translate_image(struct fd5_image *img, struct 
pipe_image_view *pimg)
        enum pipe_format format = pimg->format;
        struct pipe_resource *prsc = pimg->resource;
        struct fd_resource *rsc = fd_resource(prsc);
-       unsigned lvl;
 
        if (!pimg->resource) {
                memset(img, 0, sizeof(*img));
@@ -80,45 +80,56 @@ static void translate_image(struct fd5_image *img, struct 
pipe_image_view *pimg)
                img->type = A5XX_TEX_2D;
 
        if (prsc->target == PIPE_BUFFER) {
-               lvl = 0;
+               img->buffer = true;
                img->offset = pimg->u.buf.offset;
-               img->pitch  = pimg->u.buf.size;
+               img->pitch  = 0;
+               img->array_pitch  = 0;
+
+               /* size is encoded with low 15b in WIDTH and high bits in
+                * HEIGHT, in units of elements:
+                */
+               unsigned sz = pimg->u.buf.size / 
util_format_get_blocksize(format);
+               img->width  = sz & MASK(15);
+               img->height = sz >> 15;
+               img->depth  = 0;
        } else {
-               lvl = pimg->u.tex.level;
+               img->buffer = false;
+
+               unsigned lvl = pimg->u.tex.level;
                img->offset = fd_resource_offset(rsc, lvl, 
pimg->u.tex.first_layer);
                img->pitch  = fd_resource_pitch(rsc, lvl);
-       }
 
-       img->width     = u_minify(prsc->width0, lvl);
-       img->height    = u_minify(prsc->height0, lvl);
-
-       unsigned layers = pimg->u.tex.last_layer - pimg->u.tex.first_layer + 1;
-
-       switch (prsc->target) {
-       case PIPE_TEXTURE_RECT:
-       case PIPE_TEXTURE_1D:
-       case PIPE_TEXTURE_2D:
-               img->array_pitch = rsc->layout.layer_size;
-               img->depth = 1;
-               break;
-       case PIPE_TEXTURE_1D_ARRAY:
-       case PIPE_TEXTURE_2D_ARRAY:
-               img->array_pitch = rsc->layout.layer_size;
-               img->depth = layers;
-               break;
-       case PIPE_TEXTURE_CUBE:
-       case PIPE_TEXTURE_CUBE_ARRAY:
-               img->array_pitch = rsc->layout.layer_size;
-               img->depth = layers;
-               break;
-       case PIPE_TEXTURE_3D:
-               img->array_pitch = fd_resource_slice(rsc, lvl)->size0;
-               img->depth = u_minify(prsc->depth0, lvl);
-               break;
-       default:
-               img->array_pitch = 0;
-               img->depth = 0;
-               break;
+               img->width     = u_minify(prsc->width0, lvl);
+               img->height    = u_minify(prsc->height0, lvl);
+
+               unsigned layers = pimg->u.tex.last_layer - 
pimg->u.tex.first_layer + 1;
+
+               switch (prsc->target) {
+               case PIPE_TEXTURE_RECT:
+               case PIPE_TEXTURE_1D:
+               case PIPE_TEXTURE_2D:
+                       img->array_pitch = rsc->layout.layer_size;
+                       img->depth = 1;
+                       break;
+               case PIPE_TEXTURE_1D_ARRAY:
+               case PIPE_TEXTURE_2D_ARRAY:
+                       img->array_pitch = rsc->layout.layer_size;
+                       img->depth = layers;
+                       break;
+               case PIPE_TEXTURE_CUBE:
+               case PIPE_TEXTURE_CUBE_ARRAY:
+                       img->array_pitch = rsc->layout.layer_size;
+                       img->depth = layers;
+                       break;
+               case PIPE_TEXTURE_3D:
+                       img->array_pitch = fd_resource_slice(rsc, lvl)->size0;
+                       img->depth = u_minify(prsc->depth0, lvl);
+                       break;
+               default:
+                       img->array_pitch = 0;
+                       img->depth = 0;
+                       break;
+               }
        }
 }
 
@@ -140,7 +151,9 @@ static void emit_image_tex(struct fd_ringbuffer *ring, 
unsigned slot,
                COND(img->srgb, A5XX_TEX_CONST_0_SRGB));
        OUT_RING(ring, A5XX_TEX_CONST_1_WIDTH(img->width) |
                A5XX_TEX_CONST_1_HEIGHT(img->height));
-       OUT_RING(ring, A5XX_TEX_CONST_2_TYPE(img->type) |
+       OUT_RING(ring,
+               COND(img->buffer, A5XX_TEX_CONST_2_UNK4 | 
A5XX_TEX_CONST_2_UNK31) |
+               A5XX_TEX_CONST_2_TYPE(img->type) |
                A5XX_TEX_CONST_2_PITCH(img->pitch));
        OUT_RING(ring, A5XX_TEX_CONST_3_ARRAY_PITCH(img->array_pitch));
        if (img->bo) {
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_texture.c 
b/src/gallium/drivers/freedreno/a5xx/fd5_texture.c
index 0d6191d19dd..d1e15e0c1cb 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_texture.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_texture.c
@@ -185,10 +185,11 @@ fd5_sampler_view_create(struct pipe_context *pctx, struct 
pipe_resource *prsc,
 
                lvl = 0;
                so->texconst1 =
-                       A5XX_TEX_CONST_1_WIDTH(elements) |
-                       A5XX_TEX_CONST_1_HEIGHT(1);
+                       A5XX_TEX_CONST_1_WIDTH(elements & MASK(15)) |
+                       A5XX_TEX_CONST_1_HEIGHT(elements >> 15);
                so->texconst2 =
-                       A5XX_TEX_CONST_2_PITCH(elements * rsc->layout.cpp);
+                       A5XX_TEX_CONST_2_UNK4 |
+                       A5XX_TEX_CONST_2_UNK31;
                so->offset = cso->u.buf.offset;
        } else {
                unsigned miplevels;

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to