From d31b7dcefdfdce8916d5ba3a5a9edc5812d94196 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Tue, 27 Jul 2021 13:59:39 -0400 Subject: [PATCH] zink: track fbfetch info on context, update as needed Reviewed-by: Dave Airlie Part-of: --- src/gallium/drivers/zink/zink_context.c | 25 +++++++++++++++++++++++++ src/gallium/drivers/zink/zink_context.h | 6 +++++- src/gallium/drivers/zink/zink_program.c | 14 +++++++++++++- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 09dd9abb1a5..e00398eea1e 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -1467,6 +1467,28 @@ zink_set_patch_vertices(struct pipe_context *pctx, uint8_t patch_vertices) ctx->gfx_pipeline_state.patch_vertices = patch_vertices; } +void +zink_update_fbfetch(struct zink_context *ctx) +{ + const bool had_fbfetch = ctx->di.fbfetch.imageLayout == VK_IMAGE_LAYOUT_GENERAL; + if (!ctx->gfx_stages[PIPE_SHADER_FRAGMENT] || + !ctx->gfx_stages[PIPE_SHADER_FRAGMENT]->nir->info.fs.uses_fbfetch_output) { + if (!had_fbfetch) + return; + ctx->di.fbfetch.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + ctx->di.fbfetch.imageView = zink_screen(ctx->base.screen)->info.rb2_feats.nullDescriptor ? + VK_NULL_HANDLE : + zink_surface(ctx->dummy_surface)->image_view; + return; + } + + if (ctx->fb_state.cbufs[0]) { + VkImageView fbfetch = zink_surface(ctx->fb_state.cbufs[0])->image_view; + ctx->di.fbfetch.imageView = zink_surface(ctx->fb_state.cbufs[0])->image_view; + } + ctx->di.fbfetch.imageLayout = VK_IMAGE_LAYOUT_GENERAL; +} + static uint32_t hash_render_pass_state(const void *key) { @@ -1975,6 +1997,7 @@ zink_set_framebuffer_state(struct pipe_context *pctx, unsigned h = ctx->fb_state.height; util_copy_framebuffer_state(&ctx->fb_state, state); + zink_update_fbfetch(ctx); unsigned prev_void_alpha_attachments = ctx->gfx_pipeline_state.void_alpha_attachments; ctx->gfx_pipeline_state.void_alpha_attachments = 0; for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) { @@ -3577,6 +3600,8 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) update_descriptor_state_image(ctx, i, j); } } + if (!screen->info.rb2_feats.nullDescriptor) + ctx->di.fbfetch.imageView = zink_surface(ctx->dummy_surface)->image_view; p_atomic_inc(&screen->base.num_contexts); zink_select_draw_vbo(ctx); diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 5bb730890fa..e1475078621 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -235,6 +235,7 @@ struct zink_context { struct zink_framebuffer_clear fb_clears[PIPE_MAX_COLOR_BUFS + 1]; uint16_t clears_enabled; uint16_t rp_clears_enabled; + uint16_t fbfetch_outputs; VkBuffer vbufs[PIPE_MAX_ATTRIBS]; unsigned vbuf_offsets[PIPE_MAX_ATTRIBS]; @@ -299,6 +300,8 @@ struct zink_context { VkBufferView texel_images[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES]; uint8_t num_images[PIPE_SHADER_TYPES]; + VkDescriptorImageInfo fbfetch; + struct zink_resource *descriptor_res[ZINK_DESCRIPTOR_TYPES][PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; struct zink_descriptor_surface sampler_surfaces[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; struct zink_descriptor_surface image_surfaces[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES]; @@ -351,7 +354,8 @@ zink_check_batch_completion(struct zink_context *ctx, uint32_t batch_id, bool ha void zink_flush_queue(struct zink_context *ctx); - +void +zink_update_fbfetch(struct zink_context *ctx); bool zink_resource_access_is_write(VkAccessFlags flags); diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index 91662f6472e..1e90ec8154d 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -945,7 +945,19 @@ static void zink_bind_fs_state(struct pipe_context *pctx, void *cso) { - bind_stage(zink_context(pctx), PIPE_SHADER_FRAGMENT, cso); + struct zink_context *ctx = zink_context(pctx); + bind_stage(ctx, PIPE_SHADER_FRAGMENT, cso); + ctx->fbfetch_outputs = 0; + if (cso) { + nir_shader *nir = ctx->gfx_stages[PIPE_SHADER_FRAGMENT]->nir; + if (nir->info.fs.uses_fbfetch_output) { + nir_foreach_shader_out_variable(var, ctx->gfx_stages[PIPE_SHADER_FRAGMENT]->nir) { + if (var->data.fb_fetch_output) + ctx->fbfetch_outputs |= BITFIELD_BIT(var->data.location - FRAG_RESULT_DATA0); + } + } + } + zink_update_fbfetch(ctx); } static void