diff options
author | Emma Anholt <emma@anholt.net> | 2021-10-18 15:18:14 -0700 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2021-11-11 00:10:57 +0000 |
commit | c90220e449116824795e96ac2988c8b107cd9cf5 (patch) | |
tree | 9c2522d6aaf4cbd1d1a333dd607ce82a40ecf49c | |
parent | 533e486923b1fb760961c582aa296d5ce423a704 (diff) |
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>
-rw-r--r-- | src/gallium/drivers/freedreno/a6xx/fd6_emit.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/a6xx/fd6_image.c | 271 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/a6xx/fd6_image.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/a6xx/fd6_texture.h | 22 |
4 files changed, 47 insertions, 250 deletions
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c index 863550ecbc6..b19e8158f70 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c @@ -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]); } } diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_image.c b/src/gallium/drivers/freedreno/a6xx/fd6_image.c index 288c7666e2a..3a778b916fb 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_image.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_image.c @@ -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, - 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 */ - } + .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, - 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 */ + .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); + } } 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; diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_image.h b/src/gallium/drivers/freedreno/a6xx/fd6_image.h index da7b21c1faf..439317ea572 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_image.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_image.h @@ -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; diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_texture.h b/src/gallium/drivers/freedreno/a6xx/fd6_texture.h index d02278866db..6882aaa639f 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_texture.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_texture.h @@ -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 |