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 <dpiliaiev@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9391>
This commit is contained in:
Danylo Piliaiev 2021-03-08 18:31:09 +02:00 committed by Marge Bot
parent d968995c67
commit 8e6ed9948e
4 changed files with 60 additions and 60 deletions

View File

@ -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];

View File

@ -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">
<!--

View File

@ -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);
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;
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;
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) {

View File

@ -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;