zink: handle clears with scissor regions
this just sets the info struct members as needed Reviewed-by: Adam Jackson <ajax@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8512>
This commit is contained in:
parent
196794264f
commit
a131d06f17
|
@ -23,8 +23,26 @@
|
|||
|
||||
#include "zink_context.h"
|
||||
#include "zink_resource.h"
|
||||
#include "util/format/u_format.h"
|
||||
#include "util/u_framebuffer.h"
|
||||
#include "util/format_srgb.h"
|
||||
#include "util/u_rect.h"
|
||||
|
||||
static inline bool
|
||||
check_3d_layers(struct pipe_surface *psurf)
|
||||
{
|
||||
/* SPEC PROBLEM:
|
||||
* though the vk spec doesn't seem to explicitly address this, currently drivers
|
||||
* are claiming that all 3D images have a single "3D" layer regardless of layercount,
|
||||
* so we can never clear them if we aren't trying to clear only layer 0
|
||||
*/
|
||||
if (psurf->u.tex.first_layer)
|
||||
return false;
|
||||
|
||||
if (psurf->u.tex.last_layer - psurf->u.tex.first_layer > 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_in_rp(struct pipe_context *pctx,
|
||||
|
@ -72,11 +90,16 @@ clear_in_rp(struct pipe_context *pctx,
|
|||
++num_attachments;
|
||||
}
|
||||
|
||||
VkClearRect cr;
|
||||
cr.rect.offset.x = 0;
|
||||
cr.rect.offset.y = 0;
|
||||
cr.rect.extent.width = fb->width;
|
||||
cr.rect.extent.height = fb->height;
|
||||
VkClearRect cr = {};
|
||||
if (scissor_state) {
|
||||
cr.rect.offset.x = scissor_state->minx;
|
||||
cr.rect.offset.y = scissor_state->miny;
|
||||
cr.rect.extent.width = MIN2(fb->width, scissor_state->maxx - scissor_state->minx);
|
||||
cr.rect.extent.height = MIN2(fb->height, scissor_state->maxy - scissor_state->miny);
|
||||
} else {
|
||||
cr.rect.extent.width = fb->width;
|
||||
cr.rect.extent.height = fb->height;
|
||||
}
|
||||
cr.baseArrayLayer = 0;
|
||||
cr.layerCount = util_framebuffer_get_num_layers(fb);
|
||||
vkCmdClearAttachments(batch->cmdbuf, num_attachments, attachments, 1, &cr);
|
||||
|
@ -90,16 +113,94 @@ zink_clear(struct pipe_context *pctx,
|
|||
double depth, unsigned stencil)
|
||||
{
|
||||
struct zink_context *ctx = zink_context(pctx);
|
||||
struct pipe_framebuffer_state *fb = &ctx->fb_state;
|
||||
struct zink_batch *batch = zink_curr_batch(ctx);
|
||||
|
||||
/* FIXME: this is very inefficient; if no renderpass has been started yet,
|
||||
* we should record the clear if it's full-screen, and apply it as we
|
||||
* start the render-pass. Otherwise we can do a partial out-of-renderpass
|
||||
* clear.
|
||||
*/
|
||||
zink_batch_rp(ctx);
|
||||
assert(zink_curr_batch(ctx)->in_rp);
|
||||
if (zink_curr_batch(ctx)->in_rp || ctx->render_condition_active) {
|
||||
if (scissor_state) {
|
||||
bool need_rp = false;
|
||||
struct u_rect intersect = {0, fb->width, 0, fb->height};
|
||||
struct u_rect scissor = {scissor_state->minx, scissor_state->maxx, scissor_state->miny, scissor_state->maxy};
|
||||
if (!u_rect_test_intersection(&scissor, &intersect))
|
||||
need_rp = true;
|
||||
else {
|
||||
u_rect_find_intersection(&scissor, &intersect);
|
||||
if (intersect.x0 != 0 || intersect.y0 != 0 ||
|
||||
intersect.x1 != fb->width || intersect.y1 != fb->height)
|
||||
need_rp = true;
|
||||
}
|
||||
if (need_rp)
|
||||
/* FIXME: this is very inefficient; if no renderpass has been started yet,
|
||||
* we should record the clear if it's full-screen, and apply it as we
|
||||
* start the render-pass. Otherwise we can do a partial out-of-renderpass
|
||||
* clear.
|
||||
*/
|
||||
batch = zink_batch_rp(ctx);
|
||||
}
|
||||
|
||||
if (batch->in_rp || ctx->render_condition_active) {
|
||||
clear_in_rp(pctx, buffers, scissor_state, pcolor, depth, stencil);
|
||||
return;
|
||||
}
|
||||
|
||||
VkImageSubresourceRange range = {};
|
||||
range.levelCount = 1;
|
||||
if (buffers & PIPE_CLEAR_COLOR) {
|
||||
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
for (unsigned i = 0; i < fb->nr_cbufs; i++) {
|
||||
if (!(buffers & (PIPE_CLEAR_COLOR0 << i)) || !fb->cbufs[i])
|
||||
continue;
|
||||
VkClearColorValue color;
|
||||
struct pipe_surface *psurf = fb->cbufs[i];
|
||||
|
||||
if (psurf->texture->target == PIPE_TEXTURE_3D && !check_3d_layers(psurf)) {
|
||||
clear_in_rp(pctx, buffers, scissor_state, pcolor, depth, stencil);
|
||||
return;
|
||||
}
|
||||
|
||||
struct zink_resource *res = zink_resource(psurf->texture);
|
||||
if (res->layout != VK_IMAGE_LAYOUT_GENERAL && res->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
|
||||
zink_resource_barrier(batch->cmdbuf, res, range.aspectMask, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
if (psurf->format != res->base.format &&
|
||||
!util_format_is_srgb(psurf->format) && util_format_is_srgb(res->base.format)) {
|
||||
/* if SRGB mode is disabled for the fb with a backing srgb image then we have to
|
||||
* convert this to srgb color
|
||||
*/
|
||||
color.float32[0] = util_format_srgb_to_linear_float(pcolor->f[0]);
|
||||
color.float32[1] = util_format_srgb_to_linear_float(pcolor->f[1]);
|
||||
color.float32[2] = util_format_srgb_to_linear_float(pcolor->f[2]);
|
||||
} else {
|
||||
color.float32[0] = pcolor->f[0];
|
||||
color.float32[1] = pcolor->f[1];
|
||||
color.float32[2] = pcolor->f[2];
|
||||
}
|
||||
color.float32[3] = pcolor->f[3];
|
||||
range.baseMipLevel = psurf->u.tex.level;
|
||||
range.baseArrayLayer = psurf->u.tex.first_layer;
|
||||
range.layerCount = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1;
|
||||
|
||||
vkCmdClearColorImage(batch->cmdbuf, res->image, res->layout, &color, 1, &range);
|
||||
}
|
||||
}
|
||||
|
||||
range.aspectMask = 0;
|
||||
if (buffers & PIPE_CLEAR_DEPTHSTENCIL && fb->zsbuf) {
|
||||
if (fb->zsbuf->texture->target == PIPE_TEXTURE_3D && !check_3d_layers(fb->zsbuf)) {
|
||||
clear_in_rp(pctx, buffers, scissor_state, pcolor, depth, stencil);
|
||||
return;
|
||||
}
|
||||
|
||||
if (buffers & PIPE_CLEAR_DEPTH)
|
||||
range.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
if (buffers & PIPE_CLEAR_STENCIL)
|
||||
range.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
VkClearDepthStencilValue zs_value = {depth, stencil};
|
||||
range.baseMipLevel = fb->zsbuf->u.tex.level;
|
||||
range.baseArrayLayer = fb->zsbuf->u.tex.first_layer;
|
||||
range.layerCount = fb->zsbuf->u.tex.last_layer - fb->zsbuf->u.tex.first_layer + 1;
|
||||
|
||||
struct zink_resource *res = zink_resource(fb->zsbuf->texture);
|
||||
if (res->layout != VK_IMAGE_LAYOUT_GENERAL && res->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
|
||||
zink_resource_barrier(batch->cmdbuf, res, range.aspectMask, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
vkCmdClearDepthStencilImage(batch->cmdbuf, res->image, res->layout, &zs_value, 1, &range);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue