Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/intel/vulkan/anv_blorp.c
4547 views
1
/*
2
* Copyright © 2016 Intel Corporation
3
*
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
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
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
13
* Software.
14
*
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 NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*/
23
24
#include "anv_private.h"
25
26
static bool
27
lookup_blorp_shader(struct blorp_batch *batch,
28
const void *key, uint32_t key_size,
29
uint32_t *kernel_out, void *prog_data_out)
30
{
31
struct blorp_context *blorp = batch->blorp;
32
struct anv_device *device = blorp->driver_ctx;
33
34
/* The default cache must be a real cache */
35
assert(device->default_pipeline_cache.cache);
36
37
struct anv_shader_bin *bin =
38
anv_pipeline_cache_search(&device->default_pipeline_cache, key, key_size);
39
if (!bin)
40
return false;
41
42
/* The cache already has a reference and it's not going anywhere so there
43
* is no need to hold a second reference.
44
*/
45
anv_shader_bin_unref(device, bin);
46
47
*kernel_out = bin->kernel.offset;
48
*(const struct brw_stage_prog_data **)prog_data_out = bin->prog_data;
49
50
return true;
51
}
52
53
static bool
54
upload_blorp_shader(struct blorp_batch *batch, uint32_t stage,
55
const void *key, uint32_t key_size,
56
const void *kernel, uint32_t kernel_size,
57
const struct brw_stage_prog_data *prog_data,
58
uint32_t prog_data_size,
59
uint32_t *kernel_out, void *prog_data_out)
60
{
61
struct blorp_context *blorp = batch->blorp;
62
struct anv_device *device = blorp->driver_ctx;
63
64
/* The blorp cache must be a real cache */
65
assert(device->default_pipeline_cache.cache);
66
67
struct anv_pipeline_bind_map bind_map = {
68
.surface_count = 0,
69
.sampler_count = 0,
70
};
71
72
struct anv_shader_bin *bin =
73
anv_pipeline_cache_upload_kernel(&device->default_pipeline_cache, stage,
74
key, key_size, kernel, kernel_size,
75
prog_data, prog_data_size,
76
NULL, 0, NULL, &bind_map);
77
78
if (!bin)
79
return false;
80
81
/* The cache already has a reference and it's not going anywhere so there
82
* is no need to hold a second reference.
83
*/
84
anv_shader_bin_unref(device, bin);
85
86
*kernel_out = bin->kernel.offset;
87
*(const struct brw_stage_prog_data **)prog_data_out = bin->prog_data;
88
89
return true;
90
}
91
92
void
93
anv_device_init_blorp(struct anv_device *device)
94
{
95
blorp_init(&device->blorp, device, &device->isl_dev);
96
device->blorp.compiler = device->physical->compiler;
97
device->blorp.lookup_shader = lookup_blorp_shader;
98
device->blorp.upload_shader = upload_blorp_shader;
99
switch (device->info.verx10) {
100
case 70:
101
device->blorp.exec = gfx7_blorp_exec;
102
break;
103
case 75:
104
device->blorp.exec = gfx75_blorp_exec;
105
break;
106
case 80:
107
device->blorp.exec = gfx8_blorp_exec;
108
break;
109
case 90:
110
device->blorp.exec = gfx9_blorp_exec;
111
break;
112
case 110:
113
device->blorp.exec = gfx11_blorp_exec;
114
break;
115
case 120:
116
device->blorp.exec = gfx12_blorp_exec;
117
break;
118
case 125:
119
device->blorp.exec = gfx125_blorp_exec;
120
break;
121
default:
122
unreachable("Unknown hardware generation");
123
}
124
}
125
126
void
127
anv_device_finish_blorp(struct anv_device *device)
128
{
129
blorp_finish(&device->blorp);
130
}
131
132
static void
133
get_blorp_surf_for_anv_buffer(struct anv_device *device,
134
struct anv_buffer *buffer, uint64_t offset,
135
uint32_t width, uint32_t height,
136
uint32_t row_pitch, enum isl_format format,
137
bool is_dest,
138
struct blorp_surf *blorp_surf,
139
struct isl_surf *isl_surf)
140
{
141
const struct isl_format_layout *fmtl =
142
isl_format_get_layout(format);
143
bool ok UNUSED;
144
145
/* ASTC is the only format which doesn't support linear layouts.
146
* Create an equivalently sized surface with ISL to get around this.
147
*/
148
if (fmtl->txc == ISL_TXC_ASTC) {
149
/* Use an equivalently sized format */
150
format = ISL_FORMAT_R32G32B32A32_UINT;
151
assert(fmtl->bpb == isl_format_get_layout(format)->bpb);
152
153
/* Shrink the dimensions for the new format */
154
width = DIV_ROUND_UP(width, fmtl->bw);
155
height = DIV_ROUND_UP(height, fmtl->bh);
156
}
157
158
*blorp_surf = (struct blorp_surf) {
159
.surf = isl_surf,
160
.addr = {
161
.buffer = buffer->address.bo,
162
.offset = buffer->address.offset + offset,
163
.mocs = anv_mocs(device, buffer->address.bo,
164
is_dest ? ISL_SURF_USAGE_RENDER_TARGET_BIT
165
: ISL_SURF_USAGE_TEXTURE_BIT),
166
},
167
};
168
169
ok = isl_surf_init(&device->isl_dev, isl_surf,
170
.dim = ISL_SURF_DIM_2D,
171
.format = format,
172
.width = width,
173
.height = height,
174
.depth = 1,
175
.levels = 1,
176
.array_len = 1,
177
.samples = 1,
178
.row_pitch_B = row_pitch,
179
.usage = is_dest ? ISL_SURF_USAGE_RENDER_TARGET_BIT
180
: ISL_SURF_USAGE_TEXTURE_BIT,
181
.tiling_flags = ISL_TILING_LINEAR_BIT);
182
assert(ok);
183
}
184
185
/* Pick something high enough that it won't be used in core and low enough it
186
* will never map to an extension.
187
*/
188
#define ANV_IMAGE_LAYOUT_EXPLICIT_AUX (VkImageLayout)10000000
189
190
static struct blorp_address
191
anv_to_blorp_address(struct anv_address addr)
192
{
193
return (struct blorp_address) {
194
.buffer = addr.bo,
195
.offset = addr.offset,
196
};
197
}
198
199
static void
200
get_blorp_surf_for_anv_image(const struct anv_device *device,
201
const struct anv_image *image,
202
VkImageAspectFlags aspect,
203
VkImageUsageFlags usage,
204
VkImageLayout layout,
205
enum isl_aux_usage aux_usage,
206
struct blorp_surf *blorp_surf)
207
{
208
uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);
209
210
if (layout != ANV_IMAGE_LAYOUT_EXPLICIT_AUX) {
211
assert(usage != 0);
212
aux_usage = anv_layout_to_aux_usage(&device->info, image,
213
aspect, usage, layout);
214
}
215
216
isl_surf_usage_flags_t mocs_usage =
217
(usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) ?
218
ISL_SURF_USAGE_RENDER_TARGET_BIT : ISL_SURF_USAGE_TEXTURE_BIT;
219
220
const struct anv_surface *surface = &image->planes[plane].primary_surface;
221
const struct anv_address address =
222
anv_image_address(image, &surface->memory_range);
223
224
*blorp_surf = (struct blorp_surf) {
225
.surf = &surface->isl,
226
.addr = {
227
.buffer = address.bo,
228
.offset = address.offset,
229
.mocs = anv_mocs(device, address.bo, mocs_usage),
230
},
231
};
232
233
if (aux_usage != ISL_AUX_USAGE_NONE) {
234
const struct anv_surface *aux_surface = &image->planes[plane].aux_surface;
235
const struct anv_address aux_address =
236
anv_image_address(image, &aux_surface->memory_range);
237
238
blorp_surf->aux_usage = aux_usage;
239
blorp_surf->aux_surf = &aux_surface->isl;
240
241
if (!anv_address_is_null(aux_address)) {
242
blorp_surf->aux_addr = (struct blorp_address) {
243
.buffer = aux_address.bo,
244
.offset = aux_address.offset,
245
.mocs = anv_mocs(device, aux_address.bo, 0),
246
};
247
}
248
249
/* If we're doing a partial resolve, then we need the indirect clear
250
* color. If we are doing a fast clear and want to store/update the
251
* clear color, we also pass the address to blorp, otherwise it will only
252
* stomp the CCS to a particular value and won't care about format or
253
* clear value
254
*/
255
if (aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) {
256
const struct anv_address clear_color_addr =
257
anv_image_get_clear_color_addr(device, image, aspect);
258
blorp_surf->clear_color_addr = anv_to_blorp_address(clear_color_addr);
259
} else if (aspect & VK_IMAGE_ASPECT_DEPTH_BIT) {
260
const struct anv_address clear_color_addr =
261
anv_image_get_clear_color_addr(device, image, aspect);
262
blorp_surf->clear_color_addr = anv_to_blorp_address(clear_color_addr);
263
blorp_surf->clear_color = (union isl_color_value) {
264
.f32 = { ANV_HZ_FC_VAL },
265
};
266
}
267
}
268
}
269
270
static bool
271
get_blorp_surf_for_anv_shadow_image(const struct anv_device *device,
272
const struct anv_image *image,
273
VkImageAspectFlags aspect,
274
struct blorp_surf *blorp_surf)
275
{
276
277
uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);
278
if (!anv_surface_is_valid(&image->planes[plane].shadow_surface))
279
return false;
280
281
const struct anv_surface *surface = &image->planes[plane].shadow_surface;
282
const struct anv_address address =
283
anv_image_address(image, &surface->memory_range);
284
285
*blorp_surf = (struct blorp_surf) {
286
.surf = &surface->isl,
287
.addr = {
288
.buffer = address.bo,
289
.offset = address.offset,
290
.mocs = anv_mocs(device, address.bo, ISL_SURF_USAGE_RENDER_TARGET_BIT),
291
},
292
};
293
294
return true;
295
}
296
297
static void
298
copy_image(struct anv_cmd_buffer *cmd_buffer,
299
struct blorp_batch *batch,
300
struct anv_image *src_image,
301
VkImageLayout src_image_layout,
302
struct anv_image *dst_image,
303
VkImageLayout dst_image_layout,
304
const VkImageCopy2KHR *region)
305
{
306
VkOffset3D srcOffset =
307
anv_sanitize_image_offset(src_image->type, region->srcOffset);
308
VkOffset3D dstOffset =
309
anv_sanitize_image_offset(dst_image->type, region->dstOffset);
310
VkExtent3D extent =
311
anv_sanitize_image_extent(src_image->type, region->extent);
312
313
const uint32_t dst_level = region->dstSubresource.mipLevel;
314
unsigned dst_base_layer, layer_count;
315
if (dst_image->type == VK_IMAGE_TYPE_3D) {
316
dst_base_layer = region->dstOffset.z;
317
layer_count = region->extent.depth;
318
} else {
319
dst_base_layer = region->dstSubresource.baseArrayLayer;
320
layer_count =
321
anv_get_layerCount(dst_image, &region->dstSubresource);
322
}
323
324
const uint32_t src_level = region->srcSubresource.mipLevel;
325
unsigned src_base_layer;
326
if (src_image->type == VK_IMAGE_TYPE_3D) {
327
src_base_layer = region->srcOffset.z;
328
} else {
329
src_base_layer = region->srcSubresource.baseArrayLayer;
330
assert(layer_count ==
331
anv_get_layerCount(src_image, &region->srcSubresource));
332
}
333
334
VkImageAspectFlags src_mask = region->srcSubresource.aspectMask,
335
dst_mask = region->dstSubresource.aspectMask;
336
337
assert(anv_image_aspects_compatible(src_mask, dst_mask));
338
339
if (util_bitcount(src_mask) > 1) {
340
anv_foreach_image_aspect_bit(aspect_bit, src_image, src_mask) {
341
struct blorp_surf src_surf, dst_surf;
342
get_blorp_surf_for_anv_image(cmd_buffer->device,
343
src_image, 1UL << aspect_bit,
344
VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
345
src_image_layout, ISL_AUX_USAGE_NONE,
346
&src_surf);
347
get_blorp_surf_for_anv_image(cmd_buffer->device,
348
dst_image, 1UL << aspect_bit,
349
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
350
dst_image_layout, ISL_AUX_USAGE_NONE,
351
&dst_surf);
352
anv_cmd_buffer_mark_image_written(cmd_buffer, dst_image,
353
1UL << aspect_bit,
354
dst_surf.aux_usage, dst_level,
355
dst_base_layer, layer_count);
356
357
for (unsigned i = 0; i < layer_count; i++) {
358
blorp_copy(batch, &src_surf, src_level, src_base_layer + i,
359
&dst_surf, dst_level, dst_base_layer + i,
360
srcOffset.x, srcOffset.y,
361
dstOffset.x, dstOffset.y,
362
extent.width, extent.height);
363
}
364
365
struct blorp_surf dst_shadow_surf;
366
if (get_blorp_surf_for_anv_shadow_image(cmd_buffer->device,
367
dst_image,
368
1UL << aspect_bit,
369
&dst_shadow_surf)) {
370
for (unsigned i = 0; i < layer_count; i++) {
371
blorp_copy(batch, &src_surf, src_level, src_base_layer + i,
372
&dst_shadow_surf, dst_level, dst_base_layer + i,
373
srcOffset.x, srcOffset.y,
374
dstOffset.x, dstOffset.y,
375
extent.width, extent.height);
376
}
377
}
378
}
379
} else {
380
struct blorp_surf src_surf, dst_surf;
381
get_blorp_surf_for_anv_image(cmd_buffer->device, src_image, src_mask,
382
VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
383
src_image_layout, ISL_AUX_USAGE_NONE,
384
&src_surf);
385
get_blorp_surf_for_anv_image(cmd_buffer->device, dst_image, dst_mask,
386
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
387
dst_image_layout, ISL_AUX_USAGE_NONE,
388
&dst_surf);
389
anv_cmd_buffer_mark_image_written(cmd_buffer, dst_image, dst_mask,
390
dst_surf.aux_usage, dst_level,
391
dst_base_layer, layer_count);
392
393
for (unsigned i = 0; i < layer_count; i++) {
394
blorp_copy(batch, &src_surf, src_level, src_base_layer + i,
395
&dst_surf, dst_level, dst_base_layer + i,
396
srcOffset.x, srcOffset.y,
397
dstOffset.x, dstOffset.y,
398
extent.width, extent.height);
399
}
400
401
struct blorp_surf dst_shadow_surf;
402
if (get_blorp_surf_for_anv_shadow_image(cmd_buffer->device,
403
dst_image, dst_mask,
404
&dst_shadow_surf)) {
405
for (unsigned i = 0; i < layer_count; i++) {
406
blorp_copy(batch, &src_surf, src_level, src_base_layer + i,
407
&dst_shadow_surf, dst_level, dst_base_layer + i,
408
srcOffset.x, srcOffset.y,
409
dstOffset.x, dstOffset.y,
410
extent.width, extent.height);
411
}
412
}
413
}
414
}
415
416
void anv_CmdCopyImage2KHR(
417
VkCommandBuffer commandBuffer,
418
const VkCopyImageInfo2KHR* pCopyImageInfo)
419
{
420
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
421
ANV_FROM_HANDLE(anv_image, src_image, pCopyImageInfo->srcImage);
422
ANV_FROM_HANDLE(anv_image, dst_image, pCopyImageInfo->dstImage);
423
424
struct blorp_batch batch;
425
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
426
427
for (unsigned r = 0; r < pCopyImageInfo->regionCount; r++) {
428
copy_image(cmd_buffer, &batch,
429
src_image, pCopyImageInfo->srcImageLayout,
430
dst_image, pCopyImageInfo->dstImageLayout,
431
&pCopyImageInfo->pRegions[r]);
432
}
433
434
blorp_batch_finish(&batch);
435
}
436
437
static enum isl_format
438
isl_format_for_size(unsigned size_B)
439
{
440
/* Prefer 32-bit per component formats for CmdFillBuffer */
441
switch (size_B) {
442
case 1: return ISL_FORMAT_R8_UINT;
443
case 2: return ISL_FORMAT_R16_UINT;
444
case 3: return ISL_FORMAT_R8G8B8_UINT;
445
case 4: return ISL_FORMAT_R32_UINT;
446
case 6: return ISL_FORMAT_R16G16B16_UINT;
447
case 8: return ISL_FORMAT_R32G32_UINT;
448
case 12: return ISL_FORMAT_R32G32B32_UINT;
449
case 16: return ISL_FORMAT_R32G32B32A32_UINT;
450
default:
451
unreachable("Unknown format size");
452
}
453
}
454
455
static void
456
copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,
457
struct blorp_batch *batch,
458
struct anv_buffer *anv_buffer,
459
struct anv_image *anv_image,
460
VkImageLayout image_layout,
461
const VkBufferImageCopy2KHR* region,
462
bool buffer_to_image)
463
{
464
struct {
465
struct blorp_surf surf;
466
uint32_t level;
467
VkOffset3D offset;
468
} image, buffer, *src, *dst;
469
470
buffer.level = 0;
471
buffer.offset = (VkOffset3D) { 0, 0, 0 };
472
473
if (buffer_to_image) {
474
src = &buffer;
475
dst = &image;
476
} else {
477
src = &image;
478
dst = &buffer;
479
}
480
481
const VkImageAspectFlags aspect = region->imageSubresource.aspectMask;
482
483
get_blorp_surf_for_anv_image(cmd_buffer->device, anv_image, aspect,
484
buffer_to_image ?
485
VK_IMAGE_USAGE_TRANSFER_DST_BIT :
486
VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
487
image_layout, ISL_AUX_USAGE_NONE,
488
&image.surf);
489
image.offset =
490
anv_sanitize_image_offset(anv_image->type, region->imageOffset);
491
image.level = region->imageSubresource.mipLevel;
492
493
VkExtent3D extent =
494
anv_sanitize_image_extent(anv_image->type, region->imageExtent);
495
if (anv_image->type != VK_IMAGE_TYPE_3D) {
496
image.offset.z = region->imageSubresource.baseArrayLayer;
497
extent.depth =
498
anv_get_layerCount(anv_image, &region->imageSubresource);
499
}
500
501
const enum isl_format linear_format =
502
anv_get_isl_format(&cmd_buffer->device->info, anv_image->vk_format,
503
aspect, VK_IMAGE_TILING_LINEAR);
504
const struct isl_format_layout *linear_fmtl =
505
isl_format_get_layout(linear_format);
506
507
const uint32_t buffer_row_length =
508
region->bufferRowLength ?
509
region->bufferRowLength : extent.width;
510
511
const uint32_t buffer_image_height =
512
region->bufferImageHeight ?
513
region->bufferImageHeight : extent.height;
514
515
const uint32_t buffer_row_pitch =
516
DIV_ROUND_UP(buffer_row_length, linear_fmtl->bw) *
517
(linear_fmtl->bpb / 8);
518
519
const uint32_t buffer_layer_stride =
520
DIV_ROUND_UP(buffer_image_height, linear_fmtl->bh) *
521
buffer_row_pitch;
522
523
/* Some formats have additional restrictions which may cause ISL to
524
* fail to create a surface for us. Some examples include:
525
*
526
* 1. ASTC formats are not allowed to be LINEAR and must be tiled
527
* 2. YCbCr formats have to have 2-pixel aligned strides
528
*
529
* To avoid these issues, we always bind the buffer as if it's a
530
* "normal" format like RGBA32_UINT. Since we're using blorp_copy,
531
* the format doesn't matter as long as it has the right bpb.
532
*/
533
const VkExtent2D buffer_extent = {
534
.width = DIV_ROUND_UP(extent.width, linear_fmtl->bw),
535
.height = DIV_ROUND_UP(extent.height, linear_fmtl->bh),
536
};
537
const enum isl_format buffer_format =
538
isl_format_for_size(linear_fmtl->bpb / 8);
539
540
struct isl_surf buffer_isl_surf;
541
get_blorp_surf_for_anv_buffer(cmd_buffer->device,
542
anv_buffer, region->bufferOffset,
543
buffer_extent.width, buffer_extent.height,
544
buffer_row_pitch, buffer_format, false,
545
&buffer.surf, &buffer_isl_surf);
546
547
bool dst_has_shadow = false;
548
struct blorp_surf dst_shadow_surf;
549
if (&image == dst) {
550
/* In this case, the source is the buffer and, since blorp takes its
551
* copy dimensions in terms of the source format, we have to use the
552
* scaled down version for compressed textures because the source
553
* format is an RGB format.
554
*/
555
extent.width = buffer_extent.width;
556
extent.height = buffer_extent.height;
557
558
anv_cmd_buffer_mark_image_written(cmd_buffer, anv_image,
559
aspect, dst->surf.aux_usage,
560
dst->level,
561
dst->offset.z, extent.depth);
562
563
dst_has_shadow =
564
get_blorp_surf_for_anv_shadow_image(cmd_buffer->device,
565
anv_image, aspect,
566
&dst_shadow_surf);
567
}
568
569
for (unsigned z = 0; z < extent.depth; z++) {
570
blorp_copy(batch, &src->surf, src->level, src->offset.z,
571
&dst->surf, dst->level, dst->offset.z,
572
src->offset.x, src->offset.y, dst->offset.x, dst->offset.y,
573
extent.width, extent.height);
574
575
if (dst_has_shadow) {
576
blorp_copy(batch, &src->surf, src->level, src->offset.z,
577
&dst_shadow_surf, dst->level, dst->offset.z,
578
src->offset.x, src->offset.y,
579
dst->offset.x, dst->offset.y,
580
extent.width, extent.height);
581
}
582
583
image.offset.z++;
584
buffer.surf.addr.offset += buffer_layer_stride;
585
}
586
}
587
588
void anv_CmdCopyBufferToImage2KHR(
589
VkCommandBuffer commandBuffer,
590
const VkCopyBufferToImageInfo2KHR* pCopyBufferToImageInfo)
591
{
592
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
593
ANV_FROM_HANDLE(anv_buffer, src_buffer, pCopyBufferToImageInfo->srcBuffer);
594
ANV_FROM_HANDLE(anv_image, dst_image, pCopyBufferToImageInfo->dstImage);
595
596
struct blorp_batch batch;
597
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
598
599
for (unsigned r = 0; r < pCopyBufferToImageInfo->regionCount; r++) {
600
copy_buffer_to_image(cmd_buffer, &batch, src_buffer, dst_image,
601
pCopyBufferToImageInfo->dstImageLayout,
602
&pCopyBufferToImageInfo->pRegions[r], true);
603
}
604
605
blorp_batch_finish(&batch);
606
}
607
608
void anv_CmdCopyImageToBuffer2KHR(
609
VkCommandBuffer commandBuffer,
610
const VkCopyImageToBufferInfo2KHR* pCopyImageToBufferInfo)
611
{
612
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
613
ANV_FROM_HANDLE(anv_image, src_image, pCopyImageToBufferInfo->srcImage);
614
ANV_FROM_HANDLE(anv_buffer, dst_buffer, pCopyImageToBufferInfo->dstBuffer);
615
616
struct blorp_batch batch;
617
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
618
619
for (unsigned r = 0; r < pCopyImageToBufferInfo->regionCount; r++) {
620
copy_buffer_to_image(cmd_buffer, &batch, dst_buffer, src_image,
621
pCopyImageToBufferInfo->srcImageLayout,
622
&pCopyImageToBufferInfo->pRegions[r], false);
623
}
624
625
blorp_batch_finish(&batch);
626
627
cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_BUFFER_WRITES;
628
}
629
630
static bool
631
flip_coords(unsigned *src0, unsigned *src1, unsigned *dst0, unsigned *dst1)
632
{
633
bool flip = false;
634
if (*src0 > *src1) {
635
unsigned tmp = *src0;
636
*src0 = *src1;
637
*src1 = tmp;
638
flip = !flip;
639
}
640
641
if (*dst0 > *dst1) {
642
unsigned tmp = *dst0;
643
*dst0 = *dst1;
644
*dst1 = tmp;
645
flip = !flip;
646
}
647
648
return flip;
649
}
650
651
static void
652
blit_image(struct anv_cmd_buffer *cmd_buffer,
653
struct blorp_batch *batch,
654
struct anv_image *src_image,
655
VkImageLayout src_image_layout,
656
struct anv_image *dst_image,
657
VkImageLayout dst_image_layout,
658
const VkImageBlit2KHR *region,
659
VkFilter filter)
660
{
661
const VkImageSubresourceLayers *src_res = &region->srcSubresource;
662
const VkImageSubresourceLayers *dst_res = &region->dstSubresource;
663
664
struct blorp_surf src, dst;
665
666
enum blorp_filter blorp_filter;
667
switch (filter) {
668
case VK_FILTER_NEAREST:
669
blorp_filter = BLORP_FILTER_NEAREST;
670
break;
671
case VK_FILTER_LINEAR:
672
blorp_filter = BLORP_FILTER_BILINEAR;
673
break;
674
default:
675
unreachable("Invalid filter");
676
}
677
678
assert(anv_image_aspects_compatible(src_res->aspectMask,
679
dst_res->aspectMask));
680
681
anv_foreach_image_aspect_bit(aspect_bit, src_image, src_res->aspectMask) {
682
get_blorp_surf_for_anv_image(cmd_buffer->device,
683
src_image, 1U << aspect_bit,
684
VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
685
src_image_layout, ISL_AUX_USAGE_NONE, &src);
686
get_blorp_surf_for_anv_image(cmd_buffer->device,
687
dst_image, 1U << aspect_bit,
688
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
689
dst_image_layout, ISL_AUX_USAGE_NONE, &dst);
690
691
struct anv_format_plane src_format =
692
anv_get_format_plane(&cmd_buffer->device->info, src_image->vk_format,
693
1U << aspect_bit, src_image->tiling);
694
struct anv_format_plane dst_format =
695
anv_get_format_plane(&cmd_buffer->device->info, dst_image->vk_format,
696
1U << aspect_bit, dst_image->tiling);
697
698
unsigned dst_start, dst_end;
699
if (dst_image->type == VK_IMAGE_TYPE_3D) {
700
assert(dst_res->baseArrayLayer == 0);
701
dst_start = region->dstOffsets[0].z;
702
dst_end = region->dstOffsets[1].z;
703
} else {
704
dst_start = dst_res->baseArrayLayer;
705
dst_end = dst_start + anv_get_layerCount(dst_image, dst_res);
706
}
707
708
unsigned src_start, src_end;
709
if (src_image->type == VK_IMAGE_TYPE_3D) {
710
assert(src_res->baseArrayLayer == 0);
711
src_start = region->srcOffsets[0].z;
712
src_end = region->srcOffsets[1].z;
713
} else {
714
src_start = src_res->baseArrayLayer;
715
src_end = src_start + anv_get_layerCount(src_image, src_res);
716
}
717
718
bool flip_z = flip_coords(&src_start, &src_end, &dst_start, &dst_end);
719
const unsigned num_layers = dst_end - dst_start;
720
float src_z_step = (float)(src_end - src_start) / (float)num_layers;
721
722
/* There is no interpolation to the pixel center during rendering, so
723
* add the 0.5 offset ourselves here. */
724
float depth_center_offset = 0;
725
if (src_image->type == VK_IMAGE_TYPE_3D)
726
depth_center_offset = 0.5 / num_layers * (src_end - src_start);
727
728
if (flip_z) {
729
src_start = src_end;
730
src_z_step *= -1;
731
depth_center_offset *= -1;
732
}
733
734
unsigned src_x0 = region->srcOffsets[0].x;
735
unsigned src_x1 = region->srcOffsets[1].x;
736
unsigned dst_x0 = region->dstOffsets[0].x;
737
unsigned dst_x1 = region->dstOffsets[1].x;
738
bool flip_x = flip_coords(&src_x0, &src_x1, &dst_x0, &dst_x1);
739
740
unsigned src_y0 = region->srcOffsets[0].y;
741
unsigned src_y1 = region->srcOffsets[1].y;
742
unsigned dst_y0 = region->dstOffsets[0].y;
743
unsigned dst_y1 = region->dstOffsets[1].y;
744
bool flip_y = flip_coords(&src_y0, &src_y1, &dst_y0, &dst_y1);
745
746
anv_cmd_buffer_mark_image_written(cmd_buffer, dst_image,
747
1U << aspect_bit,
748
dst.aux_usage,
749
dst_res->mipLevel,
750
dst_start, num_layers);
751
752
for (unsigned i = 0; i < num_layers; i++) {
753
unsigned dst_z = dst_start + i;
754
float src_z = src_start + i * src_z_step + depth_center_offset;
755
756
blorp_blit(batch, &src, src_res->mipLevel, src_z,
757
src_format.isl_format, src_format.swizzle,
758
&dst, dst_res->mipLevel, dst_z,
759
dst_format.isl_format, dst_format.swizzle,
760
src_x0, src_y0, src_x1, src_y1,
761
dst_x0, dst_y0, dst_x1, dst_y1,
762
blorp_filter, flip_x, flip_y);
763
}
764
}
765
}
766
767
void anv_CmdBlitImage2KHR(
768
VkCommandBuffer commandBuffer,
769
const VkBlitImageInfo2KHR* pBlitImageInfo)
770
{
771
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
772
ANV_FROM_HANDLE(anv_image, src_image, pBlitImageInfo->srcImage);
773
ANV_FROM_HANDLE(anv_image, dst_image, pBlitImageInfo->dstImage);
774
775
struct blorp_batch batch;
776
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
777
778
for (unsigned r = 0; r < pBlitImageInfo->regionCount; r++) {
779
blit_image(cmd_buffer, &batch,
780
src_image, pBlitImageInfo->srcImageLayout,
781
dst_image, pBlitImageInfo->dstImageLayout,
782
&pBlitImageInfo->pRegions[r], pBlitImageInfo->filter);
783
}
784
785
blorp_batch_finish(&batch);
786
}
787
788
/**
789
* Returns the greatest common divisor of a and b that is a power of two.
790
*/
791
static uint64_t
792
gcd_pow2_u64(uint64_t a, uint64_t b)
793
{
794
assert(a > 0 || b > 0);
795
796
unsigned a_log2 = ffsll(a) - 1;
797
unsigned b_log2 = ffsll(b) - 1;
798
799
/* If either a or b is 0, then a_log2 or b_log2 till be UINT_MAX in which
800
* case, the MIN2() will take the other one. If both are 0 then we will
801
* hit the assert above.
802
*/
803
return 1 << MIN2(a_log2, b_log2);
804
}
805
806
/* This is maximum possible width/height our HW can handle */
807
#define MAX_SURFACE_DIM (1ull << 14)
808
809
static void
810
copy_buffer(struct anv_device *device,
811
struct blorp_batch *batch,
812
struct anv_buffer *src_buffer,
813
struct anv_buffer *dst_buffer,
814
const VkBufferCopy2KHR *region)
815
{
816
struct blorp_address src = {
817
.buffer = src_buffer->address.bo,
818
.offset = src_buffer->address.offset + region->srcOffset,
819
.mocs = anv_mocs(device, src_buffer->address.bo,
820
ISL_SURF_USAGE_TEXTURE_BIT),
821
};
822
struct blorp_address dst = {
823
.buffer = dst_buffer->address.bo,
824
.offset = dst_buffer->address.offset + region->dstOffset,
825
.mocs = anv_mocs(device, dst_buffer->address.bo,
826
ISL_SURF_USAGE_RENDER_TARGET_BIT),
827
};
828
829
blorp_buffer_copy(batch, src, dst, region->size);
830
}
831
832
void anv_CmdCopyBuffer2KHR(
833
VkCommandBuffer commandBuffer,
834
const VkCopyBufferInfo2KHR* pCopyBufferInfo)
835
{
836
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
837
ANV_FROM_HANDLE(anv_buffer, src_buffer, pCopyBufferInfo->srcBuffer);
838
ANV_FROM_HANDLE(anv_buffer, dst_buffer, pCopyBufferInfo->dstBuffer);
839
840
struct blorp_batch batch;
841
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
842
843
for (unsigned r = 0; r < pCopyBufferInfo->regionCount; r++) {
844
copy_buffer(cmd_buffer->device, &batch, src_buffer, dst_buffer,
845
&pCopyBufferInfo->pRegions[r]);
846
}
847
848
blorp_batch_finish(&batch);
849
850
cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_BUFFER_WRITES;
851
}
852
853
854
void anv_CmdUpdateBuffer(
855
VkCommandBuffer commandBuffer,
856
VkBuffer dstBuffer,
857
VkDeviceSize dstOffset,
858
VkDeviceSize dataSize,
859
const void* pData)
860
{
861
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
862
ANV_FROM_HANDLE(anv_buffer, dst_buffer, dstBuffer);
863
864
struct blorp_batch batch;
865
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
866
867
/* We can't quite grab a full block because the state stream needs a
868
* little data at the top to build its linked list.
869
*/
870
const uint32_t max_update_size =
871
cmd_buffer->device->dynamic_state_pool.block_size - 64;
872
873
assert(max_update_size < MAX_SURFACE_DIM * 4);
874
875
/* We're about to read data that was written from the CPU. Flush the
876
* texture cache so we don't get anything stale.
877
*/
878
anv_add_pending_pipe_bits(cmd_buffer,
879
ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT,
880
"before UpdateBuffer");
881
882
while (dataSize) {
883
const uint32_t copy_size = MIN2(dataSize, max_update_size);
884
885
struct anv_state tmp_data =
886
anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, copy_size, 64);
887
888
memcpy(tmp_data.map, pData, copy_size);
889
890
struct blorp_address src = {
891
.buffer = cmd_buffer->device->dynamic_state_pool.block_pool.bo,
892
.offset = tmp_data.offset,
893
.mocs = isl_mocs(&cmd_buffer->device->isl_dev,
894
ISL_SURF_USAGE_TEXTURE_BIT, false)
895
};
896
struct blorp_address dst = {
897
.buffer = dst_buffer->address.bo,
898
.offset = dst_buffer->address.offset + dstOffset,
899
.mocs = anv_mocs(cmd_buffer->device, dst_buffer->address.bo,
900
ISL_SURF_USAGE_RENDER_TARGET_BIT),
901
};
902
903
blorp_buffer_copy(&batch, src, dst, copy_size);
904
905
dataSize -= copy_size;
906
dstOffset += copy_size;
907
pData = (void *)pData + copy_size;
908
}
909
910
blorp_batch_finish(&batch);
911
912
cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_BUFFER_WRITES;
913
}
914
915
void anv_CmdFillBuffer(
916
VkCommandBuffer commandBuffer,
917
VkBuffer dstBuffer,
918
VkDeviceSize dstOffset,
919
VkDeviceSize fillSize,
920
uint32_t data)
921
{
922
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
923
ANV_FROM_HANDLE(anv_buffer, dst_buffer, dstBuffer);
924
struct blorp_surf surf;
925
struct isl_surf isl_surf;
926
927
struct blorp_batch batch;
928
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
929
930
fillSize = anv_buffer_get_range(dst_buffer, dstOffset, fillSize);
931
932
/* From the Vulkan spec:
933
*
934
* "size is the number of bytes to fill, and must be either a multiple
935
* of 4, or VK_WHOLE_SIZE to fill the range from offset to the end of
936
* the buffer. If VK_WHOLE_SIZE is used and the remaining size of the
937
* buffer is not a multiple of 4, then the nearest smaller multiple is
938
* used."
939
*/
940
fillSize &= ~3ull;
941
942
/* First, we compute the biggest format that can be used with the
943
* given offsets and size.
944
*/
945
int bs = 16;
946
bs = gcd_pow2_u64(bs, dstOffset);
947
bs = gcd_pow2_u64(bs, fillSize);
948
enum isl_format isl_format = isl_format_for_size(bs);
949
950
union isl_color_value color = {
951
.u32 = { data, data, data, data },
952
};
953
954
const uint64_t max_fill_size = MAX_SURFACE_DIM * MAX_SURFACE_DIM * bs;
955
while (fillSize >= max_fill_size) {
956
get_blorp_surf_for_anv_buffer(cmd_buffer->device,
957
dst_buffer, dstOffset,
958
MAX_SURFACE_DIM, MAX_SURFACE_DIM,
959
MAX_SURFACE_DIM * bs, isl_format, true,
960
&surf, &isl_surf);
961
962
blorp_clear(&batch, &surf, isl_format, ISL_SWIZZLE_IDENTITY,
963
0, 0, 1, 0, 0, MAX_SURFACE_DIM, MAX_SURFACE_DIM,
964
color, NULL);
965
fillSize -= max_fill_size;
966
dstOffset += max_fill_size;
967
}
968
969
uint64_t height = fillSize / (MAX_SURFACE_DIM * bs);
970
assert(height < MAX_SURFACE_DIM);
971
if (height != 0) {
972
const uint64_t rect_fill_size = height * MAX_SURFACE_DIM * bs;
973
get_blorp_surf_for_anv_buffer(cmd_buffer->device,
974
dst_buffer, dstOffset,
975
MAX_SURFACE_DIM, height,
976
MAX_SURFACE_DIM * bs, isl_format, true,
977
&surf, &isl_surf);
978
979
blorp_clear(&batch, &surf, isl_format, ISL_SWIZZLE_IDENTITY,
980
0, 0, 1, 0, 0, MAX_SURFACE_DIM, height,
981
color, NULL);
982
fillSize -= rect_fill_size;
983
dstOffset += rect_fill_size;
984
}
985
986
if (fillSize != 0) {
987
const uint32_t width = fillSize / bs;
988
get_blorp_surf_for_anv_buffer(cmd_buffer->device,
989
dst_buffer, dstOffset,
990
width, 1,
991
width * bs, isl_format, true,
992
&surf, &isl_surf);
993
994
blorp_clear(&batch, &surf, isl_format, ISL_SWIZZLE_IDENTITY,
995
0, 0, 1, 0, 0, width, 1,
996
color, NULL);
997
}
998
999
blorp_batch_finish(&batch);
1000
1001
cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_BUFFER_WRITES;
1002
}
1003
1004
void anv_CmdClearColorImage(
1005
VkCommandBuffer commandBuffer,
1006
VkImage _image,
1007
VkImageLayout imageLayout,
1008
const VkClearColorValue* pColor,
1009
uint32_t rangeCount,
1010
const VkImageSubresourceRange* pRanges)
1011
{
1012
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1013
ANV_FROM_HANDLE(anv_image, image, _image);
1014
1015
static const bool color_write_disable[4] = { false, false, false, false };
1016
1017
struct blorp_batch batch;
1018
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
1019
1020
1021
for (unsigned r = 0; r < rangeCount; r++) {
1022
if (pRanges[r].aspectMask == 0)
1023
continue;
1024
1025
assert(pRanges[r].aspectMask & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);
1026
1027
struct blorp_surf surf;
1028
get_blorp_surf_for_anv_image(cmd_buffer->device,
1029
image, pRanges[r].aspectMask,
1030
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1031
imageLayout, ISL_AUX_USAGE_NONE, &surf);
1032
1033
struct anv_format_plane src_format =
1034
anv_get_format_plane(&cmd_buffer->device->info, image->vk_format,
1035
VK_IMAGE_ASPECT_COLOR_BIT, image->tiling);
1036
1037
unsigned base_layer = pRanges[r].baseArrayLayer;
1038
unsigned layer_count = anv_get_layerCount(image, &pRanges[r]);
1039
1040
for (unsigned i = 0; i < anv_get_levelCount(image, &pRanges[r]); i++) {
1041
const unsigned level = pRanges[r].baseMipLevel + i;
1042
const unsigned level_width = anv_minify(image->extent.width, level);
1043
const unsigned level_height = anv_minify(image->extent.height, level);
1044
1045
if (image->type == VK_IMAGE_TYPE_3D) {
1046
base_layer = 0;
1047
layer_count = anv_minify(image->extent.depth, level);
1048
}
1049
1050
anv_cmd_buffer_mark_image_written(cmd_buffer, image,
1051
pRanges[r].aspectMask,
1052
surf.aux_usage, level,
1053
base_layer, layer_count);
1054
1055
blorp_clear(&batch, &surf,
1056
src_format.isl_format, src_format.swizzle,
1057
level, base_layer, layer_count,
1058
0, 0, level_width, level_height,
1059
vk_to_isl_color(*pColor), color_write_disable);
1060
}
1061
}
1062
1063
blorp_batch_finish(&batch);
1064
}
1065
1066
void anv_CmdClearDepthStencilImage(
1067
VkCommandBuffer commandBuffer,
1068
VkImage image_h,
1069
VkImageLayout imageLayout,
1070
const VkClearDepthStencilValue* pDepthStencil,
1071
uint32_t rangeCount,
1072
const VkImageSubresourceRange* pRanges)
1073
{
1074
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1075
ANV_FROM_HANDLE(anv_image, image, image_h);
1076
1077
struct blorp_batch batch;
1078
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
1079
1080
struct blorp_surf depth, stencil, stencil_shadow;
1081
if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
1082
get_blorp_surf_for_anv_image(cmd_buffer->device,
1083
image, VK_IMAGE_ASPECT_DEPTH_BIT,
1084
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1085
imageLayout, ISL_AUX_USAGE_NONE, &depth);
1086
} else {
1087
memset(&depth, 0, sizeof(depth));
1088
}
1089
1090
bool has_stencil_shadow = false;
1091
if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
1092
get_blorp_surf_for_anv_image(cmd_buffer->device,
1093
image, VK_IMAGE_ASPECT_STENCIL_BIT,
1094
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1095
imageLayout, ISL_AUX_USAGE_NONE, &stencil);
1096
1097
has_stencil_shadow =
1098
get_blorp_surf_for_anv_shadow_image(cmd_buffer->device, image,
1099
VK_IMAGE_ASPECT_STENCIL_BIT,
1100
&stencil_shadow);
1101
} else {
1102
memset(&stencil, 0, sizeof(stencil));
1103
}
1104
1105
for (unsigned r = 0; r < rangeCount; r++) {
1106
if (pRanges[r].aspectMask == 0)
1107
continue;
1108
1109
bool clear_depth = pRanges[r].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT;
1110
bool clear_stencil = pRanges[r].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT;
1111
1112
unsigned base_layer = pRanges[r].baseArrayLayer;
1113
unsigned layer_count = anv_get_layerCount(image, &pRanges[r]);
1114
1115
for (unsigned i = 0; i < anv_get_levelCount(image, &pRanges[r]); i++) {
1116
const unsigned level = pRanges[r].baseMipLevel + i;
1117
const unsigned level_width = anv_minify(image->extent.width, level);
1118
const unsigned level_height = anv_minify(image->extent.height, level);
1119
1120
if (image->type == VK_IMAGE_TYPE_3D)
1121
layer_count = anv_minify(image->extent.depth, level);
1122
1123
blorp_clear_depth_stencil(&batch, &depth, &stencil,
1124
level, base_layer, layer_count,
1125
0, 0, level_width, level_height,
1126
clear_depth, pDepthStencil->depth,
1127
clear_stencil ? 0xff : 0,
1128
pDepthStencil->stencil);
1129
1130
if (clear_stencil && has_stencil_shadow) {
1131
union isl_color_value stencil_color = {
1132
.u32 = { pDepthStencil->stencil, },
1133
};
1134
blorp_clear(&batch, &stencil_shadow,
1135
ISL_FORMAT_R8_UINT, ISL_SWIZZLE_IDENTITY,
1136
level, base_layer, layer_count,
1137
0, 0, level_width, level_height,
1138
stencil_color, NULL);
1139
}
1140
}
1141
}
1142
1143
blorp_batch_finish(&batch);
1144
}
1145
1146
VkResult
1147
anv_cmd_buffer_alloc_blorp_binding_table(struct anv_cmd_buffer *cmd_buffer,
1148
uint32_t num_entries,
1149
uint32_t *state_offset,
1150
struct anv_state *bt_state)
1151
{
1152
*bt_state = anv_cmd_buffer_alloc_binding_table(cmd_buffer, num_entries,
1153
state_offset);
1154
if (bt_state->map == NULL) {
1155
/* We ran out of space. Grab a new binding table block. */
1156
VkResult result = anv_cmd_buffer_new_binding_table_block(cmd_buffer);
1157
if (result != VK_SUCCESS)
1158
return result;
1159
1160
/* Re-emit state base addresses so we get the new surface state base
1161
* address before we start emitting binding tables etc.
1162
*/
1163
anv_cmd_buffer_emit_state_base_address(cmd_buffer);
1164
1165
*bt_state = anv_cmd_buffer_alloc_binding_table(cmd_buffer, num_entries,
1166
state_offset);
1167
assert(bt_state->map != NULL);
1168
}
1169
1170
return VK_SUCCESS;
1171
}
1172
1173
static VkResult
1174
binding_table_for_surface_state(struct anv_cmd_buffer *cmd_buffer,
1175
struct anv_state surface_state,
1176
uint32_t *bt_offset)
1177
{
1178
uint32_t state_offset;
1179
struct anv_state bt_state;
1180
1181
VkResult result =
1182
anv_cmd_buffer_alloc_blorp_binding_table(cmd_buffer, 1, &state_offset,
1183
&bt_state);
1184
if (result != VK_SUCCESS)
1185
return result;
1186
1187
uint32_t *bt_map = bt_state.map;
1188
bt_map[0] = surface_state.offset + state_offset;
1189
1190
*bt_offset = bt_state.offset;
1191
return VK_SUCCESS;
1192
}
1193
1194
static void
1195
clear_color_attachment(struct anv_cmd_buffer *cmd_buffer,
1196
struct blorp_batch *batch,
1197
const VkClearAttachment *attachment,
1198
uint32_t rectCount, const VkClearRect *pRects)
1199
{
1200
const struct anv_subpass *subpass = cmd_buffer->state.subpass;
1201
const uint32_t color_att = attachment->colorAttachment;
1202
assert(color_att < subpass->color_count);
1203
const uint32_t att_idx = subpass->color_attachments[color_att].attachment;
1204
1205
if (att_idx == VK_ATTACHMENT_UNUSED)
1206
return;
1207
1208
struct anv_render_pass_attachment *pass_att =
1209
&cmd_buffer->state.pass->attachments[att_idx];
1210
struct anv_attachment_state *att_state =
1211
&cmd_buffer->state.attachments[att_idx];
1212
1213
uint32_t binding_table;
1214
VkResult result =
1215
binding_table_for_surface_state(cmd_buffer, att_state->color.state,
1216
&binding_table);
1217
if (result != VK_SUCCESS)
1218
return;
1219
1220
union isl_color_value clear_color =
1221
vk_to_isl_color(attachment->clearValue.color);
1222
1223
/* If multiview is enabled we ignore baseArrayLayer and layerCount */
1224
if (subpass->view_mask) {
1225
u_foreach_bit(view_idx, subpass->view_mask) {
1226
for (uint32_t r = 0; r < rectCount; ++r) {
1227
const VkOffset2D offset = pRects[r].rect.offset;
1228
const VkExtent2D extent = pRects[r].rect.extent;
1229
blorp_clear_attachments(batch, binding_table,
1230
ISL_FORMAT_UNSUPPORTED, pass_att->samples,
1231
view_idx, 1,
1232
offset.x, offset.y,
1233
offset.x + extent.width,
1234
offset.y + extent.height,
1235
true, clear_color, false, 0.0f, 0, 0);
1236
}
1237
}
1238
return;
1239
}
1240
1241
for (uint32_t r = 0; r < rectCount; ++r) {
1242
const VkOffset2D offset = pRects[r].rect.offset;
1243
const VkExtent2D extent = pRects[r].rect.extent;
1244
assert(pRects[r].layerCount != VK_REMAINING_ARRAY_LAYERS);
1245
blorp_clear_attachments(batch, binding_table,
1246
ISL_FORMAT_UNSUPPORTED, pass_att->samples,
1247
pRects[r].baseArrayLayer,
1248
pRects[r].layerCount,
1249
offset.x, offset.y,
1250
offset.x + extent.width, offset.y + extent.height,
1251
true, clear_color, false, 0.0f, 0, 0);
1252
}
1253
}
1254
1255
static void
1256
clear_depth_stencil_attachment(struct anv_cmd_buffer *cmd_buffer,
1257
struct blorp_batch *batch,
1258
const VkClearAttachment *attachment,
1259
uint32_t rectCount, const VkClearRect *pRects)
1260
{
1261
static const union isl_color_value color_value = { .u32 = { 0, } };
1262
const struct anv_subpass *subpass = cmd_buffer->state.subpass;
1263
if (!subpass->depth_stencil_attachment)
1264
return;
1265
1266
const uint32_t att_idx = subpass->depth_stencil_attachment->attachment;
1267
assert(att_idx != VK_ATTACHMENT_UNUSED);
1268
struct anv_render_pass_attachment *pass_att =
1269
&cmd_buffer->state.pass->attachments[att_idx];
1270
1271
bool clear_depth = attachment->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT;
1272
bool clear_stencil = attachment->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT;
1273
1274
enum isl_format depth_format = ISL_FORMAT_UNSUPPORTED;
1275
if (clear_depth) {
1276
depth_format = anv_get_isl_format(&cmd_buffer->device->info,
1277
pass_att->format,
1278
VK_IMAGE_ASPECT_DEPTH_BIT,
1279
VK_IMAGE_TILING_OPTIMAL);
1280
}
1281
1282
uint32_t binding_table;
1283
VkResult result =
1284
binding_table_for_surface_state(cmd_buffer,
1285
cmd_buffer->state.null_surface_state,
1286
&binding_table);
1287
if (result != VK_SUCCESS)
1288
return;
1289
1290
/* If multiview is enabled we ignore baseArrayLayer and layerCount */
1291
if (subpass->view_mask) {
1292
u_foreach_bit(view_idx, subpass->view_mask) {
1293
for (uint32_t r = 0; r < rectCount; ++r) {
1294
const VkOffset2D offset = pRects[r].rect.offset;
1295
const VkExtent2D extent = pRects[r].rect.extent;
1296
VkClearDepthStencilValue value = attachment->clearValue.depthStencil;
1297
blorp_clear_attachments(batch, binding_table,
1298
depth_format, pass_att->samples,
1299
view_idx, 1,
1300
offset.x, offset.y,
1301
offset.x + extent.width,
1302
offset.y + extent.height,
1303
false, color_value,
1304
clear_depth, value.depth,
1305
clear_stencil ? 0xff : 0, value.stencil);
1306
}
1307
}
1308
return;
1309
}
1310
1311
for (uint32_t r = 0; r < rectCount; ++r) {
1312
const VkOffset2D offset = pRects[r].rect.offset;
1313
const VkExtent2D extent = pRects[r].rect.extent;
1314
VkClearDepthStencilValue value = attachment->clearValue.depthStencil;
1315
assert(pRects[r].layerCount != VK_REMAINING_ARRAY_LAYERS);
1316
blorp_clear_attachments(batch, binding_table,
1317
depth_format, pass_att->samples,
1318
pRects[r].baseArrayLayer,
1319
pRects[r].layerCount,
1320
offset.x, offset.y,
1321
offset.x + extent.width, offset.y + extent.height,
1322
false, color_value,
1323
clear_depth, value.depth,
1324
clear_stencil ? 0xff : 0, value.stencil);
1325
}
1326
}
1327
1328
void anv_CmdClearAttachments(
1329
VkCommandBuffer commandBuffer,
1330
uint32_t attachmentCount,
1331
const VkClearAttachment* pAttachments,
1332
uint32_t rectCount,
1333
const VkClearRect* pRects)
1334
{
1335
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1336
1337
/* Because this gets called within a render pass, we tell blorp not to
1338
* trash our depth and stencil buffers.
1339
*/
1340
struct blorp_batch batch;
1341
enum blorp_batch_flags flags = BLORP_BATCH_NO_EMIT_DEPTH_STENCIL;
1342
if (cmd_buffer->state.conditional_render_enabled) {
1343
anv_cmd_emit_conditional_render_predicate(cmd_buffer);
1344
flags |= BLORP_BATCH_PREDICATE_ENABLE;
1345
}
1346
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, flags);
1347
1348
for (uint32_t a = 0; a < attachmentCount; ++a) {
1349
if (pAttachments[a].aspectMask & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) {
1350
assert(pAttachments[a].aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
1351
clear_color_attachment(cmd_buffer, &batch,
1352
&pAttachments[a],
1353
rectCount, pRects);
1354
} else {
1355
clear_depth_stencil_attachment(cmd_buffer, &batch,
1356
&pAttachments[a],
1357
rectCount, pRects);
1358
}
1359
}
1360
1361
blorp_batch_finish(&batch);
1362
}
1363
1364
enum subpass_stage {
1365
SUBPASS_STAGE_LOAD,
1366
SUBPASS_STAGE_DRAW,
1367
SUBPASS_STAGE_RESOLVE,
1368
};
1369
1370
void
1371
anv_image_msaa_resolve(struct anv_cmd_buffer *cmd_buffer,
1372
const struct anv_image *src_image,
1373
enum isl_aux_usage src_aux_usage,
1374
uint32_t src_level, uint32_t src_base_layer,
1375
const struct anv_image *dst_image,
1376
enum isl_aux_usage dst_aux_usage,
1377
uint32_t dst_level, uint32_t dst_base_layer,
1378
VkImageAspectFlagBits aspect,
1379
uint32_t src_x, uint32_t src_y,
1380
uint32_t dst_x, uint32_t dst_y,
1381
uint32_t width, uint32_t height,
1382
uint32_t layer_count,
1383
enum blorp_filter filter)
1384
{
1385
struct blorp_batch batch;
1386
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
1387
1388
assert(src_image->type == VK_IMAGE_TYPE_2D);
1389
assert(src_image->samples > 1);
1390
assert(dst_image->type == VK_IMAGE_TYPE_2D);
1391
assert(dst_image->samples == 1);
1392
assert(src_image->n_planes == dst_image->n_planes);
1393
assert(!src_image->format->can_ycbcr);
1394
assert(!dst_image->format->can_ycbcr);
1395
1396
struct blorp_surf src_surf, dst_surf;
1397
get_blorp_surf_for_anv_image(cmd_buffer->device, src_image, aspect,
1398
VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1399
ANV_IMAGE_LAYOUT_EXPLICIT_AUX,
1400
src_aux_usage, &src_surf);
1401
if (src_aux_usage == ISL_AUX_USAGE_MCS) {
1402
src_surf.clear_color_addr = anv_to_blorp_address(
1403
anv_image_get_clear_color_addr(cmd_buffer->device, src_image,
1404
VK_IMAGE_ASPECT_COLOR_BIT));
1405
}
1406
get_blorp_surf_for_anv_image(cmd_buffer->device, dst_image, aspect,
1407
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1408
ANV_IMAGE_LAYOUT_EXPLICIT_AUX,
1409
dst_aux_usage, &dst_surf);
1410
anv_cmd_buffer_mark_image_written(cmd_buffer, dst_image,
1411
aspect, dst_aux_usage,
1412
dst_level, dst_base_layer, layer_count);
1413
1414
if (filter == BLORP_FILTER_NONE) {
1415
/* If no explicit filter is provided, then it's implied by the type of
1416
* the source image.
1417
*/
1418
if ((src_surf.surf->usage & ISL_SURF_USAGE_DEPTH_BIT) ||
1419
(src_surf.surf->usage & ISL_SURF_USAGE_STENCIL_BIT) ||
1420
isl_format_has_int_channel(src_surf.surf->format)) {
1421
filter = BLORP_FILTER_SAMPLE_0;
1422
} else {
1423
filter = BLORP_FILTER_AVERAGE;
1424
}
1425
}
1426
1427
for (uint32_t l = 0; l < layer_count; l++) {
1428
blorp_blit(&batch,
1429
&src_surf, src_level, src_base_layer + l,
1430
ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY,
1431
&dst_surf, dst_level, dst_base_layer + l,
1432
ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY,
1433
src_x, src_y, src_x + width, src_y + height,
1434
dst_x, dst_y, dst_x + width, dst_y + height,
1435
filter, false, false);
1436
}
1437
1438
blorp_batch_finish(&batch);
1439
}
1440
1441
static void
1442
resolve_image(struct anv_cmd_buffer *cmd_buffer,
1443
struct anv_image *src_image,
1444
VkImageLayout src_image_layout,
1445
struct anv_image *dst_image,
1446
VkImageLayout dst_image_layout,
1447
const VkImageResolve2KHR *region)
1448
{
1449
assert(region->srcSubresource.aspectMask == region->dstSubresource.aspectMask);
1450
assert(anv_get_layerCount(src_image, &region->srcSubresource) ==
1451
anv_get_layerCount(dst_image, &region->dstSubresource));
1452
1453
const uint32_t layer_count =
1454
anv_get_layerCount(dst_image, &region->dstSubresource);
1455
1456
anv_foreach_image_aspect_bit(aspect_bit, src_image,
1457
region->srcSubresource.aspectMask) {
1458
enum isl_aux_usage src_aux_usage =
1459
anv_layout_to_aux_usage(&cmd_buffer->device->info, src_image,
1460
(1 << aspect_bit),
1461
VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1462
src_image_layout);
1463
enum isl_aux_usage dst_aux_usage =
1464
anv_layout_to_aux_usage(&cmd_buffer->device->info, dst_image,
1465
(1 << aspect_bit),
1466
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1467
dst_image_layout);
1468
1469
anv_image_msaa_resolve(cmd_buffer,
1470
src_image, src_aux_usage,
1471
region->srcSubresource.mipLevel,
1472
region->srcSubresource.baseArrayLayer,
1473
dst_image, dst_aux_usage,
1474
region->dstSubresource.mipLevel,
1475
region->dstSubresource.baseArrayLayer,
1476
(1 << aspect_bit),
1477
region->srcOffset.x,
1478
region->srcOffset.y,
1479
region->dstOffset.x,
1480
region->dstOffset.y,
1481
region->extent.width,
1482
region->extent.height,
1483
layer_count, BLORP_FILTER_NONE);
1484
}
1485
}
1486
1487
void anv_CmdResolveImage2KHR(
1488
VkCommandBuffer commandBuffer,
1489
const VkResolveImageInfo2KHR* pResolveImageInfo)
1490
{
1491
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1492
ANV_FROM_HANDLE(anv_image, src_image, pResolveImageInfo->srcImage);
1493
ANV_FROM_HANDLE(anv_image, dst_image, pResolveImageInfo->dstImage);
1494
1495
assert(!src_image->format->can_ycbcr);
1496
1497
for (uint32_t r = 0; r < pResolveImageInfo->regionCount; r++) {
1498
resolve_image(cmd_buffer,
1499
src_image, pResolveImageInfo->srcImageLayout,
1500
dst_image, pResolveImageInfo->dstImageLayout,
1501
&pResolveImageInfo->pRegions[r]);
1502
}
1503
}
1504
1505
void
1506
anv_image_copy_to_shadow(struct anv_cmd_buffer *cmd_buffer,
1507
const struct anv_image *image,
1508
VkImageAspectFlagBits aspect,
1509
uint32_t base_level, uint32_t level_count,
1510
uint32_t base_layer, uint32_t layer_count)
1511
{
1512
struct blorp_batch batch;
1513
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
1514
1515
/* We don't know who touched the main surface last so flush a bunch of
1516
* caches to ensure we get good data.
1517
*/
1518
anv_add_pending_pipe_bits(cmd_buffer,
1519
ANV_PIPE_DEPTH_CACHE_FLUSH_BIT |
1520
ANV_PIPE_HDC_PIPELINE_FLUSH_BIT |
1521
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |
1522
ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT,
1523
"before copy_to_shadow");
1524
1525
struct blorp_surf surf;
1526
get_blorp_surf_for_anv_image(cmd_buffer->device,
1527
image, aspect,
1528
VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1529
VK_IMAGE_LAYOUT_GENERAL,
1530
ISL_AUX_USAGE_NONE, &surf);
1531
assert(surf.aux_usage == ISL_AUX_USAGE_NONE);
1532
1533
struct blorp_surf shadow_surf;
1534
get_blorp_surf_for_anv_shadow_image(cmd_buffer->device,
1535
image, aspect, &shadow_surf);
1536
1537
for (uint32_t l = 0; l < level_count; l++) {
1538
const uint32_t level = base_level + l;
1539
1540
const VkExtent3D extent = {
1541
.width = anv_minify(image->extent.width, level),
1542
.height = anv_minify(image->extent.height, level),
1543
.depth = anv_minify(image->extent.depth, level),
1544
};
1545
1546
if (image->type == VK_IMAGE_TYPE_3D)
1547
layer_count = extent.depth;
1548
1549
for (uint32_t a = 0; a < layer_count; a++) {
1550
const uint32_t layer = base_layer + a;
1551
1552
blorp_copy(&batch, &surf, level, layer,
1553
&shadow_surf, level, layer,
1554
0, 0, 0, 0, extent.width, extent.height);
1555
}
1556
}
1557
1558
/* We just wrote to the buffer with the render cache. Flush it. */
1559
anv_add_pending_pipe_bits(cmd_buffer,
1560
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT,
1561
"after copy_to_shadow");
1562
1563
blorp_batch_finish(&batch);
1564
}
1565
1566
void
1567
anv_image_clear_color(struct anv_cmd_buffer *cmd_buffer,
1568
const struct anv_image *image,
1569
VkImageAspectFlagBits aspect,
1570
enum isl_aux_usage aux_usage,
1571
enum isl_format format, struct isl_swizzle swizzle,
1572
uint32_t level, uint32_t base_layer, uint32_t layer_count,
1573
VkRect2D area, union isl_color_value clear_color)
1574
{
1575
assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
1576
1577
/* We don't support planar images with multisampling yet */
1578
assert(image->n_planes == 1);
1579
1580
struct blorp_batch batch;
1581
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
1582
1583
struct blorp_surf surf;
1584
get_blorp_surf_for_anv_image(cmd_buffer->device, image, aspect,
1585
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1586
ANV_IMAGE_LAYOUT_EXPLICIT_AUX,
1587
aux_usage, &surf);
1588
anv_cmd_buffer_mark_image_written(cmd_buffer, image, aspect, aux_usage,
1589
level, base_layer, layer_count);
1590
1591
blorp_clear(&batch, &surf, format, anv_swizzle_for_render(swizzle),
1592
level, base_layer, layer_count,
1593
area.offset.x, area.offset.y,
1594
area.offset.x + area.extent.width,
1595
area.offset.y + area.extent.height,
1596
clear_color, NULL);
1597
1598
blorp_batch_finish(&batch);
1599
}
1600
1601
void
1602
anv_image_clear_depth_stencil(struct anv_cmd_buffer *cmd_buffer,
1603
const struct anv_image *image,
1604
VkImageAspectFlags aspects,
1605
enum isl_aux_usage depth_aux_usage,
1606
uint32_t level,
1607
uint32_t base_layer, uint32_t layer_count,
1608
VkRect2D area,
1609
float depth_value, uint8_t stencil_value)
1610
{
1611
assert(image->aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
1612
VK_IMAGE_ASPECT_STENCIL_BIT));
1613
1614
struct blorp_batch batch;
1615
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
1616
1617
struct blorp_surf depth = {};
1618
if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
1619
get_blorp_surf_for_anv_image(cmd_buffer->device,
1620
image, VK_IMAGE_ASPECT_DEPTH_BIT,
1621
0, ANV_IMAGE_LAYOUT_EXPLICIT_AUX,
1622
depth_aux_usage, &depth);
1623
}
1624
1625
struct blorp_surf stencil = {};
1626
if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
1627
uint32_t plane = anv_image_aspect_to_plane(image->aspects,
1628
VK_IMAGE_ASPECT_STENCIL_BIT);
1629
get_blorp_surf_for_anv_image(cmd_buffer->device,
1630
image, VK_IMAGE_ASPECT_STENCIL_BIT,
1631
0, ANV_IMAGE_LAYOUT_EXPLICIT_AUX,
1632
image->planes[plane].aux_usage, &stencil);
1633
}
1634
1635
/* Blorp may choose to clear stencil using RGBA32_UINT for better
1636
* performance. If it does this, we need to flush it out of the depth
1637
* cache before rendering to it.
1638
*/
1639
anv_add_pending_pipe_bits(cmd_buffer,
1640
ANV_PIPE_DEPTH_CACHE_FLUSH_BIT |
1641
ANV_PIPE_END_OF_PIPE_SYNC_BIT,
1642
"before clear DS");
1643
1644
blorp_clear_depth_stencil(&batch, &depth, &stencil,
1645
level, base_layer, layer_count,
1646
area.offset.x, area.offset.y,
1647
area.offset.x + area.extent.width,
1648
area.offset.y + area.extent.height,
1649
aspects & VK_IMAGE_ASPECT_DEPTH_BIT,
1650
depth_value,
1651
(aspects & VK_IMAGE_ASPECT_STENCIL_BIT) ? 0xff : 0,
1652
stencil_value);
1653
1654
/* Blorp may choose to clear stencil using RGBA32_UINT for better
1655
* performance. If it does this, we need to flush it out of the render
1656
* cache before someone starts trying to do stencil on it.
1657
*/
1658
anv_add_pending_pipe_bits(cmd_buffer,
1659
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |
1660
ANV_PIPE_TILE_CACHE_FLUSH_BIT |
1661
ANV_PIPE_END_OF_PIPE_SYNC_BIT,
1662
"after clear DS");
1663
1664
struct blorp_surf stencil_shadow;
1665
if ((aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
1666
get_blorp_surf_for_anv_shadow_image(cmd_buffer->device, image,
1667
VK_IMAGE_ASPECT_STENCIL_BIT,
1668
&stencil_shadow)) {
1669
union isl_color_value stencil_color = {
1670
.u32 = { stencil_value },
1671
};
1672
blorp_clear(&batch, &stencil_shadow,
1673
ISL_FORMAT_R8_UINT, ISL_SWIZZLE_IDENTITY,
1674
level, base_layer, layer_count,
1675
area.offset.x, area.offset.y,
1676
area.offset.x + area.extent.width,
1677
area.offset.y + area.extent.height,
1678
stencil_color, NULL);
1679
}
1680
1681
blorp_batch_finish(&batch);
1682
}
1683
1684
void
1685
anv_image_hiz_op(struct anv_cmd_buffer *cmd_buffer,
1686
const struct anv_image *image,
1687
VkImageAspectFlagBits aspect, uint32_t level,
1688
uint32_t base_layer, uint32_t layer_count,
1689
enum isl_aux_op hiz_op)
1690
{
1691
assert(aspect == VK_IMAGE_ASPECT_DEPTH_BIT);
1692
assert(base_layer + layer_count <= anv_image_aux_layers(image, aspect, level));
1693
uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);
1694
assert(plane == 0);
1695
1696
struct blorp_batch batch;
1697
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
1698
1699
struct blorp_surf surf;
1700
get_blorp_surf_for_anv_image(cmd_buffer->device,
1701
image, VK_IMAGE_ASPECT_DEPTH_BIT,
1702
0, ANV_IMAGE_LAYOUT_EXPLICIT_AUX,
1703
image->planes[plane].aux_usage, &surf);
1704
1705
blorp_hiz_op(&batch, &surf, level, base_layer, layer_count, hiz_op);
1706
1707
blorp_batch_finish(&batch);
1708
}
1709
1710
void
1711
anv_image_hiz_clear(struct anv_cmd_buffer *cmd_buffer,
1712
const struct anv_image *image,
1713
VkImageAspectFlags aspects,
1714
uint32_t level,
1715
uint32_t base_layer, uint32_t layer_count,
1716
VkRect2D area, uint8_t stencil_value)
1717
{
1718
assert(image->aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
1719
VK_IMAGE_ASPECT_STENCIL_BIT));
1720
1721
struct blorp_batch batch;
1722
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
1723
1724
struct blorp_surf depth = {};
1725
if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
1726
uint32_t plane = anv_image_aspect_to_plane(image->aspects,
1727
VK_IMAGE_ASPECT_DEPTH_BIT);
1728
assert(base_layer + layer_count <=
1729
anv_image_aux_layers(image, VK_IMAGE_ASPECT_DEPTH_BIT, level));
1730
get_blorp_surf_for_anv_image(cmd_buffer->device,
1731
image, VK_IMAGE_ASPECT_DEPTH_BIT,
1732
0, ANV_IMAGE_LAYOUT_EXPLICIT_AUX,
1733
image->planes[plane].aux_usage, &depth);
1734
}
1735
1736
struct blorp_surf stencil = {};
1737
if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
1738
uint32_t plane = anv_image_aspect_to_plane(image->aspects,
1739
VK_IMAGE_ASPECT_STENCIL_BIT);
1740
get_blorp_surf_for_anv_image(cmd_buffer->device,
1741
image, VK_IMAGE_ASPECT_STENCIL_BIT,
1742
0, ANV_IMAGE_LAYOUT_EXPLICIT_AUX,
1743
image->planes[plane].aux_usage, &stencil);
1744
}
1745
1746
/* From the Sky Lake PRM Volume 7, "Depth Buffer Clear":
1747
*
1748
* "The following is required when performing a depth buffer clear with
1749
* using the WM_STATE or 3DSTATE_WM:
1750
*
1751
* * If other rendering operations have preceded this clear, a
1752
* PIPE_CONTROL with depth cache flush enabled, Depth Stall bit
1753
* enabled must be issued before the rectangle primitive used for
1754
* the depth buffer clear operation.
1755
* * [...]"
1756
*
1757
* Even though the PRM only says that this is required if using 3DSTATE_WM
1758
* and a 3DPRIMITIVE, the GPU appears to also need this to avoid occasional
1759
* hangs when doing a clear with WM_HZ_OP.
1760
*/
1761
anv_add_pending_pipe_bits(cmd_buffer,
1762
ANV_PIPE_DEPTH_CACHE_FLUSH_BIT |
1763
ANV_PIPE_DEPTH_STALL_BIT,
1764
"before clear hiz");
1765
1766
blorp_hiz_clear_depth_stencil(&batch, &depth, &stencil,
1767
level, base_layer, layer_count,
1768
area.offset.x, area.offset.y,
1769
area.offset.x + area.extent.width,
1770
area.offset.y + area.extent.height,
1771
aspects & VK_IMAGE_ASPECT_DEPTH_BIT,
1772
ANV_HZ_FC_VAL,
1773
aspects & VK_IMAGE_ASPECT_STENCIL_BIT,
1774
stencil_value);
1775
1776
blorp_batch_finish(&batch);
1777
1778
/* From the SKL PRM, Depth Buffer Clear:
1779
*
1780
* "Depth Buffer Clear Workaround
1781
*
1782
* Depth buffer clear pass using any of the methods (WM_STATE,
1783
* 3DSTATE_WM or 3DSTATE_WM_HZ_OP) must be followed by a PIPE_CONTROL
1784
* command with DEPTH_STALL bit and Depth FLUSH bits “set” before
1785
* starting to render. DepthStall and DepthFlush are not needed between
1786
* consecutive depth clear passes nor is it required if the depth-clear
1787
* pass was done with “full_surf_clear” bit set in the
1788
* 3DSTATE_WM_HZ_OP."
1789
*
1790
* Even though the PRM provides a bunch of conditions under which this is
1791
* supposedly unnecessary, we choose to perform the flush unconditionally
1792
* just to be safe.
1793
*/
1794
anv_add_pending_pipe_bits(cmd_buffer,
1795
ANV_PIPE_DEPTH_CACHE_FLUSH_BIT |
1796
ANV_PIPE_DEPTH_STALL_BIT,
1797
"after clear hiz");
1798
}
1799
1800
void
1801
anv_image_mcs_op(struct anv_cmd_buffer *cmd_buffer,
1802
const struct anv_image *image,
1803
enum isl_format format, struct isl_swizzle swizzle,
1804
VkImageAspectFlagBits aspect,
1805
uint32_t base_layer, uint32_t layer_count,
1806
enum isl_aux_op mcs_op, union isl_color_value *clear_value,
1807
bool predicate)
1808
{
1809
assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
1810
assert(image->samples > 1);
1811
assert(base_layer + layer_count <= anv_image_aux_layers(image, aspect, 0));
1812
1813
/* Multisampling with multi-planar formats is not supported */
1814
assert(image->n_planes == 1);
1815
1816
struct blorp_batch batch;
1817
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer,
1818
BLORP_BATCH_PREDICATE_ENABLE * predicate +
1819
BLORP_BATCH_NO_UPDATE_CLEAR_COLOR * !clear_value);
1820
1821
struct blorp_surf surf;
1822
get_blorp_surf_for_anv_image(cmd_buffer->device, image, aspect,
1823
0, ANV_IMAGE_LAYOUT_EXPLICIT_AUX,
1824
ISL_AUX_USAGE_MCS, &surf);
1825
1826
/* Blorp will store the clear color for us if we provide the clear color
1827
* address and we are doing a fast clear. So we save the clear value into
1828
* the blorp surface.
1829
*/
1830
if (clear_value)
1831
surf.clear_color = *clear_value;
1832
1833
/* From the Sky Lake PRM Vol. 7, "Render Target Fast Clear":
1834
*
1835
* "After Render target fast clear, pipe-control with color cache
1836
* write-flush must be issued before sending any DRAW commands on
1837
* that render target."
1838
*
1839
* This comment is a bit cryptic and doesn't really tell you what's going
1840
* or what's really needed. It appears that fast clear ops are not
1841
* properly synchronized with other drawing. This means that we cannot
1842
* have a fast clear operation in the pipe at the same time as other
1843
* regular drawing operations. We need to use a PIPE_CONTROL to ensure
1844
* that the contents of the previous draw hit the render target before we
1845
* resolve and then use a second PIPE_CONTROL after the resolve to ensure
1846
* that it is completed before any additional drawing occurs.
1847
*/
1848
anv_add_pending_pipe_bits(cmd_buffer,
1849
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |
1850
ANV_PIPE_TILE_CACHE_FLUSH_BIT |
1851
ANV_PIPE_END_OF_PIPE_SYNC_BIT,
1852
"before fast clear mcs");
1853
1854
switch (mcs_op) {
1855
case ISL_AUX_OP_FAST_CLEAR:
1856
blorp_fast_clear(&batch, &surf, format, swizzle,
1857
0, base_layer, layer_count,
1858
0, 0, image->extent.width, image->extent.height);
1859
break;
1860
case ISL_AUX_OP_PARTIAL_RESOLVE:
1861
blorp_mcs_partial_resolve(&batch, &surf, format,
1862
base_layer, layer_count);
1863
break;
1864
case ISL_AUX_OP_FULL_RESOLVE:
1865
case ISL_AUX_OP_AMBIGUATE:
1866
default:
1867
unreachable("Unsupported MCS operation");
1868
}
1869
1870
anv_add_pending_pipe_bits(cmd_buffer,
1871
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |
1872
ANV_PIPE_END_OF_PIPE_SYNC_BIT,
1873
"after fast clear mcs");
1874
1875
blorp_batch_finish(&batch);
1876
}
1877
1878
void
1879
anv_image_ccs_op(struct anv_cmd_buffer *cmd_buffer,
1880
const struct anv_image *image,
1881
enum isl_format format, struct isl_swizzle swizzle,
1882
VkImageAspectFlagBits aspect, uint32_t level,
1883
uint32_t base_layer, uint32_t layer_count,
1884
enum isl_aux_op ccs_op, union isl_color_value *clear_value,
1885
bool predicate)
1886
{
1887
assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);
1888
assert(image->samples == 1);
1889
assert(level < anv_image_aux_levels(image, aspect));
1890
/* Multi-LOD YcBcR is not allowed */
1891
assert(image->n_planes == 1 || level == 0);
1892
assert(base_layer + layer_count <=
1893
anv_image_aux_layers(image, aspect, level));
1894
1895
uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);
1896
uint32_t width_div = image->format->planes[plane].denominator_scales[0];
1897
uint32_t height_div = image->format->planes[plane].denominator_scales[1];
1898
uint32_t level_width = anv_minify(image->extent.width, level) / width_div;
1899
uint32_t level_height = anv_minify(image->extent.height, level) / height_div;
1900
1901
struct blorp_batch batch;
1902
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer,
1903
BLORP_BATCH_PREDICATE_ENABLE * predicate +
1904
BLORP_BATCH_NO_UPDATE_CLEAR_COLOR * !clear_value);
1905
1906
struct blorp_surf surf;
1907
get_blorp_surf_for_anv_image(cmd_buffer->device, image, aspect,
1908
0, ANV_IMAGE_LAYOUT_EXPLICIT_AUX,
1909
image->planes[plane].aux_usage,
1910
&surf);
1911
1912
/* Blorp will store the clear color for us if we provide the clear color
1913
* address and we are doing a fast clear. So we save the clear value into
1914
* the blorp surface.
1915
*/
1916
if (clear_value)
1917
surf.clear_color = *clear_value;
1918
1919
/* From the Sky Lake PRM Vol. 7, "Render Target Fast Clear":
1920
*
1921
* "After Render target fast clear, pipe-control with color cache
1922
* write-flush must be issued before sending any DRAW commands on
1923
* that render target."
1924
*
1925
* This comment is a bit cryptic and doesn't really tell you what's going
1926
* or what's really needed. It appears that fast clear ops are not
1927
* properly synchronized with other drawing. This means that we cannot
1928
* have a fast clear operation in the pipe at the same time as other
1929
* regular drawing operations. We need to use a PIPE_CONTROL to ensure
1930
* that the contents of the previous draw hit the render target before we
1931
* resolve and then use a second PIPE_CONTROL after the resolve to ensure
1932
* that it is completed before any additional drawing occurs.
1933
*/
1934
anv_add_pending_pipe_bits(cmd_buffer,
1935
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |
1936
ANV_PIPE_TILE_CACHE_FLUSH_BIT |
1937
ANV_PIPE_END_OF_PIPE_SYNC_BIT,
1938
"before fast clear ccs");
1939
1940
switch (ccs_op) {
1941
case ISL_AUX_OP_FAST_CLEAR:
1942
blorp_fast_clear(&batch, &surf, format, swizzle,
1943
level, base_layer, layer_count,
1944
0, 0, level_width, level_height);
1945
break;
1946
case ISL_AUX_OP_FULL_RESOLVE:
1947
case ISL_AUX_OP_PARTIAL_RESOLVE:
1948
blorp_ccs_resolve(&batch, &surf, level, base_layer, layer_count,
1949
format, ccs_op);
1950
break;
1951
case ISL_AUX_OP_AMBIGUATE:
1952
for (uint32_t a = 0; a < layer_count; a++) {
1953
const uint32_t layer = base_layer + a;
1954
blorp_ccs_ambiguate(&batch, &surf, level, layer);
1955
}
1956
break;
1957
default:
1958
unreachable("Unsupported CCS operation");
1959
}
1960
1961
anv_add_pending_pipe_bits(cmd_buffer,
1962
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |
1963
ANV_PIPE_END_OF_PIPE_SYNC_BIT,
1964
"after fast clear ccs");
1965
1966
blorp_batch_finish(&batch);
1967
}
1968
1969