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>
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)
{
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;
}
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);
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;
#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;
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 :
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;
zs_ref.attachment = num_attachments++;
zs_ref.layout = layout;
+ pstate->num_attachments++;
}
VkSubpassDependency deps[] = {
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));
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,