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
