mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 06:50:11 +01:00
zink: decouple renderpass from framebuffer state
a framebuffer is based on the surfaces attached to it a renderpass is based on the operations being performed a zink_framebuffer object doesn't necessarily need to be changed if the renderpass changes, as this might just indicate that a clear operation is being used instead of a load, so we can cache the corresponding vk objects into the zink_framebuffer based on the renderpass ops being used to (eventually) reduce fb object thrashing by doing more incremental updates Reviewed-by: Adam Jackson <ajax@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8227>
This commit is contained in:
parent
49bb791991
commit
3d88e65e88
3 changed files with 77 additions and 21 deletions
|
|
@ -709,7 +709,6 @@ create_framebuffer(struct zink_context *ctx)
|
||||||
struct pipe_surface *attachments[PIPE_MAX_COLOR_BUFS + 1] = {};
|
struct pipe_surface *attachments[PIPE_MAX_COLOR_BUFS + 1] = {};
|
||||||
|
|
||||||
struct zink_framebuffer_state state = {};
|
struct zink_framebuffer_state state = {};
|
||||||
state.rp = get_render_pass(ctx);
|
|
||||||
for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
|
for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
|
||||||
struct pipe_surface *psurf = ctx->fb_state.cbufs[i];
|
struct pipe_surface *psurf = ctx->fb_state.cbufs[i];
|
||||||
state.attachments[i] = psurf ? zink_surface(psurf)->image_view : VK_NULL_HANDLE;
|
state.attachments[i] = psurf ? zink_surface(psurf)->image_view : VK_NULL_HANDLE;
|
||||||
|
|
@ -728,7 +727,9 @@ create_framebuffer(struct zink_context *ctx)
|
||||||
state.layers = MAX2(util_framebuffer_get_num_layers(&ctx->fb_state), 1);
|
state.layers = MAX2(util_framebuffer_get_num_layers(&ctx->fb_state), 1);
|
||||||
state.samples = ctx->fb_state.samples;
|
state.samples = ctx->fb_state.samples;
|
||||||
|
|
||||||
return zink_create_framebuffer(ctx, screen, &state, attachments);
|
struct zink_framebuffer *fb = zink_create_framebuffer(ctx, &state, attachments);
|
||||||
|
zink_init_framebuffer(screen, fb, get_render_pass(ctx));
|
||||||
|
return fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -814,7 +815,7 @@ zink_batch_rp(struct zink_context *ctx)
|
||||||
struct zink_batch *batch = zink_curr_batch(ctx);
|
struct zink_batch *batch = zink_curr_batch(ctx);
|
||||||
if (!batch->in_rp) {
|
if (!batch->in_rp) {
|
||||||
zink_begin_render_pass(ctx, batch);
|
zink_begin_render_pass(ctx, batch);
|
||||||
assert(batch->fb && batch->fb->state.rp);
|
assert(batch->fb && batch->fb->rp);
|
||||||
}
|
}
|
||||||
return batch;
|
return batch;
|
||||||
}
|
}
|
||||||
|
|
@ -847,7 +848,7 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
|
||||||
zink_framebuffer_reference(screen, &fb, NULL);
|
zink_framebuffer_reference(screen, &fb, NULL);
|
||||||
fb = create_framebuffer(ctx);
|
fb = create_framebuffer(ctx);
|
||||||
zink_framebuffer_reference(screen, &ctx->framebuffer, fb);
|
zink_framebuffer_reference(screen, &ctx->framebuffer, fb);
|
||||||
ctx->gfx_pipeline_state.render_pass = fb->state.rp;
|
ctx->gfx_pipeline_state.render_pass = fb->rp;
|
||||||
|
|
||||||
uint8_t rast_samples = util_framebuffer_get_num_samples(state);
|
uint8_t rast_samples = util_framebuffer_get_num_samples(state);
|
||||||
/* in vulkan, gl_SampleMask needs to be explicitly ignored for sampleCount == 1 */
|
/* in vulkan, gl_SampleMask needs to be explicitly ignored for sampleCount == 1 */
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,14 @@ void
|
||||||
zink_destroy_framebuffer(struct zink_screen *screen,
|
zink_destroy_framebuffer(struct zink_screen *screen,
|
||||||
struct zink_framebuffer *fb)
|
struct zink_framebuffer *fb)
|
||||||
{
|
{
|
||||||
vkDestroyFramebuffer(screen->dev, fb->fb, NULL);
|
hash_table_foreach(&fb->objects, he) {
|
||||||
|
#if defined(_WIN64) || defined(__x86_64__)
|
||||||
|
vkDestroyFramebuffer(screen->dev, he->data, NULL);
|
||||||
|
#else
|
||||||
|
VkFramebuffer *ptr = he->data;
|
||||||
|
vkDestroyFramebuffer(screen->dev, *ptr, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
for (int i = 0; i < ARRAY_SIZE(fb->surfaces); ++i)
|
for (int i = 0; i < ARRAY_SIZE(fb->surfaces); ++i)
|
||||||
pipe_surface_reference(fb->surfaces + i, NULL);
|
pipe_surface_reference(fb->surfaces + i, NULL);
|
||||||
|
|
||||||
|
|
@ -72,11 +79,60 @@ zink_destroy_framebuffer(struct zink_screen *screen,
|
||||||
ralloc_free(fb);
|
ralloc_free(fb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zink_init_framebuffer(struct zink_screen *screen, struct zink_framebuffer *fb, struct zink_render_pass *rp)
|
||||||
|
{
|
||||||
|
VkFramebuffer ret;
|
||||||
|
|
||||||
|
if (fb->rp == rp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32_t hash = _mesa_hash_pointer(rp);
|
||||||
|
|
||||||
|
struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&fb->objects, hash, rp);
|
||||||
|
if (he) {
|
||||||
|
#if defined(_WIN64) || defined(__x86_64__)
|
||||||
|
ret = (VkFramebuffer)he->data;
|
||||||
|
#else
|
||||||
|
VkFramebuffer *ptr = he->data;
|
||||||
|
ret = *ptr;
|
||||||
|
#endif
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkFramebufferCreateInfo fci = {};
|
||||||
|
fci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
|
fci.renderPass = rp->render_pass;
|
||||||
|
fci.attachmentCount = fb->state.num_attachments;
|
||||||
|
fci.pAttachments = fb->state.attachments;
|
||||||
|
fci.width = fb->state.width;
|
||||||
|
fci.height = fb->state.height;
|
||||||
|
fci.layers = fb->state.layers;
|
||||||
|
|
||||||
|
if (vkCreateFramebuffer(screen->dev, &fci, NULL, &ret) != VK_SUCCESS)
|
||||||
|
return;
|
||||||
|
#if defined(_WIN64) || defined(__x86_64__)
|
||||||
|
_mesa_hash_table_insert_pre_hashed(&fb->objects, hash, rp, ret);
|
||||||
|
#else
|
||||||
|
VkFramebuffer *ptr = ralloc(fb, VkFramebuffer);
|
||||||
|
if (!ptr) {
|
||||||
|
vkDestroyFramebuffer(screen->dev, ret, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*ptr = ret;
|
||||||
|
_mesa_hash_table_insert_pre_hashed(&fb->objects, hash, rp, ptr);
|
||||||
|
#endif
|
||||||
|
out:
|
||||||
|
fb->rp = rp;
|
||||||
|
fb->fb = ret;
|
||||||
|
}
|
||||||
|
|
||||||
struct zink_framebuffer *
|
struct zink_framebuffer *
|
||||||
zink_create_framebuffer(struct zink_context *ctx, struct zink_screen *screen,
|
zink_create_framebuffer(struct zink_context *ctx,
|
||||||
struct zink_framebuffer_state *state,
|
struct zink_framebuffer_state *state,
|
||||||
struct pipe_surface **attachments)
|
struct pipe_surface **attachments)
|
||||||
{
|
{
|
||||||
|
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
||||||
struct zink_framebuffer *fb = rzalloc(NULL, struct zink_framebuffer);
|
struct zink_framebuffer *fb = rzalloc(NULL, struct zink_framebuffer);
|
||||||
if (!fb)
|
if (!fb)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -93,22 +149,14 @@ zink_create_framebuffer(struct zink_context *ctx, struct zink_screen *screen,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VkFramebufferCreateInfo fci = {};
|
if (!_mesa_hash_table_init(&fb->objects, fb, _mesa_hash_pointer, _mesa_key_pointer_equal))
|
||||||
fci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
goto fail;
|
||||||
fci.renderPass = state->rp->render_pass;
|
|
||||||
fci.attachmentCount = state->num_attachments;
|
|
||||||
fci.pAttachments = state->attachments;
|
|
||||||
fci.width = state->width;
|
|
||||||
fci.height = state->height;
|
|
||||||
fci.layers = state->layers;
|
|
||||||
|
|
||||||
if (vkCreateFramebuffer(screen->dev, &fci, NULL, &fb->fb) != VK_SUCCESS) {
|
|
||||||
zink_destroy_framebuffer(screen, fb);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
memcpy(&fb->state, state, sizeof(struct zink_framebuffer_state));
|
memcpy(&fb->state, state, sizeof(struct zink_framebuffer_state));
|
||||||
|
|
||||||
return fb;
|
return fb;
|
||||||
|
fail:
|
||||||
|
zink_destroy_framebuffer(screen, fb);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include "pipe/p_state.h"
|
#include "pipe/p_state.h"
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
|
#include "util/hash_table.h"
|
||||||
#include "util/u_inlines.h"
|
#include "util/u_inlines.h"
|
||||||
|
|
||||||
struct zink_context;
|
struct zink_context;
|
||||||
|
|
@ -34,7 +35,6 @@ struct zink_screen;
|
||||||
struct zink_render_pass;
|
struct zink_render_pass;
|
||||||
|
|
||||||
struct zink_framebuffer_state {
|
struct zink_framebuffer_state {
|
||||||
struct zink_render_pass *rp;
|
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint16_t height, layers;
|
uint16_t height, layers;
|
||||||
uint8_t samples;
|
uint8_t samples;
|
||||||
|
|
@ -44,18 +44,25 @@ struct zink_framebuffer_state {
|
||||||
|
|
||||||
struct zink_framebuffer {
|
struct zink_framebuffer {
|
||||||
struct pipe_reference reference;
|
struct pipe_reference reference;
|
||||||
|
|
||||||
|
/* current objects */
|
||||||
VkFramebuffer fb;
|
VkFramebuffer fb;
|
||||||
|
struct zink_render_pass *rp;
|
||||||
|
|
||||||
struct pipe_surface *surfaces[PIPE_MAX_COLOR_BUFS + 1];
|
struct pipe_surface *surfaces[PIPE_MAX_COLOR_BUFS + 1];
|
||||||
struct pipe_surface *null_surface; /* for use with unbound attachments */
|
struct pipe_surface *null_surface; /* for use with unbound attachments */
|
||||||
struct zink_framebuffer_state state;
|
struct zink_framebuffer_state state;
|
||||||
|
struct hash_table objects;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zink_framebuffer *
|
struct zink_framebuffer *
|
||||||
zink_create_framebuffer(struct zink_context *ctx, struct zink_screen *screen,
|
zink_create_framebuffer(struct zink_context *ctx,
|
||||||
struct zink_framebuffer_state *fb,
|
struct zink_framebuffer_state *fb,
|
||||||
struct pipe_surface **attachments);
|
struct pipe_surface **attachments);
|
||||||
|
|
||||||
|
void
|
||||||
|
zink_init_framebuffer(struct zink_screen *screen, struct zink_framebuffer *fb, struct zink_render_pass *rp);
|
||||||
|
|
||||||
void
|
void
|
||||||
zink_destroy_framebuffer(struct zink_screen *screen,
|
zink_destroy_framebuffer(struct zink_screen *screen,
|
||||||
struct zink_framebuffer *fbuf);
|
struct zink_framebuffer *fbuf);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue