2
* Copyright 2018 Collabora Ltd.
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* on the rights to use, copy, modify, merge, publish, distribute, sub
8
* license, and/or sell copies of the Software, and to permit persons to whom
9
* the Software is furnished to do so, subject to the following conditions:
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21
* USE OR OTHER DEALINGS IN THE SOFTWARE.
24
#include "zink_context.h"
25
#include "zink_kopper.h"
26
#include "zink_query.h"
27
#include "zink_resource.h"
28
#include "zink_screen.h"
30
#include "util/u_blitter.h"
31
#include "util/u_dynarray.h"
32
#include "util/format/u_format.h"
33
#include "util/format_srgb.h"
34
#include "util/u_framebuffer.h"
35
#include "util/u_inlines.h"
36
#include "util/u_rect.h"
37
#include "util/u_surface.h"
38
#include "util/u_helpers.h"
41
check_3d_layers(struct pipe_surface *psurf)
43
if (psurf->texture->target != PIPE_TEXTURE_3D)
46
* though the vk spec doesn't seem to explicitly address this, currently drivers
47
* are claiming that all 3D images have a single "3D" layer regardless of layercount,
48
* so we can never clear them if we aren't trying to clear only layer 0
50
if (psurf->u.tex.first_layer)
53
if (psurf->u.tex.last_layer - psurf->u.tex.first_layer > 0)
59
scissor_states_equal(const struct pipe_scissor_state *a, const struct pipe_scissor_state *b)
61
return a->minx == b->minx && a->miny == b->miny && a->maxx == b->maxx && a->maxy == b->maxy;
65
clear_in_rp(struct pipe_context *pctx,
67
const struct pipe_scissor_state *scissor_state,
68
const union pipe_color_union *pcolor,
69
double depth, unsigned stencil)
71
struct zink_context *ctx = zink_context(pctx);
72
struct pipe_framebuffer_state *fb = &ctx->fb_state;
74
VkClearAttachment attachments[1 + PIPE_MAX_COLOR_BUFS];
75
int num_attachments = 0;
77
if (buffers & PIPE_CLEAR_COLOR) {
78
VkClearColorValue color;
79
color.uint32[0] = pcolor->ui[0];
80
color.uint32[1] = pcolor->ui[1];
81
color.uint32[2] = pcolor->ui[2];
82
color.uint32[3] = pcolor->ui[3];
84
for (unsigned i = 0; i < fb->nr_cbufs; i++) {
85
if (!(buffers & (PIPE_CLEAR_COLOR0 << i)) || !fb->cbufs[i])
88
attachments[num_attachments].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
89
attachments[num_attachments].colorAttachment = i;
90
attachments[num_attachments].clearValue.color = color;
95
if (buffers & PIPE_CLEAR_DEPTHSTENCIL && fb->zsbuf) {
96
VkImageAspectFlags aspect = 0;
97
if (buffers & PIPE_CLEAR_DEPTH)
98
aspect |= VK_IMAGE_ASPECT_DEPTH_BIT;
99
if (buffers & PIPE_CLEAR_STENCIL)
100
aspect |= VK_IMAGE_ASPECT_STENCIL_BIT;
102
attachments[num_attachments].aspectMask = aspect;
103
attachments[num_attachments].clearValue.depthStencil.depth = depth;
104
attachments[num_attachments].clearValue.depthStencil.stencil = stencil;
108
VkClearRect cr = {0};
110
cr.rect.offset.x = scissor_state->minx;
111
cr.rect.offset.y = scissor_state->miny;
112
cr.rect.extent.width = MIN2(fb->width, scissor_state->maxx - scissor_state->minx);
113
cr.rect.extent.height = MIN2(fb->height, scissor_state->maxy - scissor_state->miny);
115
cr.rect.extent.width = fb->width;
116
cr.rect.extent.height = fb->height;
118
cr.baseArrayLayer = 0;
119
cr.layerCount = util_framebuffer_get_num_layers(fb);
120
struct zink_batch *batch = &ctx->batch;
122
VKCTX(CmdClearAttachments)(batch->state->cmdbuf, num_attachments, attachments, 1, &cr);
124
Rendering within a subpass containing a feedback loop creates a data race, except in the following
126
• If a memory dependency is inserted between when the attachment is written and when it is
127
subsequently read by later fragments. Pipeline barriers expressing a subpass self-dependency
128
are the only way to achieve this, and one must be inserted every time a fragment will read
129
values at a particular sample (x, y, layer, sample) coordinate, if those values have been written
130
since the most recent pipeline barrier
132
VK 1.3.211, Chapter 8: Render Pass
134
if (ctx->fbfetch_outputs)
135
ctx->base.texture_barrier(&ctx->base, PIPE_TEXTURE_BARRIER_FRAMEBUFFER);
139
clear_color_no_rp(struct zink_context *ctx, struct zink_resource *res, const union pipe_color_union *pcolor, unsigned level, unsigned layer, unsigned layerCount)
141
struct zink_batch *batch = &ctx->batch;
142
zink_batch_no_rp(ctx);
143
VkImageSubresourceRange range = {0};
144
range.baseMipLevel = level;
145
range.levelCount = 1;
146
range.baseArrayLayer = layer;
147
range.layerCount = layerCount;
148
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
150
VkClearColorValue color;
151
color.uint32[0] = pcolor->ui[0];
152
color.uint32[1] = pcolor->ui[1];
153
color.uint32[2] = pcolor->ui[2];
154
color.uint32[3] = pcolor->ui[3];
156
if (zink_is_swapchain(res)) {
157
if (!zink_kopper_acquire(ctx, res, UINT64_MAX))
160
if (zink_resource_image_needs_barrier(res, VK_IMAGE_LAYOUT_GENERAL, 0, 0) &&
161
zink_resource_image_needs_barrier(res, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0))
162
zink_resource_image_barrier(ctx, res, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0);
163
zink_batch_reference_resource_rw(batch, res, true);
164
VKCTX(CmdClearColorImage)(batch->state->cmdbuf, res->obj->image, res->layout, &color, 1, &range);
168
clear_zs_no_rp(struct zink_context *ctx, struct zink_resource *res, VkImageAspectFlags aspects, double depth, unsigned stencil, unsigned level, unsigned layer, unsigned layerCount)
170
struct zink_batch *batch = &ctx->batch;
171
zink_batch_no_rp(ctx);
172
VkImageSubresourceRange range = {0};
173
range.baseMipLevel = level;
174
range.levelCount = 1;
175
range.baseArrayLayer = layer;
176
range.layerCount = layerCount;
177
range.aspectMask = aspects;
179
VkClearDepthStencilValue zs_value = {depth, stencil};
181
if (zink_resource_image_needs_barrier(res, VK_IMAGE_LAYOUT_GENERAL, 0, 0) &&
182
zink_resource_image_needs_barrier(res, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0))
183
zink_resource_image_barrier(ctx, res, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0);
184
zink_batch_reference_resource_rw(batch, res, true);
185
VKCTX(CmdClearDepthStencilImage)(batch->state->cmdbuf, res->obj->image, res->layout, &zs_value, 1, &range);
190
static struct zink_framebuffer_clear_data *
191
get_clear_data(struct zink_context *ctx, struct zink_framebuffer_clear *fb_clear, const struct pipe_scissor_state *scissor_state)
193
struct zink_framebuffer_clear_data *clear = NULL;
194
unsigned num_clears = zink_fb_clear_count(fb_clear);
196
struct zink_framebuffer_clear_data *last_clear = zink_fb_clear_element(fb_clear, num_clears - 1);
197
/* if we're completely overwriting the previous clear, merge this into the previous clear */
198
if (!scissor_state || (last_clear->has_scissor && scissor_states_equal(&last_clear->scissor, scissor_state)))
202
struct zink_framebuffer_clear_data cd = {0};
203
util_dynarray_append(&fb_clear->clears, struct zink_framebuffer_clear_data, cd);
204
clear = zink_fb_clear_element(fb_clear, zink_fb_clear_count(fb_clear) - 1);
210
zink_clear(struct pipe_context *pctx,
212
const struct pipe_scissor_state *scissor_state,
213
const union pipe_color_union *pcolor,
214
double depth, unsigned stencil)
216
struct zink_context *ctx = zink_context(pctx);
217
struct pipe_framebuffer_state *fb = &ctx->fb_state;
218
struct zink_batch *batch = &ctx->batch;
219
bool needs_rp = false;
221
if (unlikely(!zink_screen(pctx->screen)->info.have_EXT_conditional_rendering && !zink_check_conditional_render(ctx)))
225
struct u_rect scissor = {scissor_state->minx, scissor_state->maxx, scissor_state->miny, scissor_state->maxy};
226
needs_rp = !zink_blit_region_fills(scissor, fb->width, fb->height);
231
clear_in_rp(pctx, buffers, scissor_state, pcolor, depth, stencil);
235
if (buffers & PIPE_CLEAR_COLOR) {
236
for (unsigned i = 0; i < fb->nr_cbufs; i++) {
237
if ((buffers & (PIPE_CLEAR_COLOR0 << i)) && fb->cbufs[i]) {
238
struct pipe_surface *psurf = fb->cbufs[i];
239
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[i];
240
struct zink_framebuffer_clear_data *clear = get_clear_data(ctx, fb_clear, needs_rp ? scissor_state : NULL);
242
ctx->clears_enabled |= PIPE_CLEAR_COLOR0 << i;
243
clear->conditional = ctx->render_condition_active;
244
clear->has_scissor = needs_rp;
245
if (scissor_state && needs_rp)
246
clear->scissor = *scissor_state;
247
clear->color.color = *pcolor;
248
clear->color.srgb = psurf->format != psurf->texture->format &&
249
!util_format_is_srgb(psurf->format) && util_format_is_srgb(psurf->texture->format);
250
if (zink_fb_clear_first_needs_explicit(fb_clear))
251
ctx->rp_clears_enabled &= ~(PIPE_CLEAR_COLOR0 << i);
253
ctx->rp_clears_enabled |= PIPE_CLEAR_COLOR0 << i;
258
if (buffers & PIPE_CLEAR_DEPTHSTENCIL && fb->zsbuf) {
259
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[PIPE_MAX_COLOR_BUFS];
260
struct zink_framebuffer_clear_data *clear = get_clear_data(ctx, fb_clear, needs_rp ? scissor_state : NULL);
261
ctx->clears_enabled |= PIPE_CLEAR_DEPTHSTENCIL;
262
clear->conditional = ctx->render_condition_active;
263
clear->has_scissor = needs_rp;
264
if (scissor_state && needs_rp)
265
clear->scissor = *scissor_state;
266
if (buffers & PIPE_CLEAR_DEPTH)
267
clear->zs.depth = depth;
268
if (buffers & PIPE_CLEAR_STENCIL)
269
clear->zs.stencil = stencil;
270
clear->zs.bits |= (buffers & PIPE_CLEAR_DEPTHSTENCIL);
271
if (zink_fb_clear_first_needs_explicit(fb_clear))
272
ctx->rp_clears_enabled &= ~PIPE_CLEAR_DEPTHSTENCIL;
274
ctx->rp_clears_enabled |= (buffers & PIPE_CLEAR_DEPTHSTENCIL);
279
colors_equal(union pipe_color_union *a, union pipe_color_union *b)
281
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];
285
zink_clear_framebuffer(struct zink_context *ctx, unsigned clear_buffers)
287
unsigned to_clear = 0;
288
struct pipe_framebuffer_state *fb_state = &ctx->fb_state;
290
assert(!(clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) || zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS));
291
for (int i = 0; i < fb_state->nr_cbufs && clear_buffers >= PIPE_CLEAR_COLOR0; i++) {
292
assert(!(clear_buffers & (PIPE_CLEAR_COLOR0 << i)) || zink_fb_clear_enabled(ctx, i));
295
while (clear_buffers) {
296
struct zink_framebuffer_clear *color_clear = NULL;
297
struct zink_framebuffer_clear *zs_clear = NULL;
298
unsigned num_clears = 0;
299
for (int i = 0; i < fb_state->nr_cbufs && clear_buffers >= PIPE_CLEAR_COLOR0; i++) {
300
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[i];
301
/* these need actual clear calls inside the rp */
302
if (!(clear_buffers & (PIPE_CLEAR_COLOR0 << i)))
305
/* different number of clears -> do another clear */
306
//XXX: could potentially merge "some" of the clears into this one for a very, very small optimization
307
if (num_clears != zink_fb_clear_count(fb_clear))
309
/* compare all the clears to determine if we can batch these buffers together */
310
for (int j = !zink_fb_clear_first_needs_explicit(fb_clear); j < num_clears; j++) {
311
struct zink_framebuffer_clear_data *a = zink_fb_clear_element(color_clear, j);
312
struct zink_framebuffer_clear_data *b = zink_fb_clear_element(fb_clear, j);
313
/* scissors don't match, fire this one off */
314
if (a->has_scissor != b->has_scissor || (a->has_scissor && !scissor_states_equal(&a->scissor, &b->scissor)))
317
/* colors don't match, fire this one off */
318
if (!colors_equal(&a->color.color, &b->color.color))
322
color_clear = fb_clear;
323
num_clears = zink_fb_clear_count(fb_clear);
326
clear_buffers &= ~(PIPE_CLEAR_COLOR0 << i);
327
to_clear |= (PIPE_CLEAR_COLOR0 << i);
329
clear_buffers &= ~PIPE_CLEAR_COLOR;
330
if (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) {
331
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[PIPE_MAX_COLOR_BUFS];
333
if (num_clears != zink_fb_clear_count(fb_clear))
335
/* compare all the clears to determine if we can batch these buffers together */
336
for (int j = !zink_fb_clear_first_needs_explicit(fb_clear); j < zink_fb_clear_count(color_clear); j++) {
337
struct zink_framebuffer_clear_data *a = zink_fb_clear_element(color_clear, j);
338
struct zink_framebuffer_clear_data *b = zink_fb_clear_element(fb_clear, j);
339
/* scissors don't match, fire this one off */
340
if (a->has_scissor != b->has_scissor || (a->has_scissor && !scissor_states_equal(&a->scissor, &b->scissor)))
345
to_clear |= (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL);
346
clear_buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
351
for (int j = !zink_fb_clear_first_needs_explicit(color_clear); j < num_clears; j++) {
352
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(color_clear, j);
353
struct zink_framebuffer_clear_data *zsclear = NULL;
354
/* zs bits are both set here if those aspects should be cleared at some point */
355
unsigned clear_bits = to_clear & ~PIPE_CLEAR_DEPTHSTENCIL;
357
zsclear = zink_fb_clear_element(zs_clear, j);
358
clear_bits |= zsclear->zs.bits;
360
zink_clear(&ctx->base, clear_bits,
361
clear->has_scissor ? &clear->scissor : NULL,
363
zsclear ? zsclear->zs.depth : 0,
364
zsclear ? zsclear->zs.stencil : 0);
367
for (int j = !zink_fb_clear_first_needs_explicit(zs_clear); j < zink_fb_clear_count(zs_clear); j++) {
368
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(zs_clear, j);
369
zink_clear(&ctx->base, clear->zs.bits,
370
clear->has_scissor ? &clear->scissor : NULL,
379
for (int i = 0; i < ARRAY_SIZE(ctx->fb_clears); i++)
380
zink_fb_clear_reset(ctx, i);
383
static struct pipe_surface *
384
create_clear_surface(struct pipe_context *pctx, struct pipe_resource *pres, unsigned level, const struct pipe_box *box)
386
struct pipe_surface tmpl = {{0}};
388
tmpl.format = pres->format;
389
tmpl.u.tex.first_layer = box->z;
390
tmpl.u.tex.last_layer = box->z + box->depth - 1;
391
tmpl.u.tex.level = level;
392
return pctx->create_surface(pctx, pres, &tmpl);
396
zink_clear_texture(struct pipe_context *pctx,
397
struct pipe_resource *pres,
399
const struct pipe_box *box,
402
struct zink_context *ctx = zink_context(pctx);
403
struct zink_resource *res = zink_resource(pres);
404
struct pipe_screen *pscreen = pctx->screen;
405
struct u_rect region = zink_rect_from_box(box);
406
bool needs_rp = !zink_blit_region_fills(region, pres->width0, pres->height0) || ctx->render_condition_active;
407
struct pipe_surface *surf = NULL;
409
if (res->aspect & VK_IMAGE_ASPECT_COLOR_BIT) {
410
union pipe_color_union color;
412
util_format_unpack_rgba(pres->format, color.ui, data, 1);
414
if (pscreen->is_format_supported(pscreen, pres->format, pres->target, 0, 0,
415
PIPE_BIND_RENDER_TARGET) && !needs_rp) {
416
zink_batch_no_rp(ctx);
417
clear_color_no_rp(ctx, res, &color, level, box->z, box->depth);
419
surf = create_clear_surface(pctx, pres, level, box);
420
zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS);
421
util_blitter_clear_render_target(ctx->blitter, surf, &color, box->x, box->y, box->width, box->height);
423
if (res->base.b.target == PIPE_BUFFER)
424
util_range_add(&res->base.b, &res->valid_buffer_range, box->x, box->x + box->width);
429
if (res->aspect & VK_IMAGE_ASPECT_DEPTH_BIT)
430
util_format_unpack_z_float(pres->format, &depth, data, 1);
432
if (res->aspect & VK_IMAGE_ASPECT_STENCIL_BIT)
433
util_format_unpack_s_8uint(pres->format, &stencil, data, 1);
436
zink_batch_no_rp(ctx);
437
clear_zs_no_rp(ctx, res, res->aspect, depth, stencil, level, box->z, box->depth);
440
if (res->aspect & VK_IMAGE_ASPECT_DEPTH_BIT)
441
flags |= PIPE_CLEAR_DEPTH;
442
if (res->aspect & VK_IMAGE_ASPECT_STENCIL_BIT)
443
flags |= PIPE_CLEAR_STENCIL;
444
surf = create_clear_surface(pctx, pres, level, box);
445
zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS);
446
util_blitter_clear_depth_stencil(ctx->blitter, surf, flags, depth, stencil, box->x, box->y, box->width, box->height);
449
/* this will never destroy the surface */
450
pipe_surface_reference(&surf, NULL);
454
zink_clear_buffer(struct pipe_context *pctx,
455
struct pipe_resource *pres,
458
const void *clear_value,
459
int clear_value_size)
461
struct zink_context *ctx = zink_context(pctx);
462
struct zink_resource *res = zink_resource(pres);
465
if (util_lower_clearsize_to_dword(clear_value, &clear_value_size, &clamped))
466
clear_value = &clamped;
467
if (offset % 4 == 0 && size % 4 == 0 && clear_value_size == sizeof(uint32_t)) {
469
- dstOffset is the byte offset into the buffer at which to start filling,
470
and must be a multiple of 4.
472
- size is the number of bytes to fill, and must be either a multiple of 4,
473
or VK_WHOLE_SIZE to fill the range from offset to the end of the buffer
475
struct zink_batch *batch = &ctx->batch;
476
zink_batch_no_rp(ctx);
477
zink_batch_reference_resource_rw(batch, res, true);
478
util_range_add(&res->base.b, &res->valid_buffer_range, offset, offset + size);
479
zink_resource_buffer_barrier(ctx, res, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
480
VKCTX(CmdFillBuffer)(batch->state->cmdbuf, res->obj->buffer, offset, size, *(uint32_t*)clear_value);
483
struct pipe_transfer *xfer;
484
uint8_t *map = pipe_buffer_map_range(pctx, pres, offset, size,
485
PIPE_MAP_WRITE | PIPE_MAP_ONCE | PIPE_MAP_DISCARD_RANGE, &xfer);
488
unsigned rem = size % clear_value_size;
490
for (unsigned i = 0; i < (size - rem) / clear_value_size; i++) {
491
memcpy(ptr, clear_value, clear_value_size);
492
ptr += clear_value_size;
495
memcpy(map + size - rem, clear_value, rem);
496
pipe_buffer_unmap(pctx, xfer);
500
zink_clear_render_target(struct pipe_context *pctx, struct pipe_surface *dst,
501
const union pipe_color_union *color, unsigned dstx,
502
unsigned dsty, unsigned width, unsigned height,
503
bool render_condition_enabled)
505
struct zink_context *ctx = zink_context(pctx);
506
zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS | (render_condition_enabled ? 0 : ZINK_BLIT_NO_COND_RENDER));
507
util_blitter_clear_render_target(ctx->blitter, dst, color, dstx, dsty, width, height);
508
if (!render_condition_enabled && ctx->render_condition_active)
509
zink_start_conditional_render(ctx);
513
zink_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *dst,
514
unsigned clear_flags, double depth, unsigned stencil,
515
unsigned dstx, unsigned dsty, unsigned width, unsigned height,
516
bool render_condition_enabled)
518
struct zink_context *ctx = zink_context(pctx);
519
zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS | (render_condition_enabled ? 0 : ZINK_BLIT_NO_COND_RENDER));
520
util_blitter_clear_depth_stencil(ctx->blitter, dst, clear_flags, depth, stencil, dstx, dsty, width, height);
521
if (!render_condition_enabled && ctx->render_condition_active)
522
zink_start_conditional_render(ctx);
526
zink_fb_clear_needs_explicit(struct zink_framebuffer_clear *fb_clear)
528
if (zink_fb_clear_count(fb_clear) != 1)
530
return zink_fb_clear_element_needs_explicit(zink_fb_clear_element(fb_clear, 0));
534
zink_fb_clear_first_needs_explicit(struct zink_framebuffer_clear *fb_clear)
536
if (!zink_fb_clear_count(fb_clear))
538
return zink_fb_clear_element_needs_explicit(zink_fb_clear_element(fb_clear, 0));
542
zink_fb_clear_util_unpack_clear_color(struct zink_framebuffer_clear_data *clear, enum pipe_format format, union pipe_color_union *color)
544
const struct util_format_description *desc = util_format_description(format);
545
if (clear->color.srgb) {
546
/* if SRGB mode is disabled for the fb with a backing srgb image then we have to
547
* convert this to srgb color
549
for (unsigned j = 0; j < MIN2(3, desc->nr_channels); j++) {
550
assert(desc->channel[j].normalized);
551
color->f[j] = util_format_srgb_to_linear_float(clear->color.color.f[j]);
553
color->f[3] = clear->color.color.f[3];
555
*color = clear->color.color;
560
fb_clears_apply_internal(struct zink_context *ctx, struct pipe_resource *pres, int i)
562
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[i];
563
struct zink_resource *res = zink_resource(pres);
565
if (!zink_fb_clear_enabled(ctx, i))
567
if (ctx->batch.in_rp)
568
zink_clear_framebuffer(ctx, BITFIELD_BIT(i));
569
else if (res->aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
570
if (zink_fb_clear_needs_explicit(fb_clear) || !check_3d_layers(ctx->fb_state.cbufs[i]))
571
/* this will automatically trigger all the clears */
574
struct pipe_surface *psurf = ctx->fb_state.cbufs[i];
575
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(fb_clear, 0);
576
union pipe_color_union color = clear->color.color;
578
if (psurf->format != psurf->texture->format) {
580
util_format_pack_rgba(psurf->format, data, color.ui, 1);
581
util_format_unpack_rgba(pres->format, color.ui, data, 1);
584
clear_color_no_rp(ctx, res, &color,
585
psurf->u.tex.level, psurf->u.tex.first_layer,
586
psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1);
588
zink_fb_clear_reset(ctx, i);
591
if (zink_fb_clear_needs_explicit(fb_clear) || !check_3d_layers(ctx->fb_state.zsbuf))
592
/* this will automatically trigger all the clears */
595
struct pipe_surface *psurf = ctx->fb_state.zsbuf;
596
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(fb_clear, 0);
597
VkImageAspectFlags aspects = 0;
598
if (clear->zs.bits & PIPE_CLEAR_DEPTH)
599
aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
600
if (clear->zs.bits & PIPE_CLEAR_STENCIL)
601
aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
602
clear_zs_no_rp(ctx, res, aspects, clear->zs.depth, clear->zs.stencil,
603
psurf->u.tex.level, psurf->u.tex.first_layer,
604
psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1);
607
zink_fb_clear_reset(ctx, i);
611
zink_fb_clear_reset(struct zink_context *ctx, unsigned i)
613
util_dynarray_clear(&ctx->fb_clears[i].clears);
614
if (i == PIPE_MAX_COLOR_BUFS) {
615
ctx->clears_enabled &= ~PIPE_CLEAR_DEPTHSTENCIL;
616
ctx->rp_clears_enabled &= ~PIPE_CLEAR_DEPTHSTENCIL;
618
ctx->clears_enabled &= ~(PIPE_CLEAR_COLOR0 << i);
619
ctx->rp_clears_enabled &= ~(PIPE_CLEAR_COLOR0 << i);
624
zink_fb_clears_apply(struct zink_context *ctx, struct pipe_resource *pres)
626
if (zink_resource(pres)->aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
627
for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
628
if (ctx->fb_state.cbufs[i] && ctx->fb_state.cbufs[i]->texture == pres) {
629
fb_clears_apply_internal(ctx, pres, i);
633
if (ctx->fb_state.zsbuf && ctx->fb_state.zsbuf->texture == pres) {
634
fb_clears_apply_internal(ctx, pres, PIPE_MAX_COLOR_BUFS);
640
zink_fb_clears_discard(struct zink_context *ctx, struct pipe_resource *pres)
642
if (zink_resource(pres)->aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
643
for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
644
if (ctx->fb_state.cbufs[i] && ctx->fb_state.cbufs[i]->texture == pres) {
645
if (zink_fb_clear_enabled(ctx, i)) {
646
zink_fb_clear_reset(ctx, i);
651
if (zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS) && ctx->fb_state.zsbuf && ctx->fb_state.zsbuf->texture == pres) {
652
int i = PIPE_MAX_COLOR_BUFS;
653
zink_fb_clear_reset(ctx, i);
659
zink_clear_apply_conditionals(struct zink_context *ctx)
661
for (int i = 0; i < ARRAY_SIZE(ctx->fb_clears); i++) {
662
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[i];
663
if (!zink_fb_clear_enabled(ctx, i))
665
for (int j = 0; j < zink_fb_clear_count(fb_clear); j++) {
666
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(fb_clear, j);
667
if (clear->conditional) {
668
struct pipe_surface *surf;
669
if (i < PIPE_MAX_COLOR_BUFS)
670
surf = ctx->fb_state.cbufs[i];
672
surf = ctx->fb_state.zsbuf;
674
fb_clears_apply_internal(ctx, surf->texture, i);
676
zink_fb_clear_reset(ctx, i);
684
fb_clears_apply_or_discard_internal(struct zink_context *ctx, struct pipe_resource *pres, struct u_rect region, bool discard_only, bool invert, int i)
686
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[i];
687
if (zink_fb_clear_enabled(ctx, i)) {
688
if (zink_blit_region_fills(region, pres->width0, pres->height0)) {
690
fb_clears_apply_internal(ctx, pres, i);
692
/* we know we can skip these */
693
zink_fb_clears_discard(ctx, pres);
696
for (int j = 0; j < zink_fb_clear_count(fb_clear); j++) {
697
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(fb_clear, j);
698
struct u_rect scissor = {clear->scissor.minx, clear->scissor.maxx,
699
clear->scissor.miny, clear->scissor.maxy};
700
if (!clear->has_scissor || zink_blit_region_covers(region, scissor)) {
701
/* this is a clear that isn't fully covered by our pending write */
703
fb_clears_apply_internal(ctx, pres, i);
708
/* if we haven't already returned, then we know we can discard */
709
zink_fb_clears_discard(ctx, pres);
714
zink_fb_clears_apply_or_discard(struct zink_context *ctx, struct pipe_resource *pres, struct u_rect region, bool discard_only)
716
if (zink_resource(pres)->aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
717
for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
718
if (ctx->fb_state.cbufs[i] && ctx->fb_state.cbufs[i]->texture == pres) {
719
fb_clears_apply_or_discard_internal(ctx, pres, region, discard_only, false, i);
723
if (zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS) && ctx->fb_state.zsbuf && ctx->fb_state.zsbuf->texture == pres) {
724
fb_clears_apply_or_discard_internal(ctx, pres, region, discard_only, false, PIPE_MAX_COLOR_BUFS);
730
zink_fb_clears_apply_region(struct zink_context *ctx, struct pipe_resource *pres, struct u_rect region)
732
if (zink_resource(pres)->aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
733
for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
734
if (ctx->fb_state.cbufs[i] && ctx->fb_state.cbufs[i]->texture == pres) {
735
fb_clears_apply_or_discard_internal(ctx, pres, region, false, true, i);
739
if (ctx->fb_state.zsbuf && ctx->fb_state.zsbuf->texture == pres) {
740
fb_clears_apply_or_discard_internal(ctx, pres, region, false, true, PIPE_MAX_COLOR_BUFS);