mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 13:40:16 +01:00
zink: defer pipe_context::clear calls when not currently in a renderpass
instead, we can attach the clear to the next renderpass start and even add it to the renderpass cache for reuse also add handling for flushing clears on map or fb switching to avoid brekaing behavior this should save us a lot of time with potentially beginning/ending renderpasses as well as allowing drivers to do better batching of clears by passing in all the buffers at once this doesn't handle deferring conditional renders yet in a futile attempt to try and keep the size of the patch down Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9206>
This commit is contained in:
parent
b37cba8271
commit
5c629e9ff2
7 changed files with 379 additions and 49 deletions
|
|
@ -36,6 +36,9 @@ blit_resolve(struct zink_context *ctx, const struct pipe_blit_info *info)
|
||||||
if (info->dst.resource->target == PIPE_BUFFER)
|
if (info->dst.resource->target == PIPE_BUFFER)
|
||||||
util_range_add(info->dst.resource, &dst->valid_buffer_range,
|
util_range_add(info->dst.resource, &dst->valid_buffer_range,
|
||||||
info->dst.box.x, info->dst.box.x + info->dst.box.width);
|
info->dst.box.x, info->dst.box.x + info->dst.box.width);
|
||||||
|
|
||||||
|
zink_fb_clears_apply(ctx, info->dst.resource);
|
||||||
|
zink_fb_clears_apply(ctx, info->src.resource);
|
||||||
struct zink_batch *batch = zink_batch_no_rp(ctx);
|
struct zink_batch *batch = zink_batch_no_rp(ctx);
|
||||||
|
|
||||||
zink_batch_reference_resource_rw(batch, src, false);
|
zink_batch_reference_resource_rw(batch, src, false);
|
||||||
|
|
@ -116,6 +119,8 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info)
|
||||||
dst->format != zink_get_format(screen, info->dst.format))
|
dst->format != zink_get_format(screen, info->dst.format))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
zink_fb_clears_apply(ctx, info->dst.resource);
|
||||||
|
zink_fb_clears_apply(ctx, info->src.resource);
|
||||||
struct zink_batch *batch = zink_batch_no_rp(ctx);
|
struct zink_batch *batch = zink_batch_no_rp(ctx);
|
||||||
zink_batch_reference_resource_rw(batch, src, false);
|
zink_batch_reference_resource_rw(batch, src, false);
|
||||||
zink_batch_reference_resource_rw(batch, dst, true);
|
zink_batch_reference_resource_rw(batch, dst, true);
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include "zink_screen.h"
|
#include "zink_screen.h"
|
||||||
|
|
||||||
#include "util/u_blitter.h"
|
#include "util/u_blitter.h"
|
||||||
|
#include "util/u_dynarray.h"
|
||||||
#include "util/format/u_format.h"
|
#include "util/format/u_format.h"
|
||||||
#include "util/format_srgb.h"
|
#include "util/format_srgb.h"
|
||||||
#include "util/u_framebuffer.h"
|
#include "util/u_framebuffer.h"
|
||||||
|
|
@ -36,6 +37,8 @@
|
||||||
static inline bool
|
static inline bool
|
||||||
check_3d_layers(struct pipe_surface *psurf)
|
check_3d_layers(struct pipe_surface *psurf)
|
||||||
{
|
{
|
||||||
|
if (psurf->texture->target != PIPE_TEXTURE_3D)
|
||||||
|
return true;
|
||||||
/* SPEC PROBLEM:
|
/* SPEC PROBLEM:
|
||||||
* though the vk spec doesn't seem to explicitly address this, currently drivers
|
* 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,
|
* are claiming that all 3D images have a single "3D" layer regardless of layercount,
|
||||||
|
|
@ -49,6 +52,12 @@ check_3d_layers(struct pipe_surface *psurf)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
scissor_states_equal(const struct pipe_scissor_state *a, const struct pipe_scissor_state *b)
|
||||||
|
{
|
||||||
|
return a->minx == b->minx && a->miny == b->miny && a->maxx == b->maxx && a->maxy == b->maxy;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clear_in_rp(struct pipe_context *pctx,
|
clear_in_rp(struct pipe_context *pctx,
|
||||||
unsigned buffers,
|
unsigned buffers,
|
||||||
|
|
@ -58,8 +67,6 @@ clear_in_rp(struct pipe_context *pctx,
|
||||||
{
|
{
|
||||||
struct zink_context *ctx = zink_context(pctx);
|
struct zink_context *ctx = zink_context(pctx);
|
||||||
struct pipe_framebuffer_state *fb = &ctx->fb_state;
|
struct pipe_framebuffer_state *fb = &ctx->fb_state;
|
||||||
struct zink_resource *resources[PIPE_MAX_COLOR_BUFS + 1] = {};
|
|
||||||
int res_count = 0;
|
|
||||||
|
|
||||||
VkClearAttachment attachments[1 + PIPE_MAX_COLOR_BUFS];
|
VkClearAttachment attachments[1 + PIPE_MAX_COLOR_BUFS];
|
||||||
int num_attachments = 0;
|
int num_attachments = 0;
|
||||||
|
|
@ -79,9 +86,6 @@ clear_in_rp(struct pipe_context *pctx,
|
||||||
attachments[num_attachments].colorAttachment = i;
|
attachments[num_attachments].colorAttachment = i;
|
||||||
attachments[num_attachments].clearValue.color = color;
|
attachments[num_attachments].clearValue.color = color;
|
||||||
++num_attachments;
|
++num_attachments;
|
||||||
struct zink_resource *res = (struct zink_resource*)fb->cbufs[i]->texture;
|
|
||||||
zink_resource_image_barrier(ctx, NULL, res, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, 0);
|
|
||||||
resources[res_count++] = res;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,9 +100,6 @@ clear_in_rp(struct pipe_context *pctx,
|
||||||
attachments[num_attachments].clearValue.depthStencil.depth = depth;
|
attachments[num_attachments].clearValue.depthStencil.depth = depth;
|
||||||
attachments[num_attachments].clearValue.depthStencil.stencil = stencil;
|
attachments[num_attachments].clearValue.depthStencil.stencil = stencil;
|
||||||
++num_attachments;
|
++num_attachments;
|
||||||
struct zink_resource *res = (struct zink_resource*)fb->zsbuf->texture;
|
|
||||||
zink_resource_image_barrier(ctx, NULL, res, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 0, 0);
|
|
||||||
resources[res_count++] = res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkClearRect cr = {};
|
VkClearRect cr = {};
|
||||||
|
|
@ -114,8 +115,6 @@ clear_in_rp(struct pipe_context *pctx,
|
||||||
cr.baseArrayLayer = 0;
|
cr.baseArrayLayer = 0;
|
||||||
cr.layerCount = util_framebuffer_get_num_layers(fb);
|
cr.layerCount = util_framebuffer_get_num_layers(fb);
|
||||||
struct zink_batch *batch = zink_batch_rp(ctx);
|
struct zink_batch *batch = zink_batch_rp(ctx);
|
||||||
for (int i = 0; i < res_count; i++)
|
|
||||||
zink_batch_reference_resource_rw(batch, resources[i], true);
|
|
||||||
vkCmdClearAttachments(batch->cmdbuf, num_attachments, attachments, 1, &cr);
|
vkCmdClearAttachments(batch->cmdbuf, num_attachments, attachments, 1, &cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -168,11 +167,6 @@ clear_needs_rp(unsigned width, unsigned height, struct u_rect *region)
|
||||||
{
|
{
|
||||||
struct u_rect intersect = {0, width, 0, height};
|
struct u_rect intersect = {0, width, 0, height};
|
||||||
|
|
||||||
/* 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.
|
|
||||||
*/
|
|
||||||
if (!u_rect_test_intersection(region, &intersect))
|
if (!u_rect_test_intersection(region, &intersect))
|
||||||
/* is this even a thing? */
|
/* is this even a thing? */
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -185,6 +179,25 @@ clear_needs_rp(unsigned width, unsigned height, struct u_rect *region)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct zink_framebuffer_clear_data *
|
||||||
|
get_clear_data(struct zink_context *ctx, struct zink_framebuffer_clear *fb_clear, const struct pipe_scissor_state *scissor_state)
|
||||||
|
{
|
||||||
|
struct zink_framebuffer_clear_data *clear = NULL;
|
||||||
|
unsigned num_clears = zink_fb_clear_count(fb_clear);
|
||||||
|
if (num_clears) {
|
||||||
|
struct zink_framebuffer_clear_data *last_clear = zink_fb_clear_element(fb_clear, num_clears - 1);
|
||||||
|
/* if we're completely overwriting the previous clear, merge this into the previous clear */
|
||||||
|
if (!scissor_state || (last_clear->has_scissor && scissor_states_equal(&last_clear->scissor, scissor_state)))
|
||||||
|
clear = last_clear;
|
||||||
|
}
|
||||||
|
if (!clear) {
|
||||||
|
struct zink_framebuffer_clear_data cd = {};
|
||||||
|
util_dynarray_append(&fb_clear->clears, struct zink_framebuffer_clear_data, cd);
|
||||||
|
clear = zink_fb_clear_element(fb_clear, zink_fb_clear_count(fb_clear) - 1);
|
||||||
|
}
|
||||||
|
return clear;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zink_clear(struct pipe_context *pctx,
|
zink_clear(struct pipe_context *pctx,
|
||||||
unsigned buffers,
|
unsigned buffers,
|
||||||
|
|
@ -203,7 +216,7 @@ zink_clear(struct pipe_context *pctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (needs_rp || batch->in_rp || ctx->render_condition_active) {
|
if (batch->in_rp || ctx->render_condition_active) {
|
||||||
clear_in_rp(pctx, buffers, scissor_state, pcolor, depth, stencil);
|
clear_in_rp(pctx, buffers, scissor_state, pcolor, depth, stencil);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -212,45 +225,129 @@ zink_clear(struct pipe_context *pctx,
|
||||||
for (unsigned i = 0; i < fb->nr_cbufs; i++) {
|
for (unsigned i = 0; i < fb->nr_cbufs; i++) {
|
||||||
if ((buffers & (PIPE_CLEAR_COLOR0 << i)) && fb->cbufs[i]) {
|
if ((buffers & (PIPE_CLEAR_COLOR0 << i)) && fb->cbufs[i]) {
|
||||||
struct pipe_surface *psurf = fb->cbufs[i];
|
struct pipe_surface *psurf = fb->cbufs[i];
|
||||||
|
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[i];
|
||||||
|
struct zink_framebuffer_clear_data *clear = get_clear_data(ctx, fb_clear, needs_rp ? scissor_state : NULL);
|
||||||
|
|
||||||
if (psurf->texture->target == PIPE_TEXTURE_3D && !check_3d_layers(psurf)) {
|
fb_clear->enabled = true;
|
||||||
clear_in_rp(pctx, buffers, scissor_state, pcolor, depth, stencil);
|
clear->has_scissor = needs_rp;
|
||||||
return;
|
if (scissor_state && needs_rp)
|
||||||
}
|
clear->scissor = *scissor_state;
|
||||||
struct zink_resource *res = zink_resource(psurf->texture);
|
clear->color.color = *pcolor;
|
||||||
union pipe_color_union color = *pcolor;
|
clear->color.srgb = psurf->format != psurf->texture->format &&
|
||||||
if (psurf->format != res->base.format &&
|
!util_format_is_srgb(psurf->format) && util_format_is_srgb(psurf->texture->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.f[0] = util_format_srgb_to_linear_float(pcolor->f[0]);
|
|
||||||
color.f[1] = util_format_srgb_to_linear_float(pcolor->f[1]);
|
|
||||||
color.f[2] = util_format_srgb_to_linear_float(pcolor->f[2]);
|
|
||||||
}
|
|
||||||
clear_color_no_rp(ctx, zink_resource(fb->cbufs[i]->texture), &color,
|
|
||||||
psurf->u.tex.level, psurf->u.tex.first_layer,
|
|
||||||
psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffers & PIPE_CLEAR_DEPTHSTENCIL && fb->zsbuf) {
|
if (buffers & PIPE_CLEAR_DEPTHSTENCIL && fb->zsbuf) {
|
||||||
if (fb->zsbuf->texture->target == PIPE_TEXTURE_3D && !check_3d_layers(fb->zsbuf)) {
|
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[PIPE_MAX_COLOR_BUFS];
|
||||||
clear_in_rp(pctx, buffers, scissor_state, pcolor, depth, stencil);
|
struct zink_framebuffer_clear_data *clear = get_clear_data(ctx, fb_clear, needs_rp ? scissor_state : NULL);
|
||||||
return;
|
fb_clear->enabled = true;
|
||||||
}
|
clear->has_scissor = needs_rp;
|
||||||
VkImageAspectFlags aspects = 0;
|
if (scissor_state && needs_rp)
|
||||||
|
clear->scissor = *scissor_state;
|
||||||
if (buffers & PIPE_CLEAR_DEPTH)
|
if (buffers & PIPE_CLEAR_DEPTH)
|
||||||
aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
clear->zs.depth = depth;
|
||||||
if (buffers & PIPE_CLEAR_STENCIL)
|
if (buffers & PIPE_CLEAR_STENCIL)
|
||||||
aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
clear->zs.stencil = stencil;
|
||||||
clear_zs_no_rp(ctx, zink_resource(fb->zsbuf->texture), aspects,
|
clear->zs.bits |= (buffers & PIPE_CLEAR_DEPTHSTENCIL);
|
||||||
depth, stencil, fb->zsbuf->u.tex.level, fb->zsbuf->u.tex.first_layer,
|
|
||||||
fb->zsbuf->u.tex.last_layer - fb->zsbuf->u.tex.first_layer + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
colors_equal(union pipe_color_union *a, union pipe_color_union *b)
|
||||||
|
{
|
||||||
|
return a->ui[0] == b->ui[0] && a->ui[1] == b->ui[1] && a->ui[2] == b->ui[2] && a->ui[3] == b->ui[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zink_clear_framebuffer(struct zink_context *ctx, unsigned clear_buffers)
|
||||||
|
{
|
||||||
|
unsigned to_clear = 0;
|
||||||
|
struct pipe_framebuffer_state *fb_state = &ctx->fb_state;
|
||||||
|
while (clear_buffers) {
|
||||||
|
struct zink_framebuffer_clear *color_clear = NULL;
|
||||||
|
struct zink_framebuffer_clear *zs_clear = NULL;
|
||||||
|
unsigned num_clears = 0;
|
||||||
|
for (int i = 0; i < fb_state->nr_cbufs && clear_buffers >= PIPE_CLEAR_COLOR0; i++) {
|
||||||
|
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[i];
|
||||||
|
/* these need actual clear calls inside the rp */
|
||||||
|
if (!(clear_buffers & (PIPE_CLEAR_COLOR0 << i)))
|
||||||
|
continue;
|
||||||
|
if (color_clear) {
|
||||||
|
/* different number of clears -> do another clear */
|
||||||
|
//XXX: could potentially merge "some" of the clears into this one for a very, very small optimization
|
||||||
|
if (num_clears != zink_fb_clear_count(fb_clear))
|
||||||
|
goto out;
|
||||||
|
/* compare all the clears to determine if we can batch these buffers together */
|
||||||
|
for (int j = 0; j < num_clears; j++) {
|
||||||
|
struct zink_framebuffer_clear_data *a = zink_fb_clear_element(color_clear, j);
|
||||||
|
struct zink_framebuffer_clear_data *b = zink_fb_clear_element(fb_clear, j);
|
||||||
|
/* scissors don't match, fire this one off */
|
||||||
|
if (a->has_scissor != b->has_scissor || (a->has_scissor && !scissor_states_equal(&a->scissor, &b->scissor)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* colors don't match, fire this one off */
|
||||||
|
if (!colors_equal(&a->color.color, &b->color.color))
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
color_clear = fb_clear;
|
||||||
|
num_clears = zink_fb_clear_count(fb_clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_buffers &= ~(PIPE_CLEAR_COLOR0 << i);
|
||||||
|
to_clear |= (PIPE_CLEAR_COLOR0 << i);
|
||||||
|
}
|
||||||
|
if (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) {
|
||||||
|
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[PIPE_MAX_COLOR_BUFS];
|
||||||
|
if (color_clear) {
|
||||||
|
if (num_clears != zink_fb_clear_count(fb_clear))
|
||||||
|
goto out;
|
||||||
|
/* compare all the clears to determine if we can batch these buffers together */
|
||||||
|
for (int j = 0; j < zink_fb_clear_count(color_clear); j++) {
|
||||||
|
struct zink_framebuffer_clear_data *a = zink_fb_clear_element(color_clear, j);
|
||||||
|
struct zink_framebuffer_clear_data *b = zink_fb_clear_element(fb_clear, j);
|
||||||
|
/* scissors don't match, fire this one off */
|
||||||
|
if (a->has_scissor != b->has_scissor || (a->has_scissor && !scissor_states_equal(&a->scissor, &b->scissor)))
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zs_clear = fb_clear;
|
||||||
|
to_clear |= (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL);
|
||||||
|
clear_buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
if (to_clear) {
|
||||||
|
if (num_clears) {
|
||||||
|
for (int j = 0; j < num_clears; j++) {
|
||||||
|
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(color_clear, j);
|
||||||
|
struct zink_framebuffer_clear_data *zsclear = NULL;
|
||||||
|
if (zs_clear)
|
||||||
|
zsclear = zink_fb_clear_element(zs_clear, j);
|
||||||
|
zink_clear(&ctx->base, to_clear,
|
||||||
|
clear->has_scissor ? &clear->scissor : NULL,
|
||||||
|
&clear->color.color,
|
||||||
|
zsclear ? zsclear->zs.depth : 0,
|
||||||
|
zsclear ? zsclear->zs.stencil : 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int j = 0; j < zink_fb_clear_count(zs_clear); j++) {
|
||||||
|
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(zs_clear, j);
|
||||||
|
zink_clear(&ctx->base, to_clear,
|
||||||
|
clear->has_scissor ? &clear->scissor : NULL,
|
||||||
|
NULL,
|
||||||
|
clear->zs.depth,
|
||||||
|
clear->zs.stencil);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
to_clear = 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(ctx->fb_clears); i++)
|
||||||
|
zink_fb_clear_reset(&ctx->fb_clears[i]);
|
||||||
|
}
|
||||||
|
|
||||||
static struct pipe_surface *
|
static struct pipe_surface *
|
||||||
create_clear_surface(struct pipe_context *pctx, struct pipe_resource *pres, unsigned level, const struct pipe_box *box)
|
create_clear_surface(struct pipe_context *pctx, struct pipe_resource *pres, unsigned level, const struct pipe_box *box)
|
||||||
{
|
{
|
||||||
|
|
@ -318,3 +415,91 @@ zink_clear_texture(struct pipe_context *pctx,
|
||||||
}
|
}
|
||||||
pipe_surface_reference(&surf, NULL);
|
pipe_surface_reference(&surf, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
zink_fb_clear_needs_explicit(struct zink_framebuffer_clear *fb_clear)
|
||||||
|
{
|
||||||
|
if (zink_fb_clear_count(fb_clear) != 1)
|
||||||
|
return true;
|
||||||
|
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(fb_clear, 0);
|
||||||
|
return clear->has_scissor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zink_fb_clears_apply(struct zink_context *ctx, struct pipe_resource *pres)
|
||||||
|
{
|
||||||
|
if (zink_resource(pres)->aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
|
||||||
|
for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
|
||||||
|
if (ctx->fb_state.cbufs[i] && ctx->fb_state.cbufs[i]->texture == pres) {
|
||||||
|
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[i];
|
||||||
|
if (fb_clear->enabled) {
|
||||||
|
assert(!zink_curr_batch(ctx)->in_rp);
|
||||||
|
if (zink_fb_clear_needs_explicit(fb_clear) || !check_3d_layers(ctx->fb_state.cbufs[i]))
|
||||||
|
/* this will automatically trigger all the clears */
|
||||||
|
zink_batch_rp(ctx);
|
||||||
|
else {
|
||||||
|
struct pipe_surface *psurf = ctx->fb_state.cbufs[i];
|
||||||
|
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(fb_clear, 0);
|
||||||
|
union pipe_color_union color = clear->color.color;
|
||||||
|
if (clear->color.srgb) {
|
||||||
|
/* if SRGB mode is disabled for the fb with a backing srgb image then we have to
|
||||||
|
* convert this to srgb color
|
||||||
|
*/
|
||||||
|
color.f[0] = util_format_srgb_to_linear_float(clear->color.color.f[0]);
|
||||||
|
color.f[1] = util_format_srgb_to_linear_float(clear->color.color.f[1]);
|
||||||
|
color.f[2] = util_format_srgb_to_linear_float(clear->color.color.f[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_color_no_rp(ctx, zink_resource(pres), &color,
|
||||||
|
psurf->u.tex.level, psurf->u.tex.first_layer,
|
||||||
|
psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1);
|
||||||
|
}
|
||||||
|
zink_fb_clear_reset(&ctx->fb_clears[i]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[PIPE_MAX_COLOR_BUFS];
|
||||||
|
if (fb_clear->enabled && ctx->fb_state.zsbuf && ctx->fb_state.zsbuf->texture == pres) {
|
||||||
|
assert(!zink_curr_batch(ctx)->in_rp);
|
||||||
|
if (zink_fb_clear_needs_explicit(fb_clear) || !check_3d_layers(ctx->fb_state.zsbuf))
|
||||||
|
/* this will automatically trigger all the clears */
|
||||||
|
zink_batch_rp(ctx);
|
||||||
|
else {
|
||||||
|
struct pipe_surface *psurf = ctx->fb_state.zsbuf;
|
||||||
|
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(fb_clear, 0);
|
||||||
|
VkImageAspectFlags aspects = 0;
|
||||||
|
if (clear->zs.bits & PIPE_CLEAR_DEPTH)
|
||||||
|
aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||||
|
if (clear->zs.bits & PIPE_CLEAR_STENCIL)
|
||||||
|
aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||||
|
clear_zs_no_rp(ctx, zink_resource(pres), aspects, clear->zs.depth, clear->zs.stencil,
|
||||||
|
psurf->u.tex.level, psurf->u.tex.first_layer,
|
||||||
|
psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1);
|
||||||
|
zink_fb_clear_reset(fb_clear);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zink_fb_clears_discard(struct zink_context *ctx, struct pipe_resource *pres)
|
||||||
|
{
|
||||||
|
if (zink_resource(pres)->aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
|
||||||
|
for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
|
||||||
|
if (ctx->fb_state.cbufs[i] && ctx->fb_state.cbufs[i]->texture == pres) {
|
||||||
|
if (ctx->fb_clears[i].enabled) {
|
||||||
|
zink_fb_clear_reset(&ctx->fb_clears[i]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ctx->fb_clears[PIPE_MAX_COLOR_BUFS].enabled && ctx->fb_state.zsbuf && ctx->fb_state.zsbuf->texture == pres) {
|
||||||
|
int i = PIPE_MAX_COLOR_BUFS;
|
||||||
|
zink_fb_clear_reset(&ctx->fb_clears[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
#include "indices/u_primconvert.h"
|
#include "indices/u_primconvert.h"
|
||||||
#include "util/u_blitter.h"
|
#include "util/u_blitter.h"
|
||||||
#include "util/u_debug.h"
|
#include "util/u_debug.h"
|
||||||
|
#include "util/format_srgb.h"
|
||||||
#include "util/format/u_format.h"
|
#include "util/format/u_format.h"
|
||||||
#include "util/u_framebuffer.h"
|
#include "util/u_framebuffer.h"
|
||||||
#include "util/u_helpers.h"
|
#include "util/u_helpers.h"
|
||||||
|
|
@ -731,6 +732,7 @@ get_render_pass(struct zink_context *ctx)
|
||||||
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
||||||
const struct pipe_framebuffer_state *fb = &ctx->fb_state;
|
const struct pipe_framebuffer_state *fb = &ctx->fb_state;
|
||||||
struct zink_render_pass_state state = { 0 };
|
struct zink_render_pass_state state = { 0 };
|
||||||
|
uint32_t clears = 0;
|
||||||
|
|
||||||
for (int i = 0; i < fb->nr_cbufs; i++) {
|
for (int i = 0; i < fb->nr_cbufs; i++) {
|
||||||
struct pipe_surface *surf = fb->cbufs[i];
|
struct pipe_surface *surf = fb->cbufs[i];
|
||||||
|
|
@ -738,6 +740,8 @@ get_render_pass(struct zink_context *ctx)
|
||||||
state.rts[i].format = zink_get_format(screen, surf->format);
|
state.rts[i].format = zink_get_format(screen, surf->format);
|
||||||
state.rts[i].samples = surf->texture->nr_samples > 0 ? surf->texture->nr_samples :
|
state.rts[i].samples = surf->texture->nr_samples > 0 ? surf->texture->nr_samples :
|
||||||
VK_SAMPLE_COUNT_1_BIT;
|
VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
state.rts[i].clear_color = ctx->fb_clears[i].enabled && !zink_fb_clear_needs_explicit(&ctx->fb_clears[i]);
|
||||||
|
clears |= !!state.rts[i].clear_color ? BITFIELD_BIT(i) : 0;
|
||||||
} else {
|
} else {
|
||||||
state.rts[i].format = VK_FORMAT_R8_UINT;
|
state.rts[i].format = VK_FORMAT_R8_UINT;
|
||||||
state.rts[i].samples = MAX2(fb->samples, 1);
|
state.rts[i].samples = MAX2(fb->samples, 1);
|
||||||
|
|
@ -748,11 +752,22 @@ get_render_pass(struct zink_context *ctx)
|
||||||
|
|
||||||
if (fb->zsbuf) {
|
if (fb->zsbuf) {
|
||||||
struct zink_resource *zsbuf = zink_resource(fb->zsbuf->texture);
|
struct zink_resource *zsbuf = zink_resource(fb->zsbuf->texture);
|
||||||
|
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[PIPE_MAX_COLOR_BUFS];
|
||||||
state.rts[fb->nr_cbufs].format = zsbuf->format;
|
state.rts[fb->nr_cbufs].format = zsbuf->format;
|
||||||
state.rts[fb->nr_cbufs].samples = zsbuf->base.nr_samples > 0 ? zsbuf->base.nr_samples : VK_SAMPLE_COUNT_1_BIT;
|
state.rts[fb->nr_cbufs].samples = zsbuf->base.nr_samples > 0 ? zsbuf->base.nr_samples : VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
state.rts[fb->nr_cbufs].clear_color = fb_clear->enabled &&
|
||||||
|
!zink_fb_clear_needs_explicit(fb_clear) &&
|
||||||
|
(zink_fb_clear_element(fb_clear, 0)->zs.bits & PIPE_CLEAR_DEPTH);
|
||||||
|
state.rts[fb->nr_cbufs].clear_stencil = fb_clear->enabled &&
|
||||||
|
!zink_fb_clear_needs_explicit(fb_clear) &&
|
||||||
|
(zink_fb_clear_element(fb_clear, 0)->zs.bits & PIPE_CLEAR_STENCIL);
|
||||||
|
clears |= state.rts[fb->nr_cbufs].clear_color || state.rts[fb->nr_cbufs].clear_stencil ? BITFIELD_BIT(fb->nr_cbufs) : 0;;
|
||||||
state.num_rts++;
|
state.num_rts++;
|
||||||
}
|
}
|
||||||
state.have_zsbuf = fb->zsbuf != NULL;
|
state.have_zsbuf = fb->zsbuf != NULL;
|
||||||
|
#ifndef NDEBUG
|
||||||
|
state.clears = clears;
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32_t hash = hash_render_pass_state(&state);
|
uint32_t hash = hash_render_pass_state(&state);
|
||||||
struct hash_entry *entry = _mesa_hash_table_search_pre_hashed(ctx->render_pass_cache, hash,
|
struct hash_entry *entry = _mesa_hash_table_search_pre_hashed(ctx->render_pass_cache, hash,
|
||||||
|
|
@ -845,8 +860,51 @@ zink_begin_render_pass(struct zink_context *ctx, struct zink_batch *batch)
|
||||||
rpbi.renderArea.offset.y = 0;
|
rpbi.renderArea.offset.y = 0;
|
||||||
rpbi.renderArea.extent.width = fb_state->width;
|
rpbi.renderArea.extent.width = fb_state->width;
|
||||||
rpbi.renderArea.extent.height = fb_state->height;
|
rpbi.renderArea.extent.height = fb_state->height;
|
||||||
rpbi.clearValueCount = 0;
|
|
||||||
rpbi.pClearValues = NULL;
|
VkClearValue clears[PIPE_MAX_COLOR_BUFS + 1] = {};
|
||||||
|
unsigned clear_buffers = 0;
|
||||||
|
uint32_t clear_validate = 0;
|
||||||
|
for (int i = 0; i < fb_state->nr_cbufs; i++) {
|
||||||
|
/* these are no-ops */
|
||||||
|
if (!fb_state->cbufs[i] || !ctx->fb_clears[i].enabled)
|
||||||
|
continue;
|
||||||
|
/* these need actual clear calls inside the rp */
|
||||||
|
if (zink_fb_clear_needs_explicit(&ctx->fb_clears[i])) {
|
||||||
|
clear_buffers |= (PIPE_CLEAR_COLOR0 << i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* we now know there's only one clear */
|
||||||
|
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(&ctx->fb_clears[i], 0);
|
||||||
|
if (clear->color.srgb) {
|
||||||
|
clears[i].color.float32[0] = util_format_srgb_to_linear_float(clear->color.color.f[0]);
|
||||||
|
clears[i].color.float32[1] = util_format_srgb_to_linear_float(clear->color.color.f[1]);
|
||||||
|
clears[i].color.float32[2] = util_format_srgb_to_linear_float(clear->color.color.f[2]);
|
||||||
|
} else {
|
||||||
|
clears[i].color.float32[0] = clear->color.color.f[0];
|
||||||
|
clears[i].color.float32[1] = clear->color.color.f[1];
|
||||||
|
clears[i].color.float32[2] = clear->color.color.f[2];
|
||||||
|
}
|
||||||
|
clears[i].color.float32[3] = clear->color.color.f[3];
|
||||||
|
rpbi.clearValueCount = i + 1;
|
||||||
|
clear_validate |= BITFIELD_BIT(i);
|
||||||
|
assert(ctx->framebuffer->rp->state.clears);
|
||||||
|
}
|
||||||
|
if (fb_state->zsbuf && ctx->fb_clears[PIPE_MAX_COLOR_BUFS].enabled) {
|
||||||
|
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[PIPE_MAX_COLOR_BUFS];
|
||||||
|
if (zink_fb_clear_needs_explicit(fb_clear)) {
|
||||||
|
for (int j = 0; j < zink_fb_clear_count(fb_clear); j++)
|
||||||
|
clear_buffers |= zink_fb_clear_element(fb_clear, j)->zs.bits;
|
||||||
|
} else {
|
||||||
|
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(fb_clear, 0);
|
||||||
|
clears[fb_state->nr_cbufs].depthStencil.depth = clear->zs.depth;
|
||||||
|
clears[fb_state->nr_cbufs].depthStencil.stencil = clear->zs.stencil;
|
||||||
|
rpbi.clearValueCount = fb_state->nr_cbufs + 1;
|
||||||
|
clear_validate |= BITFIELD_BIT(fb_state->nr_cbufs);
|
||||||
|
assert(ctx->framebuffer->rp->state.clears);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(clear_validate == ctx->framebuffer->rp->state.clears);
|
||||||
|
rpbi.pClearValues = &clears[0];
|
||||||
rpbi.framebuffer = ctx->framebuffer->fb;
|
rpbi.framebuffer = ctx->framebuffer->fb;
|
||||||
|
|
||||||
assert(ctx->gfx_pipeline_state.render_pass && ctx->framebuffer);
|
assert(ctx->gfx_pipeline_state.render_pass && ctx->framebuffer);
|
||||||
|
|
@ -859,6 +917,8 @@ zink_begin_render_pass(struct zink_context *ctx, struct zink_batch *batch)
|
||||||
|
|
||||||
vkCmdBeginRenderPass(batch->cmdbuf, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(batch->cmdbuf, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
batch->in_rp = true;
|
batch->in_rp = true;
|
||||||
|
|
||||||
|
zink_clear_framebuffer(ctx, clear_buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -916,6 +976,22 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
|
||||||
{
|
{
|
||||||
struct zink_context *ctx = zink_context(pctx);
|
struct zink_context *ctx = zink_context(pctx);
|
||||||
|
|
||||||
|
for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
|
||||||
|
struct pipe_surface *surf = ctx->fb_state.cbufs[i];
|
||||||
|
if (surf &&
|
||||||
|
(!state->cbufs[i] || i >= state->nr_cbufs ||
|
||||||
|
surf->texture != state->cbufs[i]->texture ||
|
||||||
|
surf->format != state->cbufs[i]->format ||
|
||||||
|
memcmp(&surf->u, &state->cbufs[i]->u, sizeof(union pipe_surface_desc))))
|
||||||
|
zink_fb_clears_apply(ctx, surf->texture);
|
||||||
|
}
|
||||||
|
if (ctx->fb_state.zsbuf) {
|
||||||
|
struct pipe_surface *surf = ctx->fb_state.zsbuf;
|
||||||
|
if (!state->zsbuf || surf->texture != state->zsbuf->texture ||
|
||||||
|
memcmp(&surf->u, &state->zsbuf->u, sizeof(union pipe_surface_desc)))
|
||||||
|
zink_fb_clears_apply(ctx, ctx->fb_state.zsbuf->texture);
|
||||||
|
}
|
||||||
|
|
||||||
util_copy_framebuffer_state(&ctx->fb_state, state);
|
util_copy_framebuffer_state(&ctx->fb_state, state);
|
||||||
|
|
||||||
uint8_t rast_samples = util_framebuffer_get_num_samples(state);
|
uint8_t rast_samples = util_framebuffer_get_num_samples(state);
|
||||||
|
|
@ -1515,6 +1591,9 @@ zink_resource_copy_region(struct pipe_context *pctx,
|
||||||
} else
|
} else
|
||||||
unreachable("planar formats not yet handled");
|
unreachable("planar formats not yet handled");
|
||||||
|
|
||||||
|
zink_fb_clears_apply(ctx, pdst);
|
||||||
|
zink_fb_clears_apply(ctx, psrc);
|
||||||
|
|
||||||
region.srcSubresource.aspectMask = src->aspect;
|
region.srcSubresource.aspectMask = src->aspect;
|
||||||
region.srcSubresource.mipLevel = src_level;
|
region.srcSubresource.mipLevel = src_level;
|
||||||
region.srcSubresource.layerCount = 1;
|
region.srcSubresource.layerCount = 1;
|
||||||
|
|
@ -1767,6 +1846,8 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
||||||
|
|
||||||
ctx->base.stream_uploader = u_upload_create_default(&ctx->base);
|
ctx->base.stream_uploader = u_upload_create_default(&ctx->base);
|
||||||
ctx->base.const_uploader = ctx->base.stream_uploader;
|
ctx->base.const_uploader = ctx->base.stream_uploader;
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(ctx->fb_clears); i++)
|
||||||
|
util_dynarray_init(&ctx->fb_clears[i].clears, ctx);
|
||||||
|
|
||||||
int prim_hwsupport = 1 << PIPE_PRIM_POINTS |
|
int prim_hwsupport = 1 << PIPE_PRIM_POINTS |
|
||||||
1 << PIPE_PRIM_LINES |
|
1 << PIPE_PRIM_LINES |
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,27 @@ struct zink_viewport_state {
|
||||||
uint8_t num_viewports;
|
uint8_t num_viewports;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct zink_framebuffer_clear_data {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
union pipe_color_union color;
|
||||||
|
bool srgb;
|
||||||
|
} color;
|
||||||
|
struct {
|
||||||
|
float depth;
|
||||||
|
unsigned stencil;
|
||||||
|
uint8_t bits : 2; // PIPE_CLEAR_DEPTH, PIPE_CLEAR_STENCIL
|
||||||
|
} zs;
|
||||||
|
};
|
||||||
|
struct pipe_scissor_state scissor;
|
||||||
|
bool has_scissor;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct zink_framebuffer_clear {
|
||||||
|
struct util_dynarray clears;
|
||||||
|
bool enabled;
|
||||||
|
};
|
||||||
|
|
||||||
#define ZINK_SHADER_COUNT (PIPE_SHADER_TYPES - 1)
|
#define ZINK_SHADER_COUNT (PIPE_SHADER_TYPES - 1)
|
||||||
#define ZINK_NUM_GFX_BATCHES 4
|
#define ZINK_NUM_GFX_BATCHES 4
|
||||||
#define ZINK_COMPUTE_BATCH_ID ZINK_NUM_GFX_BATCHES
|
#define ZINK_COMPUTE_BATCH_ID ZINK_NUM_GFX_BATCHES
|
||||||
|
|
@ -145,6 +166,7 @@ struct zink_context {
|
||||||
struct primconvert_context *primconvert;
|
struct primconvert_context *primconvert;
|
||||||
|
|
||||||
struct zink_framebuffer *framebuffer;
|
struct zink_framebuffer *framebuffer;
|
||||||
|
struct zink_framebuffer_clear fb_clears[PIPE_MAX_COLOR_BUFS + 1];
|
||||||
|
|
||||||
struct pipe_vertex_buffer buffers[PIPE_MAX_ATTRIBS];
|
struct pipe_vertex_buffer buffers[PIPE_MAX_ATTRIBS];
|
||||||
uint32_t buffers_enabled_mask;
|
uint32_t buffers_enabled_mask;
|
||||||
|
|
@ -270,6 +292,37 @@ zink_clear_texture(struct pipe_context *ctx,
|
||||||
const struct pipe_box *box,
|
const struct pipe_box *box,
|
||||||
const void *data);
|
const void *data);
|
||||||
|
|
||||||
|
bool
|
||||||
|
zink_fb_clear_needs_explicit(struct zink_framebuffer_clear *fb_clear);
|
||||||
|
|
||||||
|
void
|
||||||
|
zink_clear_framebuffer(struct zink_context *ctx, unsigned clear_buffers);
|
||||||
|
|
||||||
|
static inline struct zink_framebuffer_clear_data *
|
||||||
|
zink_fb_clear_element(struct zink_framebuffer_clear *fb_clear, int idx)
|
||||||
|
{
|
||||||
|
return util_dynarray_element(&fb_clear->clears, struct zink_framebuffer_clear_data, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
zink_fb_clear_count(struct zink_framebuffer_clear *fb_clear)
|
||||||
|
{
|
||||||
|
return util_dynarray_num_elements(&fb_clear->clears, struct zink_framebuffer_clear_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
zink_fb_clear_reset(struct zink_framebuffer_clear *fb_clear)
|
||||||
|
{
|
||||||
|
util_dynarray_fini(&fb_clear->clears);
|
||||||
|
fb_clear->enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zink_fb_clears_apply(struct zink_context *ctx, struct pipe_resource *pres);
|
||||||
|
|
||||||
|
void
|
||||||
|
zink_fb_clears_discard(struct zink_context *ctx, struct pipe_resource *pres);
|
||||||
|
|
||||||
void
|
void
|
||||||
zink_draw_vbo(struct pipe_context *pctx,
|
zink_draw_vbo(struct pipe_context *pctx,
|
||||||
const struct pipe_draw_info *dinfo,
|
const struct pipe_draw_info *dinfo,
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ create_render_pass(VkDevice dev, struct zink_render_pass_state *state)
|
||||||
attachments[i].flags = 0;
|
attachments[i].flags = 0;
|
||||||
attachments[i].format = rt->format;
|
attachments[i].format = rt->format;
|
||||||
attachments[i].samples = rt->samples;
|
attachments[i].samples = rt->samples;
|
||||||
attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
attachments[i].loadOp = rt->clear_color ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
attachments[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
attachments[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
attachments[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
attachments[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
|
@ -56,9 +56,9 @@ create_render_pass(VkDevice dev, struct zink_render_pass_state *state)
|
||||||
attachments[num_attachments].flags = 0;
|
attachments[num_attachments].flags = 0;
|
||||||
attachments[num_attachments].format = rt->format;
|
attachments[num_attachments].format = rt->format;
|
||||||
attachments[num_attachments].samples = rt->samples;
|
attachments[num_attachments].samples = rt->samples;
|
||||||
attachments[num_attachments].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
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].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
attachments[num_attachments].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
attachments[num_attachments].stencilLoadOp = rt->clear_stencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
attachments[num_attachments].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
attachments[num_attachments].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
attachments[num_attachments].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
attachments[num_attachments].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
attachments[num_attachments].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
attachments[num_attachments].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ struct zink_screen;
|
||||||
struct zink_rt_attrib {
|
struct zink_rt_attrib {
|
||||||
VkFormat format;
|
VkFormat format;
|
||||||
VkSampleCountFlagBits samples;
|
VkSampleCountFlagBits samples;
|
||||||
|
bool clear_color;
|
||||||
|
bool clear_stencil;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zink_render_pass_state {
|
struct zink_render_pass_state {
|
||||||
|
|
@ -41,6 +43,9 @@ struct zink_render_pass_state {
|
||||||
uint8_t have_zsbuf : 1;
|
uint8_t have_zsbuf : 1;
|
||||||
struct zink_rt_attrib rts[PIPE_MAX_COLOR_BUFS + 1];
|
struct zink_rt_attrib rts[PIPE_MAX_COLOR_BUFS + 1];
|
||||||
unsigned num_rts;
|
unsigned num_rts;
|
||||||
|
#ifndef NDEBUG
|
||||||
|
uint32_t clears; //for extra verification
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zink_render_pass {
|
struct zink_render_pass {
|
||||||
|
|
|
||||||
|
|
@ -619,6 +619,7 @@ zink_transfer_map(struct pipe_context *pctx,
|
||||||
if (usage & PIPE_MAP_WRITE)
|
if (usage & PIPE_MAP_WRITE)
|
||||||
util_range_add(&res->base, &res->valid_buffer_range, box->x, box->x + box->width);
|
util_range_add(&res->base, &res->valid_buffer_range, box->x, box->x + box->width);
|
||||||
} else {
|
} else {
|
||||||
|
zink_fb_clears_apply(ctx, pres);
|
||||||
if (res->optimal_tiling || !res->host_visible) {
|
if (res->optimal_tiling || !res->host_visible) {
|
||||||
enum pipe_format format = pres->format;
|
enum pipe_format format = pres->format;
|
||||||
if (usage & PIPE_MAP_DEPTH_ONLY)
|
if (usage & PIPE_MAP_DEPTH_ONLY)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue