mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
zink: track compatible render passes
Two render passes are compatible if their corresponding color, input, resolve, and depth/stencil attachment references are compatible and if they are otherwise identical except for: • Initial and final image layout in attachment descriptions • Load and store operations in attachment descriptions • Image layout in attachment references VK 8.2 Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12605>
This commit is contained in:
parent
d7e36a1831
commit
8dac288c8d
4 changed files with 54 additions and 9 deletions
|
|
@ -1496,6 +1496,26 @@ zink_update_fbfetch(struct zink_context *ctx)
|
|||
zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, PIPE_SHADER_FRAGMENT, ZINK_DESCRIPTOR_TYPE_UBO, 0, 1);
|
||||
}
|
||||
|
||||
static size_t
|
||||
rp_state_size(const struct zink_render_pass_pipeline_state *pstate)
|
||||
{
|
||||
return offsetof(struct zink_render_pass_pipeline_state, attachments) +
|
||||
sizeof(pstate->attachments[0]) * pstate->num_attachments;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
hash_rp_state(const void *key)
|
||||
{
|
||||
const struct zink_render_pass_pipeline_state *s = key;
|
||||
return _mesa_hash_data(key, rp_state_size(s));
|
||||
}
|
||||
|
||||
static bool
|
||||
equals_rp_state(const void *a, const void *b)
|
||||
{
|
||||
return !memcmp(a, b, rp_state_size(a));
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
hash_render_pass_state(const void *key)
|
||||
{
|
||||
|
|
@ -1574,9 +1594,17 @@ get_render_pass(struct zink_context *ctx)
|
|||
rp = entry->data;
|
||||
assert(rp->state.clears == clears);
|
||||
} else {
|
||||
rp = zink_create_render_pass(screen, &state);
|
||||
struct zink_render_pass_pipeline_state pstate;
|
||||
rp = zink_create_render_pass(screen, &state, &pstate);
|
||||
if (!_mesa_hash_table_insert_pre_hashed(ctx->render_pass_cache, hash, &rp->state, rp))
|
||||
return NULL;
|
||||
bool found = false;
|
||||
struct set_entry *entry = _mesa_set_search_or_add(&ctx->render_pass_state_cache, &pstate, &found);
|
||||
if (!found) {
|
||||
entry->key = ralloc(ctx, struct zink_render_pass_pipeline_state);
|
||||
memcpy((void*)entry->key, &pstate, rp_state_size(&pstate));
|
||||
}
|
||||
rp->pipeline_state = (void*)entry->key;
|
||||
}
|
||||
return rp;
|
||||
}
|
||||
|
|
@ -3589,6 +3617,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
|||
goto fail;
|
||||
|
||||
_mesa_hash_table_init(&ctx->compute_program_cache, ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
|
||||
_mesa_set_init(&ctx->render_pass_state_cache, ctx, hash_rp_state, equals_rp_state);
|
||||
ctx->render_pass_cache = _mesa_hash_table_create(NULL,
|
||||
hash_render_pass_state,
|
||||
equals_render_pass_state);
|
||||
|
|
|
|||
|
|
@ -232,6 +232,7 @@ struct zink_context {
|
|||
unsigned dirty_shader_stages : 6; /* mask of changed shader stages */
|
||||
bool last_vertex_stage_dirty;
|
||||
|
||||
struct set render_pass_state_cache;
|
||||
struct hash_table *render_pass_cache;
|
||||
bool new_swapchain;
|
||||
bool fb_changed;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
#include "util/u_string.h"
|
||||
|
||||
static VkRenderPass
|
||||
create_render_pass(VkDevice dev, struct zink_render_pass_state *state)
|
||||
create_render_pass(VkDevice dev, struct zink_render_pass_state *state, struct zink_render_pass_pipeline_state *pstate)
|
||||
{
|
||||
|
||||
VkAttachmentReference color_refs[PIPE_MAX_COLOR_BUFS], zs_ref;
|
||||
|
|
@ -39,11 +39,12 @@ create_render_pass(VkDevice dev, struct zink_render_pass_state *state)
|
|||
VkAccessFlags dep_access = 0;
|
||||
unsigned input_count = 0;
|
||||
|
||||
pstate->num_attachments = state->num_cbufs;
|
||||
for (int i = 0; i < state->num_cbufs; i++) {
|
||||
struct zink_rt_attrib *rt = state->rts + i;
|
||||
attachments[i].flags = 0;
|
||||
attachments[i].format = rt->format;
|
||||
attachments[i].samples = rt->samples;
|
||||
pstate->attachments[i].format = attachments[i].format = rt->format;
|
||||
pstate->attachments[i].samples = attachments[i].samples = rt->samples;
|
||||
attachments[i].loadOp = rt->clear_color ? VK_ATTACHMENT_LOAD_OP_CLEAR :
|
||||
state->swapchain_init && rt->swapchain ?
|
||||
VK_ATTACHMENT_LOAD_OP_DONT_CARE :
|
||||
|
|
@ -72,8 +73,8 @@ create_render_pass(VkDevice dev, struct zink_render_pass_state *state)
|
|||
VkImageLayout write_layout = rt->fbfetch ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
VkImageLayout layout = rt->needs_write || has_clear ? write_layout : VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
||||
attachments[num_attachments].flags = 0;
|
||||
attachments[num_attachments].format = rt->format;
|
||||
attachments[num_attachments].samples = rt->samples;
|
||||
pstate->attachments[num_attachments].format = attachments[num_attachments].format = rt->format;
|
||||
pstate->attachments[num_attachments].samples = attachments[num_attachments].samples = rt->samples;
|
||||
attachments[num_attachments].loadOp = rt->clear_color ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
attachments[num_attachments].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachments[num_attachments].stencilLoadOp = rt->clear_stencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
|
|
@ -91,6 +92,7 @@ create_render_pass(VkDevice dev, struct zink_render_pass_state *state)
|
|||
|
||||
zs_ref.attachment = num_attachments++;
|
||||
zs_ref.layout = layout;
|
||||
pstate->num_attachments++;
|
||||
}
|
||||
|
||||
VkSubpassDependency deps[] = {
|
||||
|
|
@ -126,13 +128,14 @@ create_render_pass(VkDevice dev, struct zink_render_pass_state *state)
|
|||
|
||||
struct zink_render_pass *
|
||||
zink_create_render_pass(struct zink_screen *screen,
|
||||
struct zink_render_pass_state *state)
|
||||
struct zink_render_pass_state *state,
|
||||
struct zink_render_pass_pipeline_state *pstate)
|
||||
{
|
||||
struct zink_render_pass *rp = CALLOC_STRUCT(zink_render_pass);
|
||||
if (!rp)
|
||||
goto fail;
|
||||
|
||||
rp->render_pass = create_render_pass(screen->dev, state);
|
||||
rp->render_pass = create_render_pass(screen->dev, state, pstate);
|
||||
if (!rp->render_pass)
|
||||
goto fail;
|
||||
memcpy(&rp->state, state, sizeof(struct zink_render_pass_state));
|
||||
|
|
|
|||
|
|
@ -52,14 +52,26 @@ struct zink_render_pass_state {
|
|||
uint32_t clears; //for extra verification and update flagging
|
||||
};
|
||||
|
||||
struct zink_pipeline_rt {
|
||||
VkFormat format;
|
||||
VkSampleCountFlagBits samples;
|
||||
};
|
||||
|
||||
struct zink_render_pass_pipeline_state {
|
||||
uint32_t num_attachments;
|
||||
struct zink_pipeline_rt attachments[PIPE_MAX_COLOR_BUFS + 1];
|
||||
};
|
||||
|
||||
struct zink_render_pass {
|
||||
VkRenderPass render_pass;
|
||||
struct zink_render_pass_state state;
|
||||
struct zink_render_pass_pipeline_state *pipeline_state;
|
||||
};
|
||||
|
||||
struct zink_render_pass *
|
||||
zink_create_render_pass(struct zink_screen *screen,
|
||||
struct zink_render_pass_state *state);
|
||||
struct zink_render_pass_state *state,
|
||||
struct zink_render_pass_pipeline_state *pstate);
|
||||
|
||||
void
|
||||
zink_destroy_render_pass(struct zink_screen *screen,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue