mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
freedreno/a6xx: Use fd6_view for non-buffer image descriptors, too.
This deletes a whole lot of code, but there's a modest drawoverhead perf loss: drawoverhead 1-image change -6.48856% +/- 4.28269% (n=50) drawoverhead 8-image change -5.29195% +/- 2.62549% (n=90) Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13443>
This commit is contained in:
parent
533e486923
commit
c90220e449
4 changed files with 48 additions and 251 deletions
|
|
@ -434,7 +434,7 @@ fd6_emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
|||
if (idx & IBO_SSBO) {
|
||||
fd6_emit_ssbo_tex(ctx, state, &buf->sb[idx & ~IBO_SSBO]);
|
||||
} else {
|
||||
fd6_emit_image_tex(state, &img->si[idx]);
|
||||
fd6_emit_image_tex(ctx, state, &img->si[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -77,181 +77,64 @@ fd6_ssbo_descriptor(struct fd_context *ctx,
|
|||
}
|
||||
|
||||
static void
|
||||
fd6_image_descriptor(struct fd_context *ctx, const struct pipe_image_view *buf,
|
||||
uint32_t *descriptor)
|
||||
fd6_emit_image_descriptor(struct fd_context *ctx, struct fd_ringbuffer *ring, const struct pipe_image_view *buf, bool ibo)
|
||||
{
|
||||
assert(buf->resource->target == PIPE_BUFFER);
|
||||
|
||||
fdl6_buffer_view_init(descriptor, buf->format, swiz_identity,
|
||||
buf->u.buf.offset, /* Using relocs for addresses */
|
||||
buf->u.buf.size);
|
||||
}
|
||||
|
||||
struct fd6_image {
|
||||
struct pipe_resource *prsc;
|
||||
enum pipe_format pfmt;
|
||||
enum a6xx_tex_type type;
|
||||
bool srgb;
|
||||
uint32_t cpp;
|
||||
uint32_t level;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t depth;
|
||||
uint32_t pitch;
|
||||
uint32_t array_pitch;
|
||||
struct fd_bo *bo;
|
||||
uint32_t ubwc_offset;
|
||||
uint32_t offset;
|
||||
bool buffer;
|
||||
};
|
||||
|
||||
static void
|
||||
translate_image(struct fd6_image *img, const struct pipe_image_view *pimg)
|
||||
{
|
||||
enum pipe_format format = pimg->format;
|
||||
struct pipe_resource *prsc = pimg->resource;
|
||||
struct fd_resource *rsc = fd_resource(prsc);
|
||||
|
||||
if (!prsc) {
|
||||
memset(img, 0, sizeof(*img));
|
||||
return;
|
||||
}
|
||||
|
||||
img->prsc = prsc;
|
||||
img->pfmt = format;
|
||||
img->type = fd6_tex_type(prsc->target);
|
||||
img->srgb = util_format_is_srgb(format);
|
||||
img->cpp = rsc->layout.cpp;
|
||||
img->bo = rsc->bo;
|
||||
|
||||
/* Treat cube textures as 2d-array: */
|
||||
if (img->type == A6XX_TEX_CUBE)
|
||||
img->type = A6XX_TEX_2D;
|
||||
|
||||
if (prsc->target == PIPE_BUFFER) {
|
||||
img->buffer = true;
|
||||
img->ubwc_offset = 0; /* not valid for buffers */
|
||||
img->offset = pimg->u.buf.offset;
|
||||
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;
|
||||
img->level = 0;
|
||||
} else {
|
||||
img->buffer = false;
|
||||
|
||||
unsigned lvl = pimg->u.tex.level;
|
||||
unsigned layers = pimg->u.tex.last_layer - pimg->u.tex.first_layer + 1;
|
||||
|
||||
img->ubwc_offset =
|
||||
fd_resource_ubwc_offset(rsc, lvl, pimg->u.tex.first_layer);
|
||||
img->offset = fd_resource_offset(rsc, lvl, pimg->u.tex.first_layer);
|
||||
img->pitch = fd_resource_pitch(rsc, lvl);
|
||||
|
||||
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:
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
case PIPE_TEXTURE_CUBE_ARRAY:
|
||||
img->array_pitch = rsc->layout.layer_size;
|
||||
// TODO the CUBE/CUBE_ARRAY might need to be layers/6 for tex state,
|
||||
// but empirically for ibo state it shouldn't be divided.
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
||||
img->level = lvl;
|
||||
img->width = u_minify(prsc->width0, lvl);
|
||||
img->height = u_minify(prsc->height0, lvl);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
emit_image_tex(struct fd_ringbuffer *ring, struct fd6_image *img)
|
||||
{
|
||||
if (!img->prsc) {
|
||||
struct fd_resource *rsc = fd_resource(buf->resource);
|
||||
if (!rsc) {
|
||||
for (int i = 0; i < FDL6_TEX_CONST_DWORDS; i++)
|
||||
OUT_RING(ring, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
struct fd_resource *rsc = fd_resource(img->prsc);
|
||||
bool ubwc_enabled = fd_resource_ubwc_enabled(rsc, img->level);
|
||||
|
||||
OUT_RING(ring,
|
||||
fd6_tex_const_0(img->prsc, img->level, img->pfmt, PIPE_SWIZZLE_X,
|
||||
PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W));
|
||||
OUT_RING(ring, A6XX_TEX_CONST_1_WIDTH(img->width) |
|
||||
A6XX_TEX_CONST_1_HEIGHT(img->height));
|
||||
OUT_RING(ring,
|
||||
COND(img->buffer, A6XX_TEX_CONST_2_UNK4 | A6XX_TEX_CONST_2_UNK31) |
|
||||
A6XX_TEX_CONST_2_TYPE(img->type) |
|
||||
A6XX_TEX_CONST_2_PITCH(img->pitch));
|
||||
OUT_RING(ring, A6XX_TEX_CONST_3_ARRAY_PITCH(img->array_pitch) |
|
||||
COND(ubwc_enabled, A6XX_TEX_CONST_3_FLAG) |
|
||||
COND(rsc->layout.tile_all, A6XX_TEX_CONST_3_TILE_ALL));
|
||||
if (img->bo) {
|
||||
OUT_RELOC(ring, img->bo, img->offset,
|
||||
(uint64_t)A6XX_TEX_CONST_5_DEPTH(img->depth) << 32, 0);
|
||||
if (buf->resource->target == PIPE_BUFFER) {
|
||||
uint32_t descriptor[FDL6_TEX_CONST_DWORDS];
|
||||
fdl6_buffer_view_init(descriptor, buf->format, swiz_identity,
|
||||
buf->u.buf.offset, /* Using relocs for addresses */
|
||||
buf->u.buf.size);
|
||||
fd6_emit_single_plane_descriptor(ring, buf->resource, descriptor);
|
||||
} else {
|
||||
OUT_RING(ring, 0x00000000);
|
||||
OUT_RING(ring, A6XX_TEX_CONST_5_DEPTH(img->depth));
|
||||
struct fdl_view_args args = {
|
||||
/* Using relocs for addresses */
|
||||
.iova = 0,
|
||||
|
||||
.base_miplevel = buf->u.tex.level,
|
||||
.level_count = 1,
|
||||
|
||||
.base_array_layer = buf->u.tex.first_layer,
|
||||
.layer_count = buf->u.tex.last_layer - buf->u.tex.first_layer + 1,
|
||||
|
||||
.format = buf->format,
|
||||
.swiz = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z,
|
||||
PIPE_SWIZZLE_W},
|
||||
|
||||
.type = fdl_type_from_pipe_target(buf->resource->target),
|
||||
.chroma_offsets = {FDL_CHROMA_LOCATION_COSITED_EVEN,
|
||||
FDL_CHROMA_LOCATION_COSITED_EVEN},
|
||||
};
|
||||
|
||||
/* fdl6_view makes the storage descriptor treat cubes like a 2D array (so
|
||||
* you can reference a specific layer), but we need to do that for the
|
||||
* texture descriptor as well to get our layer.
|
||||
*/
|
||||
if (args.type == FDL_VIEW_TYPE_CUBE)
|
||||
args.type = FDL_VIEW_TYPE_2D;
|
||||
|
||||
struct fdl6_view view;
|
||||
const struct fdl_layout *layouts[3] = {&rsc->layout, NULL, NULL};
|
||||
fdl6_view_init(&view, layouts, &args,
|
||||
ctx->screen->info->a6xx.has_z24uint_s8uint);
|
||||
if (ibo)
|
||||
fd6_emit_single_plane_descriptor(ring, buf->resource, view.storage_descriptor);
|
||||
else
|
||||
fd6_emit_single_plane_descriptor(ring, buf->resource, view.descriptor);
|
||||
}
|
||||
|
||||
OUT_RING(ring, 0x00000000); /* texconst6 */
|
||||
|
||||
if (ubwc_enabled) {
|
||||
uint32_t block_width, block_height;
|
||||
fdl6_get_ubwc_blockwidth(&rsc->layout, &block_width, &block_height);
|
||||
|
||||
OUT_RELOC(ring, rsc->bo, img->ubwc_offset, 0, 0);
|
||||
OUT_RING(ring, A6XX_TEX_CONST_9_FLAG_BUFFER_ARRAY_PITCH(
|
||||
rsc->layout.ubwc_layer_size >> 2));
|
||||
OUT_RING(ring, A6XX_TEX_CONST_10_FLAG_BUFFER_PITCH(
|
||||
fdl_ubwc_pitch(&rsc->layout, img->level)) |
|
||||
A6XX_TEX_CONST_10_FLAG_BUFFER_LOGW(util_logbase2_ceil(
|
||||
DIV_ROUND_UP(img->width, block_width))) |
|
||||
A6XX_TEX_CONST_10_FLAG_BUFFER_LOGH(util_logbase2_ceil(
|
||||
DIV_ROUND_UP(img->height, block_height))));
|
||||
} else {
|
||||
OUT_RING(ring, 0x00000000); /* texconst7 */
|
||||
OUT_RING(ring, 0x00000000); /* texconst8 */
|
||||
OUT_RING(ring, 0x00000000); /* texconst9 */
|
||||
OUT_RING(ring, 0x00000000); /* texconst10 */
|
||||
}
|
||||
|
||||
OUT_RING(ring, 0x00000000); /* texconst11 */
|
||||
OUT_RING(ring, 0x00000000); /* texconst12 */
|
||||
OUT_RING(ring, 0x00000000); /* texconst13 */
|
||||
OUT_RING(ring, 0x00000000); /* texconst14 */
|
||||
OUT_RING(ring, 0x00000000); /* texconst15 */
|
||||
}
|
||||
|
||||
void
|
||||
fd6_emit_image_tex(struct fd_ringbuffer *ring,
|
||||
fd6_emit_image_tex(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
const struct pipe_image_view *pimg)
|
||||
{
|
||||
struct fd6_image img;
|
||||
translate_image(&img, pimg);
|
||||
emit_image_tex(ring, &img);
|
||||
fd6_emit_image_descriptor(ctx, ring, pimg, false);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -263,61 +146,6 @@ fd6_emit_ssbo_tex(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
|||
fd6_emit_single_plane_descriptor(ring, pbuf->buffer, descriptor);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_image_ssbo(struct fd_ringbuffer *ring, struct fd6_image *img)
|
||||
{
|
||||
/* If the SSBO isn't present (becasue gallium doesn't pack atomic
|
||||
* counters), zero-fill the slot.
|
||||
*/
|
||||
if (!img->prsc) {
|
||||
for (int i = 0; i < 16; i++)
|
||||
OUT_RING(ring, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
struct fd_resource *rsc = fd_resource(img->prsc);
|
||||
enum a6xx_tile_mode tile_mode = fd_resource_tile_mode(img->prsc, img->level);
|
||||
bool ubwc_enabled = fd_resource_ubwc_enabled(rsc, img->level);
|
||||
|
||||
OUT_RING(ring, A6XX_IBO_0_FMT(
|
||||
fd6_texture_format(img->pfmt, rsc->layout.tile_mode)) |
|
||||
A6XX_IBO_0_TILE_MODE(tile_mode));
|
||||
OUT_RING(ring,
|
||||
A6XX_IBO_1_WIDTH(img->width) | A6XX_IBO_1_HEIGHT(img->height));
|
||||
OUT_RING(ring, A6XX_IBO_2_PITCH(img->pitch) |
|
||||
COND(img->buffer, A6XX_IBO_2_UNK4 | A6XX_IBO_2_UNK31) |
|
||||
A6XX_IBO_2_TYPE(img->type));
|
||||
OUT_RING(ring, A6XX_IBO_3_ARRAY_PITCH(img->array_pitch) |
|
||||
COND(ubwc_enabled, A6XX_IBO_3_FLAG | A6XX_IBO_3_UNK27));
|
||||
if (img->bo) {
|
||||
OUT_RELOC(ring, img->bo, img->offset,
|
||||
(uint64_t)A6XX_IBO_5_DEPTH(img->depth) << 32, 0);
|
||||
} else {
|
||||
OUT_RING(ring, 0x00000000);
|
||||
OUT_RING(ring, A6XX_IBO_5_DEPTH(img->depth));
|
||||
}
|
||||
OUT_RING(ring, 0x00000000);
|
||||
|
||||
if (ubwc_enabled) {
|
||||
OUT_RELOC(ring, rsc->bo, img->ubwc_offset, 0, 0);
|
||||
OUT_RING(ring, A6XX_IBO_9_FLAG_BUFFER_ARRAY_PITCH(
|
||||
rsc->layout.ubwc_layer_size >> 2));
|
||||
OUT_RING(ring, A6XX_IBO_10_FLAG_BUFFER_PITCH(
|
||||
fdl_ubwc_pitch(&rsc->layout, img->level)));
|
||||
} else {
|
||||
OUT_RING(ring, 0x00000000);
|
||||
OUT_RING(ring, 0x00000000);
|
||||
OUT_RING(ring, 0x00000000);
|
||||
OUT_RING(ring, 0x00000000);
|
||||
}
|
||||
|
||||
OUT_RING(ring, 0x00000000);
|
||||
OUT_RING(ring, 0x00000000);
|
||||
OUT_RING(ring, 0x00000000);
|
||||
OUT_RING(ring, 0x00000000);
|
||||
OUT_RING(ring, 0x00000000);
|
||||
}
|
||||
|
||||
/* Build combined image/SSBO "IBO" state, returns ownership of state reference */
|
||||
struct fd_ringbuffer *
|
||||
fd6_build_ibo_state(struct fd_context *ctx, const struct ir3_shader_variant *v,
|
||||
|
|
@ -341,16 +169,7 @@ fd6_build_ibo_state(struct fd_context *ctx, const struct ir3_shader_variant *v,
|
|||
}
|
||||
|
||||
for (unsigned i = 0; i < v->shader->nir->info.num_images; i++) {
|
||||
if (imgso->si[i].resource &&
|
||||
imgso->si[i].resource->target == PIPE_BUFFER) {
|
||||
fd6_image_descriptor(ctx, &imgso->si[i], descriptor);
|
||||
fd6_emit_single_plane_descriptor(state, imgso->si[i].resource,
|
||||
descriptor);
|
||||
} else {
|
||||
struct fd6_image img;
|
||||
translate_image(&img, &imgso->si[i]);
|
||||
emit_image_ssbo(state, &img);
|
||||
}
|
||||
fd6_emit_image_descriptor(ctx, state, &imgso->si[i], true);
|
||||
}
|
||||
|
||||
return state;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include "freedreno_context.h"
|
||||
|
||||
void fd6_emit_image_tex(struct fd_ringbuffer *ring,
|
||||
void fd6_emit_image_tex(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
const struct pipe_image_view *pimg) assert_dt;
|
||||
void fd6_emit_ssbo_tex(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
const struct pipe_shader_buffer *pbuf) assert_dt;
|
||||
|
|
|
|||
|
|
@ -77,28 +77,6 @@ void fd6_sampler_view_update(struct fd_context *ctx,
|
|||
void fd6_texture_init(struct pipe_context *pctx);
|
||||
void fd6_texture_fini(struct pipe_context *pctx);
|
||||
|
||||
static inline enum a6xx_tex_type
|
||||
fd6_tex_type(unsigned target)
|
||||
{
|
||||
switch (target) {
|
||||
default:
|
||||
assert(0);
|
||||
case PIPE_BUFFER:
|
||||
case PIPE_TEXTURE_1D:
|
||||
case PIPE_TEXTURE_1D_ARRAY:
|
||||
return A6XX_TEX_1D;
|
||||
case PIPE_TEXTURE_RECT:
|
||||
case PIPE_TEXTURE_2D:
|
||||
case PIPE_TEXTURE_2D_ARRAY:
|
||||
return A6XX_TEX_2D;
|
||||
case PIPE_TEXTURE_3D:
|
||||
return A6XX_TEX_3D;
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
case PIPE_TEXTURE_CUBE_ARRAY:
|
||||
return A6XX_TEX_CUBE;
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
fd6_border_color_offset(struct fd_context *ctx, enum pipe_shader_type type,
|
||||
struct fd_texture_stateobj *tex) assert_dt
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue