zink: add a dynamic render version of clear_texture hook

this avoids the (sizable) overhead of going through the previous path
with set_frame_buffer state et al, instead just firing off a quick
begin+end rendering with a clear

it's also easily reorderable

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21906>
This commit is contained in:
Mike Blumenkrantz 2023-03-02 12:12:32 -05:00 committed by Marge Bot
parent e1621d3e6d
commit 7411264ca6
3 changed files with 88 additions and 1 deletions

View File

@ -436,6 +436,87 @@ set_clear_fb(struct pipe_context *pctx, struct pipe_surface *psurf, struct pipe_
pctx->set_framebuffer_state(pctx, &fb_state);
}
void
zink_clear_texture_dynamic(struct pipe_context *pctx,
struct pipe_resource *pres,
unsigned level,
const struct pipe_box *box,
const void *data)
{
struct zink_context *ctx = zink_context(pctx);
struct zink_resource *res = zink_resource(pres);
bool full_clear = 0 <= box->x && u_minify(pres->width0, level) >= box->x + box->width &&
0 <= box->y && u_minify(pres->height0, level) >= box->y + box->height &&
0 <= box->z && u_minify(pres->target == PIPE_TEXTURE_3D ? pres->depth0 : pres->array_size, level) >= box->z + box->depth;
struct pipe_surface *surf = create_clear_surface(pctx, pres, level, box);
VkRenderingAttachmentInfo att = {0};
att.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
att.imageView = zink_csurface(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.loadOp = full_clear ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
att.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
VkRenderingInfo info = {0};
info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
info.renderArea.offset.x = box->x;
info.renderArea.offset.y = box->y;
info.renderArea.extent.width = box->width;
info.renderArea.extent.height = box->height;
info.layerCount = MAX2(box->depth, 1);
union pipe_color_union color;
float depth = 0.0;
uint8_t stencil = 0;
if (res->aspect & VK_IMAGE_ASPECT_COLOR_BIT) {
util_format_unpack_rgba(pres->format, color.ui, data, 1);
} else {
if (res->aspect & VK_IMAGE_ASPECT_DEPTH_BIT)
util_format_unpack_z_float(pres->format, &depth, data, 1);
if (res->aspect & VK_IMAGE_ASPECT_STENCIL_BIT)
util_format_unpack_s_8uint(pres->format, &stencil, data, 1);
}
zink_blit_barriers(ctx, NULL, res, full_clear);
VkCommandBuffer cmdbuf = zink_get_cmdbuf(ctx, NULL, res);
if (cmdbuf == ctx->batch.state->cmdbuf && ctx->batch.in_rp)
zink_batch_no_rp(ctx);
if (res->aspect & VK_IMAGE_ASPECT_COLOR_BIT) {
memcpy(&att.clearValue, &color, sizeof(float) * 4);
info.colorAttachmentCount = 1;
info.pColorAttachments = &att;
} else {
att.clearValue.depthStencil.depth = depth;
att.clearValue.depthStencil.stencil = stencil;
if (res->aspect & VK_IMAGE_ASPECT_DEPTH_BIT)
info.pDepthAttachment = &att;
if (res->aspect & VK_IMAGE_ASPECT_STENCIL_BIT)
info.pStencilAttachment = &att;
}
VKCTX(CmdBeginRendering)(cmdbuf, &info);
if (!full_clear) {
VkClearRect rect;
rect.rect = info.renderArea;
rect.baseArrayLayer = box->z;
rect.layerCount = box->depth;
VkClearAttachment clear_att;
clear_att.aspectMask = res->aspect;
clear_att.colorAttachment = 0;
clear_att.clearValue = att.clearValue;
VKCTX(CmdClearAttachments)(cmdbuf, 1, &clear_att, 1, &rect);
}
VKCTX(CmdEndRendering)(cmdbuf);
zink_batch_reference_resource_rw(&ctx->batch, res, true);
/* this will never destroy the surface */
pipe_surface_reference(&surf, NULL);
}
void
zink_clear_texture(struct pipe_context *pctx,
struct pipe_resource *pres,

View File

@ -40,6 +40,12 @@ zink_clear_texture(struct pipe_context *ctx,
const struct pipe_box *box,
const void *data);
void
zink_clear_texture_dynamic(struct pipe_context *ctx,
struct pipe_resource *p_res,
unsigned level,
const struct pipe_box *box,
const void *data);
void
zink_clear_buffer(struct pipe_context *pctx,
struct pipe_resource *pres,
unsigned offset,

View File

@ -5316,7 +5316,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
ctx->gfx_pipeline_state.sample_mask = UINT32_MAX;
ctx->base.clear = zink_clear;
ctx->base.clear_texture = zink_clear_texture;
ctx->base.clear_texture = screen->info.have_KHR_dynamic_rendering ? zink_clear_texture_dynamic : zink_clear_texture;
ctx->base.clear_buffer = zink_clear_buffer;
ctx->base.clear_render_target = zink_clear_render_target;
ctx->base.clear_depth_stencil = zink_clear_depth_stencil;