mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 20:28:04 +02:00
asahi: handle cross-process eMRT
decompress in place, just in time. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30981>
This commit is contained in:
parent
591bf066ba
commit
a6c5f7dc20
1 changed files with 67 additions and 13 deletions
|
|
@ -15,6 +15,7 @@
|
|||
#include "asahi/lib/agx_nir_passes.h"
|
||||
#include "asahi/lib/agx_ppp.h"
|
||||
#include "asahi/lib/agx_usc.h"
|
||||
#include "asahi/lib/shaders/compression.h"
|
||||
#include "asahi/lib/shaders/tessellator.h"
|
||||
#include "compiler/nir/nir.h"
|
||||
#include "compiler/nir/nir_serialize.h"
|
||||
|
|
@ -1180,7 +1181,7 @@ target_is_array(enum pipe_texture_target target)
|
|||
static void
|
||||
agx_batch_upload_pbe(struct agx_batch *batch, struct agx_pbe_packed *out,
|
||||
struct pipe_image_view *view, bool block_access,
|
||||
bool arrays_as_2d, bool force_2d_array)
|
||||
bool arrays_as_2d, bool force_2d_array, bool emrt)
|
||||
{
|
||||
struct agx_resource *tex = agx_resource(view->resource);
|
||||
const struct util_format_description *desc =
|
||||
|
|
@ -1296,7 +1297,7 @@ agx_batch_upload_pbe(struct agx_batch *batch, struct agx_pbe_packed *out,
|
|||
cfg.samples = agx_translate_sample_count(tex->base.nr_samples);
|
||||
}
|
||||
|
||||
if (ail_is_compressed(&tex->layout)) {
|
||||
if (ail_is_compressed(&tex->layout) && !emrt) {
|
||||
cfg.compressed_1 = true;
|
||||
cfg.extended = true;
|
||||
|
||||
|
|
@ -1308,7 +1309,7 @@ agx_batch_upload_pbe(struct agx_batch *batch, struct agx_pbe_packed *out,
|
|||
/* When the descriptor isn't extended architecturally, we can use the last
|
||||
* 8 bytes as a sideband. We use it to provide metadata for image atomics.
|
||||
*/
|
||||
if (!cfg.extended && tex->layout.writeable_image &&
|
||||
if (!cfg.extended && (tex->layout.writeable_image || emrt) &&
|
||||
tex->base.target != PIPE_BUFFER) {
|
||||
|
||||
if (util_res_sample_count(&tex->base) > 1) {
|
||||
|
|
@ -1322,7 +1323,7 @@ agx_batch_upload_pbe(struct agx_batch *batch, struct agx_pbe_packed *out,
|
|||
|
||||
cfg.sample_count_log2_sw = util_logbase2(tex->base.nr_samples);
|
||||
|
||||
if (tex->layout.tiling == AIL_TILING_TWIDDLED) {
|
||||
if (tex->layout.tiling == AIL_TILING_TWIDDLED || emrt) {
|
||||
struct ail_tile tile_size = tex->layout.tilesize_el[level];
|
||||
cfg.tile_width_sw = tile_size.width_el;
|
||||
cfg.tile_height_sw = tile_size.height_el;
|
||||
|
|
@ -2588,6 +2589,8 @@ agx_build_meta_shader_internal(struct agx_context *ctx,
|
|||
nir_address_format_62bit_generic);
|
||||
|
||||
agx_preprocess_nir(b.shader, NULL);
|
||||
NIR_PASS(_, b.shader, agx_nir_lower_texture);
|
||||
NIR_PASS(_, b.shader, agx_nir_lower_multisampled_image_store);
|
||||
}
|
||||
|
||||
struct agx_compiled_shader *shader = agx_compile_nir(
|
||||
|
|
@ -2681,7 +2684,7 @@ agx_upload_spilled_rt_descriptors(struct agx_texture_packed *out,
|
|||
sampler_view.target = PIPE_TEXTURE_2D_ARRAY;
|
||||
|
||||
agx_pack_texture(texture, rsrc, surf->format, &sampler_view);
|
||||
agx_batch_upload_pbe(batch, pbe, &view, false, false, true);
|
||||
agx_batch_upload_pbe(batch, pbe, &view, false, false, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2761,7 +2764,7 @@ agx_upload_textures(struct agx_batch *batch, struct agx_compiled_shader *cs,
|
|||
|
||||
agx_pack_texture(texture, agx_resource(view->resource), view->format,
|
||||
&sampler_view);
|
||||
agx_batch_upload_pbe(batch, pbe, view, false, false, false);
|
||||
agx_batch_upload_pbe(batch, pbe, view, false, false, false, false);
|
||||
}
|
||||
|
||||
if (stage == PIPE_SHADER_FRAGMENT &&
|
||||
|
|
@ -3031,7 +3034,8 @@ agx_build_internal_usc(struct agx_batch *batch, struct agx_compiled_shader *cs,
|
|||
uint64_t data)
|
||||
{
|
||||
struct agx_device *dev = agx_device(batch->ctx->base.screen);
|
||||
size_t usc_size = agx_usc_size(12);
|
||||
bool needs_sampler = cs->b.info.uses_txf;
|
||||
size_t usc_size = agx_usc_size(12 + (needs_sampler ? 1 : 0));
|
||||
|
||||
struct agx_ptr t =
|
||||
agx_pool_alloc_aligned(&batch->pipeline_pool, usc_size, 64);
|
||||
|
|
@ -3041,6 +3045,20 @@ agx_build_internal_usc(struct agx_batch *batch, struct agx_compiled_shader *cs,
|
|||
agx_usc_uniform(&b, 0, 4, agx_pool_upload(&batch->pool, &data, 8));
|
||||
agx_usc_immediates(&b, batch, cs);
|
||||
|
||||
if (needs_sampler) {
|
||||
/* TODO: deduplicate */
|
||||
struct agx_ptr t = agx_pool_alloc_aligned(
|
||||
&batch->pool, sizeof(struct agx_sampler_packed), 64);
|
||||
|
||||
agx_pack_txf_sampler((struct agx_sampler_packed *)t.cpu);
|
||||
|
||||
agx_usc_pack(&b, SAMPLER, cfg) {
|
||||
cfg.start = 0;
|
||||
cfg.count = 1;
|
||||
cfg.buffer = t.gpu;
|
||||
}
|
||||
}
|
||||
|
||||
assert(cs->b.info.scratch_size == 0 && "internal kernels don't spill");
|
||||
assert(cs->b.info.preamble_scratch_size == 0 && "internal doesn't spill");
|
||||
|
||||
|
|
@ -3193,7 +3211,7 @@ agx_build_bg_eot(struct agx_batch *batch, bool store, bool partial_render)
|
|||
/* The tilebuffer is already in sRGB space if needed. Do not convert */
|
||||
view.format = util_format_linear(view.format);
|
||||
|
||||
agx_batch_upload_pbe(batch, pbe.cpu, &view, true, true, false);
|
||||
agx_batch_upload_pbe(batch, pbe.cpu, &view, true, true, false, false);
|
||||
|
||||
agx_usc_pack(&b, TEXTURE, cfg) {
|
||||
cfg.start = rt;
|
||||
|
|
@ -3410,14 +3428,50 @@ agx_batch_init_state(struct agx_batch *batch)
|
|||
continue;
|
||||
|
||||
struct agx_resource *rsrc = agx_resource(surf->texture);
|
||||
if (rsrc->layout.writeable_image)
|
||||
struct ail_layout *layout = &rsrc->layout;
|
||||
unsigned level = surf->u.tex.level;
|
||||
|
||||
if (!ail_is_level_compressed(layout, level))
|
||||
continue;
|
||||
|
||||
/* Decompress if we can and shadow if we can't. */
|
||||
if (rsrc->base.bind & PIPE_BIND_SHARED)
|
||||
unreachable("TODO");
|
||||
else
|
||||
if (true || (rsrc->base.bind & PIPE_BIND_SHARED)) {
|
||||
struct agx_context *ctx = batch->ctx;
|
||||
struct agx_device *dev = agx_device(ctx->base.screen);
|
||||
|
||||
perf_debug(dev, "Decompressing in-place");
|
||||
|
||||
if (!batch->cdm.bo)
|
||||
batch->cdm = agx_encoder_allocate(batch, dev);
|
||||
|
||||
struct agx_ptr data = agx_pool_alloc_aligned(
|
||||
&batch->pool, sizeof(struct libagx_decompress_push), 64);
|
||||
struct libagx_decompress_push *push = data.cpu;
|
||||
agx_fill_decompress_push(push, layout, surf->u.tex.first_layer,
|
||||
level, agx_map_texture_gpu(rsrc, 0));
|
||||
|
||||
struct pipe_sampler_view sampler_view =
|
||||
sampler_view_for_surface(surf);
|
||||
sampler_view.target = PIPE_TEXTURE_2D_ARRAY;
|
||||
struct pipe_image_view view = image_view_for_surface(surf);
|
||||
agx_pack_texture(&push->compressed, rsrc, surf->format,
|
||||
&sampler_view);
|
||||
agx_batch_upload_pbe(batch, &push->uncompressed, &view, false, true,
|
||||
true, true);
|
||||
|
||||
struct agx_grid grid = agx_grid_direct(
|
||||
ail_metadata_width_tl(layout, level) * 32,
|
||||
ail_metadata_height_tl(layout, level),
|
||||
surf->u.tex.last_layer - surf->u.tex.first_layer + 1, 32, 1, 1);
|
||||
|
||||
struct agx_decompress_key key = {
|
||||
.nr_samples = layout->sample_count_sa,
|
||||
};
|
||||
|
||||
agx_launch_with_uploaded_data(batch, &grid, agx_nir_decompress,
|
||||
&key, sizeof(key), data.gpu);
|
||||
} else {
|
||||
agx_decompress(batch->ctx, rsrc, "Render target spilled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue