zink: prune zink_surface down to the imageview and create/fetch on demand

this eliminates all pipe_surface allocations

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35722>
This commit is contained in:
Mike Blumenkrantz 2025-06-23 13:01:04 -04:00
parent 309710c260
commit ef3f798957
9 changed files with 92 additions and 225 deletions

View file

@ -449,11 +449,11 @@ zink_clear_texture_dynamic(struct pipe_context *pctx,
0 <= box->z && u_minify(pres->target == PIPE_TEXTURE_3D ? pres->depth0 : pres->array_size, level) >= box->z + box->depth; 0 <= box->z && u_minify(pres->target == PIPE_TEXTURE_3D ? pres->depth0 : pres->array_size, level) >= box->z + box->depth;
struct pipe_surface psurf = create_clear_surface(pctx, pres, level, box); struct pipe_surface psurf = create_clear_surface(pctx, pres, level, box);
struct pipe_surface *surf = zink_create_fb_surface(pctx, pres, &psurf); struct zink_surface *surf = zink_create_fb_surface(pctx, pres, &psurf);
VkRenderingAttachmentInfo att = {0}; VkRenderingAttachmentInfo att = {0};
att.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; att.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
att.imageView = zink_surface(surf)->image_view; att.imageView = surf->image_view;
att.imageLayout = res->aspect & VK_IMAGE_ASPECT_COLOR_BIT ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; att.imageLayout = res->aspect & VK_IMAGE_ASPECT_COLOR_BIT ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
att.loadOp = full_clear ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD; att.loadOp = full_clear ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; att.storeOp = VK_ATTACHMENT_STORE_OP_STORE;

View file

@ -155,8 +155,6 @@ zink_context_destroy(struct pipe_context *pctx)
if (ctx->blitter) if (ctx->blitter)
util_blitter_destroy(ctx->blitter); util_blitter_destroy(ctx->blitter);
util_unreference_framebuffer_state(&ctx->fb_state);
util_framebuffer_init(pctx, NULL, ctx->fb_cbufs, &ctx->fb_zsbuf);
pipe_resource_reference(&ctx->dummy_xfb_buffer, NULL); pipe_resource_reference(&ctx->dummy_xfb_buffer, NULL);
@ -2727,10 +2725,11 @@ zink_update_fbfetch(struct zink_context *ctx)
bool changed = !had_fbfetch; bool changed = !had_fbfetch;
if (ctx->fb_state.cbufs[0].texture) { if (ctx->fb_state.cbufs[0].texture) {
VkImageView fbfetch = zink_surface(ctx->fb_cbufs[0])->image_view; struct zink_surface *surf = zink_create_fb_surface(&ctx->base, ctx->fb_state.cbufs[0].texture, &ctx->fb_state.cbufs[0]);
if (!fbfetch) if (!surf)
/* swapchain image: retry later */ /* swapchain image: retry later */
return false; return false;
VkImageView fbfetch = surf->image_view;
changed |= fbfetch != ctx->di.fbfetch.imageView; changed |= fbfetch != ctx->di.fbfetch.imageView;
ctx->di.fbfetch.imageView = fbfetch; ctx->di.fbfetch.imageView = fbfetch;
@ -2845,7 +2844,6 @@ prep_fb_attachment(struct zink_context *ctx, struct zink_resource *res, unsigned
if (zink_is_swapchain(res)) { if (zink_is_swapchain(res)) {
if (!zink_kopper_acquire(ctx, res, UINT64_MAX)) if (!zink_kopper_acquire(ctx, res, UINT64_MAX))
return false; return false;
ctx->fb_cbufs[i] = (struct pipe_surface*)zink_surface_swapchain_update(ctx, &ctx->fb_state.cbufs[i]);
if (!i) if (!i)
zink_update_fbfetch(ctx); zink_update_fbfetch(ctx);
} }
@ -2911,7 +2909,6 @@ begin_rendering(struct zink_context *ctx, bool check_msaa_expand)
unsigned clear_buffers = 0; unsigned clear_buffers = 0;
struct zink_screen *screen = zink_screen(ctx->base.screen); struct zink_screen *screen = zink_screen(ctx->base.screen);
zink_update_vk_sample_locations(ctx); zink_update_vk_sample_locations(ctx);
zink_render_update_swapchain(ctx);
if (ctx->has_swapchain) if (ctx->has_swapchain)
zink_render_fixup_swapchain(ctx); zink_render_fixup_swapchain(ctx);
bool has_depth = false; bool has_depth = false;
@ -3093,22 +3090,21 @@ begin_rendering(struct zink_context *ctx, bool check_msaa_expand)
zink_batch_no_rp(ctx); zink_batch_no_rp(ctx);
for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) { for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
VkImageView iv = VK_NULL_HANDLE; VkImageView iv = VK_NULL_HANDLE;
struct zink_surface *surf = zink_surface(ctx->fb_cbufs[i]); struct zink_resource *res = zink_resource(ctx->fb_state.cbufs[i].texture);
if (surf) { if (res) {
struct zink_resource *res = zink_resource(surf->base.texture);
/* swapchain acquire can fail */ /* swapchain acquire can fail */
if (prep_fb_attachment(ctx, res, i)) if (prep_fb_attachment(ctx, res, i))
/* swapchain acquire can change this surface */ /* swapchain acquire can change this surface */
iv = zink_surface(ctx->fb_cbufs[i])->image_view; iv = zink_create_fb_surface(&ctx->base, ctx->fb_state.cbufs[i].texture, &ctx->fb_state.cbufs[i])->image_view;
if (ctx->fb_state.cbufs[i].nr_samples && !has_msrtss) { if (ctx->fb_state.cbufs[i].nr_samples && !has_msrtss) {
struct zink_surface *transient = ctx->transients[i];
struct zink_resource *transient_res = zink_resource(transient->base.texture);
prep_fb_attachment(ctx, transient_res, i);
iv = transient->image_view;
ctx->dynamic_fb.attachments[i].imageLayout = transient_res->layout;
ctx->dynamic_fb.attachments[i].resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; ctx->dynamic_fb.attachments[i].resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT;
ctx->dynamic_fb.attachments[i].resolveImageView = surf->image_view; ctx->dynamic_fb.attachments[i].resolveImageView = iv;
ctx->dynamic_fb.attachments[i].resolveImageLayout = res->layout; ctx->dynamic_fb.attachments[i].resolveImageLayout = res->layout;
iv = zink_create_transient_surface(ctx, &ctx->fb_state.cbufs[i], ctx->fb_state.cbufs[i].nr_samples)->image_view;
struct zink_resource *transient_res = res->transient;
prep_fb_attachment(ctx, transient_res, i);
ctx->dynamic_fb.attachments[i].imageLayout = transient_res->layout;
} else { } else {
ctx->dynamic_fb.attachments[i].imageLayout = res->layout; ctx->dynamic_fb.attachments[i].imageLayout = res->layout;
ctx->dynamic_fb.attachments[i].resolveMode = VK_RESOLVE_MODE_NONE; ctx->dynamic_fb.attachments[i].resolveMode = VK_RESOLVE_MODE_NONE;
@ -3142,27 +3138,25 @@ begin_rendering(struct zink_context *ctx, bool check_msaa_expand)
ctx->dynamic_fb.info.renderArea.extent.height = res->base.b.height0; ctx->dynamic_fb.info.renderArea.extent.height = res->base.b.height0;
} }
if (ctx->fb_state.zsbuf.texture && zsbuf_used) { if (ctx->fb_state.zsbuf.texture && zsbuf_used) {
struct zink_surface *surf = zink_surface(ctx->fb_zsbuf); struct zink_resource *res = zink_resource(ctx->fb_state.zsbuf.texture);
struct zink_resource *res = zink_resource(surf->base.texture);
VkImageView iv;
prep_fb_attachment(ctx, res, ctx->fb_state.nr_cbufs); prep_fb_attachment(ctx, res, ctx->fb_state.nr_cbufs);
VkImageView iv = zink_create_fb_surface(&ctx->base, ctx->fb_state.zsbuf.texture, &ctx->fb_state.zsbuf)->image_view;
if (ctx->fb_state.zsbuf.nr_samples && !has_msrtss) { if (ctx->fb_state.zsbuf.nr_samples && !has_msrtss) {
struct zink_surface *transient = ctx->transients[PIPE_MAX_COLOR_BUFS]; ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].resolveImageView = iv;
struct zink_resource *transient_res = zink_resource(transient->base.texture);
prep_fb_attachment(ctx, transient_res, ctx->fb_state.nr_cbufs);
iv = transient->image_view;
ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].imageLayout = transient_res->layout;
ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].resolveImageView = surf->image_view;
ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].resolveImageLayout = res->layout; ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].resolveImageLayout = res->layout;
iv = zink_create_transient_surface(ctx, &ctx->fb_state.zsbuf, ctx->fb_state.zsbuf.nr_samples)->image_view;
struct zink_resource *transient_res = res->transient;
prep_fb_attachment(ctx, transient_res, ctx->fb_state.nr_cbufs);
ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].imageLayout = transient_res->layout;
} else { } else {
iv = surf->image_view;
ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].imageLayout = res->layout; ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].imageLayout = res->layout;
} }
ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].imageView = iv; ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].imageView = iv;
assert(ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].imageLayout != VK_IMAGE_LAYOUT_UNDEFINED); assert(ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].imageLayout != VK_IMAGE_LAYOUT_UNDEFINED);
ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].imageView = iv; ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].imageView = iv;
ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].imageLayout = zink_resource(surf->base.texture)->layout; ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].imageLayout = res->layout;
assert(ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].imageLayout != VK_IMAGE_LAYOUT_UNDEFINED); assert(ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].imageLayout != VK_IMAGE_LAYOUT_UNDEFINED);
if (ctx->transient_attachments & BITFIELD_BIT(PIPE_MAX_COLOR_BUFS)) { if (ctx->transient_attachments & BITFIELD_BIT(PIPE_MAX_COLOR_BUFS)) {
ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].resolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].resolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
@ -3202,11 +3196,11 @@ begin_rendering(struct zink_context *ctx, bool check_msaa_expand)
screen->image_barrier(ctx, res, layout, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); screen->image_barrier(ctx, res, layout, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
res->obj->unordered_read = res->obj->unordered_write = false; res->obj->unordered_read = res->obj->unordered_write = false;
ctx->dynamic_fb.attachments[idx].resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; ctx->dynamic_fb.attachments[idx].resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT;
ctx->dynamic_fb.attachments[idx].resolveImageLayout = zink_resource(surf->base.texture)->layout; ctx->dynamic_fb.attachments[idx].resolveImageLayout = res->layout;
ctx->dynamic_fb.attachments[idx].resolveImageView = surf->image_view; ctx->dynamic_fb.attachments[idx].resolveImageView = surf->image_view;
if (idx == PIPE_MAX_COLOR_BUFS) { if (idx == PIPE_MAX_COLOR_BUFS) {
ctx->dynamic_fb.attachments[idx + 1].resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; ctx->dynamic_fb.attachments[idx + 1].resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT;
ctx->dynamic_fb.attachments[idx + 1].resolveImageLayout = zink_resource(surf->base.texture)->layout; ctx->dynamic_fb.attachments[idx + 1].resolveImageLayout = res->layout;
ctx->dynamic_fb.attachments[idx + 1].resolveImageView = surf->image_view; ctx->dynamic_fb.attachments[idx + 1].resolveImageView = surf->image_view;
} }
} }
@ -3635,32 +3629,6 @@ zink_flush_queue(struct zink_context *ctx)
flush_batch(ctx, true); flush_batch(ctx, true);
} }
static bool
rebind_fb_surface(struct zink_context *ctx, unsigned idx, struct zink_resource *match_res)
{
struct pipe_surface **psurf = idx == PIPE_MAX_COLOR_BUFS ? &ctx->fb_zsbuf : &ctx->fb_cbufs[idx];
struct pipe_surface *templ = idx == PIPE_MAX_COLOR_BUFS ? &ctx->fb_state.zsbuf : &ctx->fb_state.cbufs[idx];
if (!*psurf)
return false;
if ((*psurf)->texture != &match_res->base.b)
return false;
struct pipe_surface *new_psurf = zink_create_fb_surface(&ctx->base, templ->texture, templ);
if (*psurf == new_psurf)
return false;
*psurf = new_psurf;
return true;
}
static bool
rebind_fb_state(struct zink_context *ctx, struct zink_resource *match_res, bool from_set_fb)
{
bool rebind = false;
for (int i = 0; i < ctx->fb_state.nr_cbufs; i++)
rebind |= rebind_fb_surface(ctx, i, match_res);
rebind |= rebind_fb_surface(ctx, PIPE_MAX_COLOR_BUFS, match_res);
return rebind;
}
static void static void
pre_sync_transfer_barrier(struct zink_context *ctx, struct zink_resource *res, bool unsync) pre_sync_transfer_barrier(struct zink_context *ctx, struct zink_resource *res, bool unsync)
{ {
@ -3681,16 +3649,16 @@ static void
unbind_fb_surface(struct zink_context *ctx, const struct pipe_surface *surf, unsigned idx, bool changed) unbind_fb_surface(struct zink_context *ctx, const struct pipe_surface *surf, unsigned idx, bool changed)
{ {
bool general_layout = zink_screen(ctx->base.screen)->driver_workarounds.general_layout; bool general_layout = zink_screen(ctx->base.screen)->driver_workarounds.general_layout;
if (!surf->texture)
return;
ctx->dynamic_fb.attachments[idx].imageView = VK_NULL_HANDLE; ctx->dynamic_fb.attachments[idx].imageView = VK_NULL_HANDLE;
if (!surf) if (!surf)
return; return;
struct zink_resource *res = zink_resource(surf->texture); struct zink_resource *res = zink_resource(surf->texture);
if (changed) { if (changed) {
ctx->rp_changed = true; ctx->rp_changed = true;
if (ctx->transients[idx]) { if (surf->nr_samples && res->transient)
zink_resource(ctx->transients[idx]->base.texture)->valid = false; res->transient->valid = false;
pipe_resource_reference(&ctx->transients[idx]->base.texture, NULL);
}
} }
res->fb_bind_count--; res->fb_bind_count--;
if (!res->fb_bind_count && !res->bind_count[0]) if (!res->fb_bind_count && !res->bind_count[0])
@ -3786,14 +3754,6 @@ framebuffer_surface_needs_mutable(const struct pipe_resource *pres, const struct
return false; return false;
} }
static void
framebuffer_surface_init_transient(struct zink_context *ctx, const struct pipe_surface *psurf, int idx)
{
unsigned nr_samples = idx == PIPE_MAX_COLOR_BUFS ? ctx->fb_state.zsbuf.nr_samples : ctx->fb_state.cbufs[idx].nr_samples;
if (!zink_screen(ctx->base.screen)->info.have_EXT_multisampled_render_to_single_sampled)
ctx->transients[idx] = zink_create_transient_surface(ctx, psurf, nr_samples);
}
static void static void
zink_set_framebuffer_state(struct pipe_context *pctx, zink_set_framebuffer_state(struct pipe_context *pctx,
const struct pipe_framebuffer_state *state) const struct pipe_framebuffer_state *state)
@ -3863,7 +3823,6 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_BLEND_ON) | BITFIELD_BIT(ZINK_DS3_BLEND_WRITE) | BITFIELD_BIT(ZINK_DS3_BLEND_EQ); ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_BLEND_ON) | BITFIELD_BIT(ZINK_DS3_BLEND_WRITE) | BITFIELD_BIT(ZINK_DS3_BLEND_EQ);
} }
util_framebuffer_init(pctx, state, ctx->fb_cbufs, &ctx->fb_zsbuf);
util_copy_framebuffer_state(&ctx->fb_state, state); util_copy_framebuffer_state(&ctx->fb_state, state);
ctx->rp_changed |= zink_update_fbfetch(ctx); ctx->rp_changed |= zink_update_fbfetch(ctx);
ctx->transient_attachments = 0; ctx->transient_attachments = 0;
@ -3888,10 +3847,10 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
ctx->fb_formats[i] = zink_get_format(screen, ctx->fb_state.cbufs[i].format); ctx->fb_formats[i] = zink_get_format(screen, ctx->fb_state.cbufs[i].format);
if (res) { if (res) {
ctx->has_swapchain |= zink_is_swapchain(res); ctx->has_swapchain |= zink_is_swapchain(res);
if (ctx->fb_state.cbufs[i].nr_samples) { if (framebuffer_surface_needs_mutable(psurf->texture, psurf))
zink_resource_object_init_mutable(ctx, res);
if (ctx->fb_state.cbufs[i].nr_samples)
ctx->transient_attachments |= BITFIELD_BIT(i); ctx->transient_attachments |= BITFIELD_BIT(i);
framebuffer_surface_init_transient(ctx, psurf, i);
}
if (!samples) if (!samples)
samples = MAX3(ctx->fb_state.cbufs[i].nr_samples, psurf->texture->nr_samples, 1); samples = MAX3(ctx->fb_state.cbufs[i].nr_samples, psurf->texture->nr_samples, 1);
if (psurf->last_layer - psurf->first_layer > layers) if (psurf->last_layer - psurf->first_layer > layers)
@ -3917,20 +3876,20 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
} }
if (ctx->fb_state.zsbuf.texture) { if (ctx->fb_state.zsbuf.texture) {
struct pipe_surface *psurf = &ctx->fb_state.zsbuf; struct pipe_surface *psurf = &ctx->fb_state.zsbuf;
struct zink_resource *res = zink_resource(psurf->texture);
if (framebuffer_surface_needs_mutable(psurf->texture, psurf))
zink_resource_object_init_mutable(ctx, res);
ctx->fb_formats[PIPE_MAX_COLOR_BUFS] = zink_get_format(screen, ctx->fb_state.zsbuf.format); ctx->fb_formats[PIPE_MAX_COLOR_BUFS] = zink_get_format(screen, ctx->fb_state.zsbuf.format);
if (ctx->fb_state.zsbuf.nr_samples) { if (ctx->fb_state.zsbuf.nr_samples)
ctx->transient_attachments |= BITFIELD_BIT(PIPE_MAX_COLOR_BUFS); ctx->transient_attachments |= BITFIELD_BIT(PIPE_MAX_COLOR_BUFS);
framebuffer_surface_init_transient(ctx, psurf, PIPE_MAX_COLOR_BUFS);
}
if (!samples) if (!samples)
samples = MAX3(ctx->fb_state.zsbuf.nr_samples, psurf->texture->nr_samples, 1); samples = MAX3(ctx->fb_state.zsbuf.nr_samples, psurf->texture->nr_samples, 1);
if (psurf->last_layer - psurf->first_layer > layers) if (psurf->last_layer - psurf->first_layer > layers)
ctx->fb_layer_mismatch |= BITFIELD_BIT(PIPE_MAX_COLOR_BUFS); ctx->fb_layer_mismatch |= BITFIELD_BIT(PIPE_MAX_COLOR_BUFS);
zink_resource(psurf->texture)->fb_bind_count++; res->fb_bind_count++;
zink_resource(psurf->texture)->fb_binds |= BITFIELD_BIT(PIPE_MAX_COLOR_BUFS); res->fb_binds |= BITFIELD_BIT(PIPE_MAX_COLOR_BUFS);
} }
rebind_fb_state(ctx, NULL, true);
ctx->fb_state.samples = MAX2(samples, 1); ctx->fb_state.samples = MAX2(samples, 1);
if (ctx->fb_state.width != w || ctx->fb_state.height != h) if (ctx->fb_state.width != w || ctx->fb_state.height != h)
ctx->scissor_changed = true; ctx->scissor_changed = true;
@ -4430,33 +4389,6 @@ zink_set_stream_output_targets(struct pipe_context *pctx,
} }
} }
void
zink_rebind_framebuffer(struct zink_context *ctx, struct zink_resource *res)
{
bool did_rebind = false;
if (res->aspect & VK_IMAGE_ASPECT_COLOR_BIT) {
for (unsigned i = 0; i < ctx->fb_state.nr_cbufs; i++) {
if (zink_resource(ctx->fb_state.cbufs[i].texture) != res)
continue;
ctx->fb_cbufs[i] = zink_create_fb_surface(&ctx->base, &res->base.b, &ctx->fb_state.cbufs[i]);
did_rebind = true;
}
} else {
if (zink_resource(ctx->fb_state.zsbuf.texture) != res) {
ctx->fb_cbufs[PIPE_MAX_COLOR_BUFS] = zink_create_fb_surface(&ctx->base, &res->base.b, &ctx->fb_state.zsbuf);
did_rebind = true;
}
}
did_rebind |= rebind_fb_state(ctx, res, false);
if (!did_rebind)
return;
zink_batch_no_rp(ctx);
ctx->rp_changed = true;
}
ALWAYS_INLINE static struct zink_resource * ALWAYS_INLINE static struct zink_resource *
rebind_ubo(struct zink_context *ctx, gl_shader_stage shader, unsigned slot) rebind_ubo(struct zink_context *ctx, gl_shader_stage shader, unsigned slot)
{ {
@ -5049,12 +4981,29 @@ zink_resource_commit(struct pipe_context *pctx, struct pipe_resource *pres, unsi
return ret; return ret;
} }
static void
check_fb_rebind(struct zink_context *ctx, struct zink_resource *res)
{
if (res->aspect & VK_IMAGE_ASPECT_COLOR_BIT) {
for (unsigned i = 0; i < ctx->fb_state.nr_cbufs; i++) {
if (zink_resource(ctx->fb_state.cbufs[i].texture) == res)
return;
}
} else {
if (zink_resource(ctx->fb_state.zsbuf.texture) == res)
return;
}
/* next renderpass will automatically pull in new surface */
zink_batch_no_rp(ctx);
ctx->rp_changed = true;
}
static void static void
rebind_image(struct zink_context *ctx, struct zink_resource *res) rebind_image(struct zink_context *ctx, struct zink_resource *res)
{ {
assert(!ctx->blitting); assert(!ctx->blitting);
if (res->fb_binds) if (res->fb_binds)
zink_rebind_framebuffer(ctx, res); check_fb_rebind(ctx, res);
if (!zink_resource_has_binds(res)) if (!zink_resource_has_binds(res))
return; return;
bool general_layout = zink_screen(ctx->base.screen)->driver_workarounds.general_layout; bool general_layout = zink_screen(ctx->base.screen)->driver_workarounds.general_layout;
@ -5132,7 +5081,35 @@ void
zink_rebind_all_images(struct zink_context *ctx) zink_rebind_all_images(struct zink_context *ctx)
{ {
assert(!ctx->blitting); assert(!ctx->blitting);
rebind_fb_state(ctx, NULL, false); if (ctx->in_rp) {
bool changed = false;
for (unsigned i = 0; i < ctx->fb_state.nr_cbufs; i++) {
if (!ctx->fb_state.cbufs[i].texture)
continue;
struct zink_resource *res = zink_resource(ctx->fb_state.cbufs[i].texture);
struct zink_surface *surf = zink_create_fb_surface(&ctx->base, &res->base.b, &ctx->fb_state.cbufs[i]);
VkImageView iv = surf ? surf->image_view : VK_NULL_HANDLE;
if (res->transient) {
changed |= ctx->dynamic_fb.attachments[i].resolveImageView != iv;
} else {
changed |= ctx->dynamic_fb.attachments[i].imageView != iv;
}
}
if (ctx->fb_state.zsbuf.texture) {
struct zink_resource *res = zink_resource(ctx->fb_state.zsbuf.texture);
struct zink_surface *surf = zink_create_fb_surface(&ctx->base, &res->base.b, &ctx->fb_state.zsbuf);
VkImageView iv = surf ? surf->image_view : VK_NULL_HANDLE;
if (res->transient) {
changed |= ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].resolveImageView != iv;
} else {
changed |= ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].imageView != iv;
}
}
if (changed) {
zink_batch_no_rp(ctx);
ctx->rp_changed = true;
}
}
bool general_layout = zink_screen(ctx->base.screen)->driver_workarounds.general_layout; bool general_layout = zink_screen(ctx->base.screen)->driver_workarounds.general_layout;
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
for (unsigned j = 0; j < ctx->di.num_sampler_views[i]; j++) { for (unsigned j = 0; j < ctx->di.num_sampler_views[i]; j++) {
@ -5377,7 +5354,6 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
ctx->base.emit_string_marker = zink_emit_string_marker; ctx->base.emit_string_marker = zink_emit_string_marker;
zink_context_surface_init(&ctx->base);
zink_context_resource_init(&ctx->base); zink_context_resource_init(&ctx->base);
zink_context_query_init(&ctx->base); zink_context_query_init(&ctx->base);

View file

@ -258,8 +258,6 @@ zink_clamp_void_swizzle(const struct util_format_description *desc, enum pipe_sw
bool bool
zink_resource_rebind(struct zink_context *ctx, struct zink_resource *res); zink_resource_rebind(struct zink_context *ctx, struct zink_resource *res);
void
zink_rebind_framebuffer(struct zink_context *ctx, struct zink_resource *res);
void void
zink_set_null_fs(struct zink_context *ctx); zink_set_null_fs(struct zink_context *ctx);

View file

@ -1136,8 +1136,6 @@ zink_kopper_fixup_depth_buffer(struct zink_context *ctx)
res->base.b.width0 = ctx->fb_state.width; res->base.b.width0 = ctx->fb_state.width;
res->base.b.height0 = ctx->fb_state.height; res->base.b.height0 = ctx->fb_state.height;
pipe_resource_reference(&pz, NULL); pipe_resource_reference(&pz, NULL);
ctx->fb_zsbuf = zink_create_fb_surface(&ctx->base, &res->base.b, &ctx->fb_state.zsbuf);
} }
bool bool

View file

@ -254,20 +254,3 @@ zink_render_fixup_swapchain(struct zink_context *ctx)
ctx->swapchain_size.width = ctx->swapchain_size.height = 0; ctx->swapchain_size.width = ctx->swapchain_size.height = 0;
} }
} }
bool
zink_render_update_swapchain(struct zink_context *ctx)
{
bool has_swapchain = false;
for (unsigned i = 0; i < ctx->fb_state.nr_cbufs; i++) {
if (!ctx->fb_state.cbufs[i].texture)
continue;
struct zink_resource *res = zink_resource(ctx->fb_state.cbufs[i].texture);
if (zink_is_swapchain(res)) {
has_swapchain = true;
if (zink_kopper_acquire(ctx, res, UINT64_MAX))
ctx->fb_cbufs[i] = (struct pipe_surface*)zink_surface_swapchain_update(ctx, &ctx->fb_state.cbufs[i]);
}
}
return has_swapchain;
}

View file

@ -32,8 +32,6 @@ VkImageLayout
zink_tc_renderpass_info_parse(struct zink_context *ctx, const struct tc_renderpass_info *info, unsigned idx, VkPipelineStageFlags *pipeline, VkAccessFlags *access); zink_tc_renderpass_info_parse(struct zink_context *ctx, const struct tc_renderpass_info *info, unsigned idx, VkPipelineStageFlags *pipeline, VkAccessFlags *access);
bool bool
zink_init_render_pass(struct zink_context *ctx); zink_init_render_pass(struct zink_context *ctx);
bool
zink_render_update_swapchain(struct zink_context *ctx);
void void
zink_render_fixup_swapchain(struct zink_context *ctx); zink_render_fixup_swapchain(struct zink_context *ctx);
void void

View file

@ -107,19 +107,6 @@ create_ivci(struct zink_screen *screen,
return ivci; return ivci;
} }
static void
init_pipe_surface_info(struct pipe_context *pctx, struct pipe_surface *psurf, const struct pipe_surface *templ, const struct pipe_resource *pres)
{
unsigned int level = templ->level;
psurf->reference.count = 10000000;
psurf->context = pctx;
psurf->format = templ->format;
psurf->nr_samples = templ->nr_samples;
psurf->level = level;
psurf->first_layer = templ->first_layer;
psurf->last_layer = templ->last_layer;
}
static void static void
apply_view_usage_for_format(struct zink_screen *screen, struct pipe_resource *pres, enum pipe_format format, VkImageViewCreateInfo *ivci, VkImageViewUsageCreateInfo *usage_info) apply_view_usage_for_format(struct zink_screen *screen, struct pipe_resource *pres, enum pipe_format format, VkImageViewCreateInfo *ivci, VkImageViewUsageCreateInfo *usage_info)
{ {
@ -150,8 +137,7 @@ static struct zink_surface *
create_surface(struct pipe_context *pctx, create_surface(struct pipe_context *pctx,
struct pipe_resource *pres, struct pipe_resource *pres,
const struct pipe_surface *templ, const struct pipe_surface *templ,
VkImageViewCreateInfo *ivci, VkImageViewCreateInfo *ivci)
bool actually)
{ {
struct zink_screen *screen = zink_screen(pctx->screen); struct zink_screen *screen = zink_screen(pctx->screen);
@ -159,12 +145,6 @@ create_surface(struct pipe_context *pctx,
if (!surface) if (!surface)
return NULL; return NULL;
surface->base.texture = pres;
pipe_reference_init(&surface->base.reference, 1);
init_pipe_surface_info(pctx, &surface->base, templ, pres);
if (!actually)
return surface;
assert(ivci->image); assert(ivci->image);
VkImageViewUsageCreateInfo usage_info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO }; VkImageViewUsageCreateInfo usage_info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO };
apply_view_usage_for_format(screen, pres, templ->format, ivci, &usage_info); apply_view_usage_for_format(screen, pres, templ->format, ivci, &usage_info);
@ -218,9 +198,7 @@ zink_get_surface(struct zink_context *ctx,
struct hash_entry *entry = _mesa_hash_table_search_pre_hashed(ht, hash, ivci); struct hash_entry *entry = _mesa_hash_table_search_pre_hashed(ht, hash, ivci);
if (!entry) { if (!entry) {
surface = create_surface(&ctx->base, pres, templ, ivci, true); surface = create_surface(&ctx->base, pres, templ, ivci);
/* only transient surfaces have nr_samples set */
surface->base.nr_samples = zink_screen(ctx->base.screen)->info.have_EXT_multisampled_render_to_single_sampled ? templ->nr_samples : 0;
entry = _mesa_hash_table_insert_pre_hashed(ht, hash, mem_dup(ivci, sizeof(*ivci)), surface); entry = _mesa_hash_table_insert_pre_hashed(ht, hash, mem_dup(ivci, sizeof(*ivci)), surface);
if (!entry) { if (!entry) {
simple_mtx_unlock(&res->obj->surface_mtx); simple_mtx_unlock(&res->obj->surface_mtx);
@ -236,17 +214,6 @@ zink_get_surface(struct zink_context *ctx,
return surface; return surface;
} }
/* this is the context hook, so only zink_ctx_surfaces will reach it */
static void
zink_surface_destroy(struct pipe_context *pctx,
struct pipe_surface *psurface)
{
/* ensure this gets repopulated if another transient surface is created */
struct zink_resource *res = zink_resource(psurface->texture);
if (res->transient)
res->transient->valid = false;
}
static VkImageViewCreateInfo static VkImageViewCreateInfo
create_fb_ivci(struct zink_screen *screen, struct zink_resource *res, const struct pipe_surface *templ) create_fb_ivci(struct zink_screen *screen, struct zink_resource *res, const struct pipe_surface *templ)
{ {
@ -256,7 +223,7 @@ create_fb_ivci(struct zink_screen *screen, struct zink_resource *res, const stru
return create_ivci(screen, res, templ, res->base.b.target == PIPE_TEXTURE_3D ? target_2d[is_array] : res->base.b.target); return create_ivci(screen, res, templ, res->base.b.target == PIPE_TEXTURE_3D ? target_2d[is_array] : res->base.b.target);
} }
struct pipe_surface * struct zink_surface *
zink_create_fb_surface(struct pipe_context *pctx, zink_create_fb_surface(struct pipe_context *pctx,
struct pipe_resource *pres, struct pipe_resource *pres,
const struct pipe_surface *templ) const struct pipe_surface *templ)
@ -264,15 +231,7 @@ zink_create_fb_surface(struct pipe_context *pctx,
struct zink_resource *res = zink_resource(pres); struct zink_resource *res = zink_resource(pres);
VkImageViewCreateInfo ivci = create_fb_ivci(zink_screen(pctx->screen), res, templ); VkImageViewCreateInfo ivci = create_fb_ivci(zink_screen(pctx->screen), res, templ);
return (struct pipe_surface*)zink_get_surface(zink_context(pctx), pres, templ, &ivci); return zink_get_surface(zink_context(pctx), pres, templ, &ivci);
}
static struct pipe_surface *
zink_create_surface(struct pipe_context *pctx,
struct pipe_resource *pres,
const struct pipe_surface *templ)
{
return zink_create_fb_surface(pctx, pres, templ);
} }
struct zink_surface * struct zink_surface *
@ -299,24 +258,3 @@ zink_create_transient_surface(struct zink_context *ctx, const struct pipe_surfac
ivci.pNext = NULL; ivci.pNext = NULL;
return zink_get_surface(ctx, &transient->base.b, psurf, &ivci); return zink_get_surface(ctx, &transient->base.b, psurf, &ivci);
} }
void
zink_context_surface_init(struct pipe_context *context)
{
context->create_surface = zink_create_surface;
context->surface_destroy = zink_surface_destroy;
}
/* must be called before a swapchain image is used to ensure correct imageview is used */
struct zink_surface *
zink_surface_swapchain_update(struct zink_context *ctx, struct pipe_surface *psurf)
{
struct zink_screen *screen = zink_screen(ctx->base.screen);
struct zink_resource *res = zink_resource(psurf->texture);
struct kopper_displaytarget *cdt = res->obj->dt;
if (!cdt)
return NULL; //dead swapchain
VkImageViewCreateInfo ivci = create_ivci(screen, res, psurf, psurf->first_layer != psurf->last_layer ? PIPE_TEXTURE_2D_ARRAY : PIPE_TEXTURE_2D);
return zink_get_surface(ctx, &res->base.b, psurf, &ivci);
}

View file

@ -26,12 +26,6 @@
#include "zink_types.h" #include "zink_types.h"
void
zink_destroy_surface(struct zink_screen *screen, struct pipe_surface *psurface);
void
zink_context_surface_init(struct pipe_context *context);
static inline bool static inline bool
equals_ivci(const void *a, const void *b) equals_ivci(const void *a, const void *b)
{ {
@ -53,7 +47,7 @@ zink_get_surface(struct zink_context *ctx,
const struct pipe_surface *templ, const struct pipe_surface *templ,
VkImageViewCreateInfo *ivci); VkImageViewCreateInfo *ivci);
struct pipe_surface * struct zink_surface *
zink_create_fb_surface(struct pipe_context *pctx, zink_create_fb_surface(struct pipe_context *pctx,
struct pipe_resource *pres, struct pipe_resource *pres,
const struct pipe_surface *templ); const struct pipe_surface *templ);
@ -75,7 +69,4 @@ zink_surface_clamp_viewtype(VkImageViewType viewType, unsigned first_layer, unsi
return viewType; return viewType;
} }
struct zink_surface *
zink_surface_swapchain_update(struct zink_context *ctx, struct pipe_surface *psurf);
#endif #endif

View file

@ -1520,24 +1520,11 @@ zink_screen(struct pipe_screen *pipe)
/** surface types */ /** surface types */
/* an imageview for a zink_resource: /* this type only exists for compat with 32bit builds because vk types are 64bit */
- may be a fb attachment, samplerview, or shader image
- cached on the parent zink_resource_object
- also handles swapchains
*/
struct zink_surface { struct zink_surface {
struct pipe_surface base;
/* the current imageview */
VkImageView image_view; VkImageView image_view;
}; };
/* use this cast for internal surfaces */
static inline struct zink_surface *
zink_surface(struct pipe_surface *psurface)
{
return (struct zink_surface *)psurface;
}
/** context types */ /** context types */
struct zink_sampler_state { struct zink_sampler_state {
@ -1705,8 +1692,6 @@ struct zink_context {
uint32_t transient_attachments; uint32_t transient_attachments;
struct pipe_framebuffer_state fb_state; struct pipe_framebuffer_state fb_state;
PIPE_FB_SURFACES; //STOP USING THIS
struct zink_surface *transients[PIPE_MAX_COLOR_BUFS + 1]; //AND THIS (probably)
VkFormat fb_formats[PIPE_MAX_COLOR_BUFS + 1]; VkFormat fb_formats[PIPE_MAX_COLOR_BUFS + 1];
struct zink_vertex_elements_state *element_state; struct zink_vertex_elements_state *element_state;