2 * Copyright © 2016 Intel Corporation
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:
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 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
24 #include "anv_private.h"
27 lookup_blorp_shader(struct blorp_context
*blorp
,
28 const void *key
, uint32_t key_size
,
29 uint32_t *kernel_out
, void *prog_data_out
)
31 struct anv_device
*device
= blorp
->driver_ctx
;
33 /* The blorp cache must be a real cache */
34 assert(device
->blorp_shader_cache
.cache
);
36 struct anv_shader_bin
*bin
=
37 anv_pipeline_cache_search(&device
->blorp_shader_cache
, key
, key_size
);
41 /* The cache already has a reference and it's not going anywhere so there
42 * is no need to hold a second reference.
44 anv_shader_bin_unref(device
, bin
);
46 *kernel_out
= bin
->kernel
.offset
;
47 *(const struct brw_stage_prog_data
**)prog_data_out
= bin
->prog_data
;
53 upload_blorp_shader(struct blorp_context
*blorp
,
54 const void *key
, uint32_t key_size
,
55 const void *kernel
, uint32_t kernel_size
,
56 const struct brw_stage_prog_data
*prog_data
,
57 uint32_t prog_data_size
,
58 uint32_t *kernel_out
, void *prog_data_out
)
60 struct anv_device
*device
= blorp
->driver_ctx
;
62 /* The blorp cache must be a real cache */
63 assert(device
->blorp_shader_cache
.cache
);
65 struct anv_pipeline_bind_map bind_map
= {
70 struct anv_shader_bin
*bin
=
71 anv_pipeline_cache_upload_kernel(&device
->blorp_shader_cache
,
72 key
, key_size
, kernel
, kernel_size
,
73 prog_data
, prog_data_size
, &bind_map
);
75 /* The cache already has a reference and it's not going anywhere so there
76 * is no need to hold a second reference.
78 anv_shader_bin_unref(device
, bin
);
80 *kernel_out
= bin
->kernel
.offset
;
81 *(const struct brw_stage_prog_data
**)prog_data_out
= bin
->prog_data
;
85 anv_device_init_blorp(struct anv_device
*device
)
87 anv_pipeline_cache_init(&device
->blorp_shader_cache
, device
, true);
88 blorp_init(&device
->blorp
, device
, &device
->isl_dev
);
89 device
->blorp
.compiler
= device
->instance
->physicalDevice
.compiler
;
90 device
->blorp
.mocs
.tex
= device
->default_mocs
;
91 device
->blorp
.mocs
.rb
= device
->default_mocs
;
92 device
->blorp
.mocs
.vb
= device
->default_mocs
;
93 device
->blorp
.lookup_shader
= lookup_blorp_shader
;
94 device
->blorp
.upload_shader
= upload_blorp_shader
;
95 switch (device
->info
.gen
) {
97 if (device
->info
.is_haswell
) {
98 device
->blorp
.exec
= gen75_blorp_exec
;
100 device
->blorp
.exec
= gen7_blorp_exec
;
104 device
->blorp
.exec
= gen8_blorp_exec
;
107 device
->blorp
.exec
= gen9_blorp_exec
;
110 unreachable("Unknown hardware generation");
115 anv_device_finish_blorp(struct anv_device
*device
)
117 blorp_finish(&device
->blorp
);
118 anv_pipeline_cache_finish(&device
->blorp_shader_cache
);
122 get_blorp_surf_for_anv_buffer(struct anv_device
*device
,
123 struct anv_buffer
*buffer
, uint64_t offset
,
124 uint32_t width
, uint32_t height
,
125 uint32_t row_pitch
, enum isl_format format
,
126 struct blorp_surf
*blorp_surf
,
127 struct isl_surf
*isl_surf
)
129 const struct isl_format_layout
*fmtl
=
130 isl_format_get_layout(format
);
132 /* ASTC is the only format which doesn't support linear layouts.
133 * Create an equivalently sized surface with ISL to get around this.
135 if (fmtl
->txc
== ISL_TXC_ASTC
) {
136 /* Use an equivalently sized format */
137 format
= ISL_FORMAT_R32G32B32A32_UINT
;
138 assert(fmtl
->bpb
== isl_format_get_layout(format
)->bpb
);
140 /* Shrink the dimensions for the new format */
141 width
= DIV_ROUND_UP(width
, fmtl
->bw
);
142 height
= DIV_ROUND_UP(height
, fmtl
->bh
);
145 *blorp_surf
= (struct blorp_surf
) {
148 .buffer
= buffer
->bo
,
149 .offset
= buffer
->offset
+ offset
,
153 isl_surf_init(&device
->isl_dev
, isl_surf
,
154 .dim
= ISL_SURF_DIM_2D
,
162 .min_pitch
= row_pitch
,
163 .usage
= ISL_SURF_USAGE_TEXTURE_BIT
|
164 ISL_SURF_USAGE_RENDER_TARGET_BIT
,
165 .tiling_flags
= ISL_TILING_LINEAR_BIT
);
166 assert(isl_surf
->row_pitch
== row_pitch
);
170 get_blorp_surf_for_anv_image(const struct anv_image
*image
,
171 VkImageAspectFlags aspect
,
172 enum isl_aux_usage aux_usage
,
173 struct blorp_surf
*blorp_surf
)
175 if (aspect
== VK_IMAGE_ASPECT_STENCIL_BIT
)
176 aux_usage
= ISL_AUX_USAGE_NONE
;
178 const struct anv_surface
*surface
=
179 anv_image_get_surface_for_aspect_mask(image
, aspect
);
181 *blorp_surf
= (struct blorp_surf
) {
182 .surf
= &surface
->isl
,
185 .offset
= image
->offset
+ surface
->offset
,
189 if (aux_usage
!= ISL_AUX_USAGE_NONE
) {
190 blorp_surf
->aux_surf
= &image
->aux_surface
.isl
,
191 blorp_surf
->aux_addr
= (struct blorp_address
) {
193 .offset
= image
->offset
+ image
->aux_surface
.offset
,
195 blorp_surf
->aux_usage
= aux_usage
;
199 void anv_CmdCopyImage(
200 VkCommandBuffer commandBuffer
,
202 VkImageLayout srcImageLayout
,
204 VkImageLayout dstImageLayout
,
205 uint32_t regionCount
,
206 const VkImageCopy
* pRegions
)
208 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
209 ANV_FROM_HANDLE(anv_image
, src_image
, srcImage
);
210 ANV_FROM_HANDLE(anv_image
, dst_image
, dstImage
);
212 struct blorp_batch batch
;
213 blorp_batch_init(&cmd_buffer
->device
->blorp
, &batch
, cmd_buffer
, 0);
215 for (unsigned r
= 0; r
< regionCount
; r
++) {
216 VkOffset3D srcOffset
=
217 anv_sanitize_image_offset(src_image
->type
, pRegions
[r
].srcOffset
);
218 VkOffset3D dstOffset
=
219 anv_sanitize_image_offset(dst_image
->type
, pRegions
[r
].dstOffset
);
221 anv_sanitize_image_extent(src_image
->type
, pRegions
[r
].extent
);
223 unsigned dst_base_layer
, layer_count
;
224 if (dst_image
->type
== VK_IMAGE_TYPE_3D
) {
225 dst_base_layer
= pRegions
[r
].dstOffset
.z
;
226 layer_count
= pRegions
[r
].extent
.depth
;
228 dst_base_layer
= pRegions
[r
].dstSubresource
.baseArrayLayer
;
229 layer_count
= pRegions
[r
].dstSubresource
.layerCount
;
232 unsigned src_base_layer
;
233 if (src_image
->type
== VK_IMAGE_TYPE_3D
) {
234 src_base_layer
= pRegions
[r
].srcOffset
.z
;
236 src_base_layer
= pRegions
[r
].srcSubresource
.baseArrayLayer
;
237 assert(pRegions
[r
].srcSubresource
.layerCount
== layer_count
);
240 assert(pRegions
[r
].srcSubresource
.aspectMask
==
241 pRegions
[r
].dstSubresource
.aspectMask
);
244 for_each_bit(a
, pRegions
[r
].dstSubresource
.aspectMask
) {
245 VkImageAspectFlagBits aspect
= (1 << a
);
247 struct blorp_surf src_surf
, dst_surf
;
248 get_blorp_surf_for_anv_image(src_image
, aspect
, src_image
->aux_usage
,
250 get_blorp_surf_for_anv_image(dst_image
, aspect
, dst_image
->aux_usage
,
253 for (unsigned i
= 0; i
< layer_count
; i
++) {
254 blorp_copy(&batch
, &src_surf
, pRegions
[r
].srcSubresource
.mipLevel
,
256 &dst_surf
, pRegions
[r
].dstSubresource
.mipLevel
,
258 srcOffset
.x
, srcOffset
.y
,
259 dstOffset
.x
, dstOffset
.y
,
260 extent
.width
, extent
.height
);
265 blorp_batch_finish(&batch
);
269 copy_buffer_to_image(struct anv_cmd_buffer
*cmd_buffer
,
270 struct anv_buffer
*anv_buffer
,
271 struct anv_image
*anv_image
,
272 uint32_t regionCount
,
273 const VkBufferImageCopy
* pRegions
,
274 bool buffer_to_image
)
276 struct blorp_batch batch
;
277 blorp_batch_init(&cmd_buffer
->device
->blorp
, &batch
, cmd_buffer
, 0);
280 struct blorp_surf surf
;
283 } image
, buffer
, *src
, *dst
;
286 buffer
.offset
= (VkOffset3D
) { 0, 0, 0 };
288 if (buffer_to_image
) {
296 for (unsigned r
= 0; r
< regionCount
; r
++) {
297 const VkImageAspectFlags aspect
= pRegions
[r
].imageSubresource
.aspectMask
;
299 get_blorp_surf_for_anv_image(anv_image
, aspect
, anv_image
->aux_usage
,
302 anv_sanitize_image_offset(anv_image
->type
, pRegions
[r
].imageOffset
);
303 image
.level
= pRegions
[r
].imageSubresource
.mipLevel
;
306 anv_sanitize_image_extent(anv_image
->type
, pRegions
[r
].imageExtent
);
307 if (anv_image
->type
!= VK_IMAGE_TYPE_3D
) {
308 image
.offset
.z
= pRegions
[r
].imageSubresource
.baseArrayLayer
;
309 extent
.depth
= pRegions
[r
].imageSubresource
.layerCount
;
312 const enum isl_format buffer_format
=
313 anv_get_isl_format(&cmd_buffer
->device
->info
, anv_image
->vk_format
,
314 aspect
, VK_IMAGE_TILING_LINEAR
);
316 const VkExtent3D bufferImageExtent
= {
317 .width
= pRegions
[r
].bufferRowLength
?
318 pRegions
[r
].bufferRowLength
: extent
.width
,
319 .height
= pRegions
[r
].bufferImageHeight
?
320 pRegions
[r
].bufferImageHeight
: extent
.height
,
323 const struct isl_format_layout
*buffer_fmtl
=
324 isl_format_get_layout(buffer_format
);
326 const uint32_t buffer_row_pitch
=
327 DIV_ROUND_UP(bufferImageExtent
.width
, buffer_fmtl
->bw
) *
328 (buffer_fmtl
->bpb
/ 8);
330 const uint32_t buffer_layer_stride
=
331 DIV_ROUND_UP(bufferImageExtent
.height
, buffer_fmtl
->bh
) *
334 struct isl_surf buffer_isl_surf
;
335 get_blorp_surf_for_anv_buffer(cmd_buffer
->device
,
336 anv_buffer
, pRegions
[r
].bufferOffset
,
337 extent
.width
, extent
.height
,
338 buffer_row_pitch
, buffer_format
,
339 &buffer
.surf
, &buffer_isl_surf
);
341 for (unsigned z
= 0; z
< extent
.depth
; z
++) {
342 blorp_copy(&batch
, &src
->surf
, src
->level
, src
->offset
.z
,
343 &dst
->surf
, dst
->level
, dst
->offset
.z
,
344 src
->offset
.x
, src
->offset
.y
, dst
->offset
.x
, dst
->offset
.y
,
345 extent
.width
, extent
.height
);
348 buffer
.surf
.addr
.offset
+= buffer_layer_stride
;
352 blorp_batch_finish(&batch
);
355 void anv_CmdCopyBufferToImage(
356 VkCommandBuffer commandBuffer
,
359 VkImageLayout dstImageLayout
,
360 uint32_t regionCount
,
361 const VkBufferImageCopy
* pRegions
)
363 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
364 ANV_FROM_HANDLE(anv_buffer
, src_buffer
, srcBuffer
);
365 ANV_FROM_HANDLE(anv_image
, dst_image
, dstImage
);
367 copy_buffer_to_image(cmd_buffer
, src_buffer
, dst_image
,
368 regionCount
, pRegions
, true);
371 void anv_CmdCopyImageToBuffer(
372 VkCommandBuffer commandBuffer
,
374 VkImageLayout srcImageLayout
,
376 uint32_t regionCount
,
377 const VkBufferImageCopy
* pRegions
)
379 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
380 ANV_FROM_HANDLE(anv_image
, src_image
, srcImage
);
381 ANV_FROM_HANDLE(anv_buffer
, dst_buffer
, dstBuffer
);
383 copy_buffer_to_image(cmd_buffer
, dst_buffer
, src_image
,
384 regionCount
, pRegions
, false);
388 flip_coords(unsigned *src0
, unsigned *src1
, unsigned *dst0
, unsigned *dst1
)
392 unsigned tmp
= *src0
;
399 unsigned tmp
= *dst0
;
408 void anv_CmdBlitImage(
409 VkCommandBuffer commandBuffer
,
411 VkImageLayout srcImageLayout
,
413 VkImageLayout dstImageLayout
,
414 uint32_t regionCount
,
415 const VkImageBlit
* pRegions
,
419 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
420 ANV_FROM_HANDLE(anv_image
, src_image
, srcImage
);
421 ANV_FROM_HANDLE(anv_image
, dst_image
, dstImage
);
423 struct blorp_surf src
, dst
;
427 case VK_FILTER_NEAREST
:
428 gl_filter
= 0x2600; /* GL_NEAREST */
430 case VK_FILTER_LINEAR
:
431 gl_filter
= 0x2601; /* GL_LINEAR */
434 unreachable("Invalid filter");
437 struct blorp_batch batch
;
438 blorp_batch_init(&cmd_buffer
->device
->blorp
, &batch
, cmd_buffer
, 0);
440 for (unsigned r
= 0; r
< regionCount
; r
++) {
441 const VkImageSubresourceLayers
*src_res
= &pRegions
[r
].srcSubresource
;
442 const VkImageSubresourceLayers
*dst_res
= &pRegions
[r
].dstSubresource
;
444 get_blorp_surf_for_anv_image(src_image
, src_res
->aspectMask
,
445 src_image
->aux_usage
, &src
);
446 get_blorp_surf_for_anv_image(dst_image
, dst_res
->aspectMask
,
447 dst_image
->aux_usage
, &dst
);
449 struct anv_format src_format
=
450 anv_get_format(&cmd_buffer
->device
->info
, src_image
->vk_format
,
451 src_res
->aspectMask
, src_image
->tiling
);
452 struct anv_format dst_format
=
453 anv_get_format(&cmd_buffer
->device
->info
, dst_image
->vk_format
,
454 dst_res
->aspectMask
, dst_image
->tiling
);
456 unsigned dst_start
, dst_end
;
457 if (dst_image
->type
== VK_IMAGE_TYPE_3D
) {
458 assert(dst_res
->baseArrayLayer
== 0);
459 dst_start
= pRegions
[r
].dstOffsets
[0].z
;
460 dst_end
= pRegions
[r
].dstOffsets
[1].z
;
462 dst_start
= dst_res
->baseArrayLayer
;
463 dst_end
= dst_start
+ dst_res
->layerCount
;
466 unsigned src_start
, src_end
;
467 if (src_image
->type
== VK_IMAGE_TYPE_3D
) {
468 assert(src_res
->baseArrayLayer
== 0);
469 src_start
= pRegions
[r
].srcOffsets
[0].z
;
470 src_end
= pRegions
[r
].srcOffsets
[1].z
;
472 src_start
= src_res
->baseArrayLayer
;
473 src_end
= src_start
+ src_res
->layerCount
;
476 bool flip_z
= flip_coords(&src_start
, &src_end
, &dst_start
, &dst_end
);
477 float src_z_step
= (float)(src_end
+ 1 - src_start
) /
478 (float)(dst_end
+ 1 - dst_start
);
485 unsigned src_x0
= pRegions
[r
].srcOffsets
[0].x
;
486 unsigned src_x1
= pRegions
[r
].srcOffsets
[1].x
;
487 unsigned dst_x0
= pRegions
[r
].dstOffsets
[0].x
;
488 unsigned dst_x1
= pRegions
[r
].dstOffsets
[1].x
;
489 bool flip_x
= flip_coords(&src_x0
, &src_x1
, &dst_x0
, &dst_x1
);
491 unsigned src_y0
= pRegions
[r
].srcOffsets
[0].y
;
492 unsigned src_y1
= pRegions
[r
].srcOffsets
[1].y
;
493 unsigned dst_y0
= pRegions
[r
].dstOffsets
[0].y
;
494 unsigned dst_y1
= pRegions
[r
].dstOffsets
[1].y
;
495 bool flip_y
= flip_coords(&src_y0
, &src_y1
, &dst_y0
, &dst_y1
);
497 const unsigned num_layers
= dst_end
- dst_start
;
498 for (unsigned i
= 0; i
< num_layers
; i
++) {
499 unsigned dst_z
= dst_start
+ i
;
500 unsigned src_z
= src_start
+ i
* src_z_step
;
502 blorp_blit(&batch
, &src
, src_res
->mipLevel
, src_z
,
503 src_format
.isl_format
, src_format
.swizzle
,
504 &dst
, dst_res
->mipLevel
, dst_z
,
505 dst_format
.isl_format
, dst_format
.swizzle
,
506 src_x0
, src_y0
, src_x1
, src_y1
,
507 dst_x0
, dst_y0
, dst_x1
, dst_y1
,
508 gl_filter
, flip_x
, flip_y
);
513 blorp_batch_finish(&batch
);
516 static enum isl_format
517 isl_format_for_size(unsigned size_B
)
520 case 1: return ISL_FORMAT_R8_UINT
;
521 case 2: return ISL_FORMAT_R8G8_UINT
;
522 case 4: return ISL_FORMAT_R8G8B8A8_UINT
;
523 case 8: return ISL_FORMAT_R16G16B16A16_UINT
;
524 case 16: return ISL_FORMAT_R32G32B32A32_UINT
;
526 unreachable("Not a power-of-two format size");
531 do_buffer_copy(struct blorp_batch
*batch
,
532 struct anv_bo
*src
, uint64_t src_offset
,
533 struct anv_bo
*dst
, uint64_t dst_offset
,
534 int width
, int height
, int block_size
)
536 struct anv_device
*device
= batch
->blorp
->driver_ctx
;
538 /* The actual format we pick doesn't matter as blorp will throw it away.
539 * The only thing that actually matters is the size.
541 enum isl_format format
= isl_format_for_size(block_size
);
543 struct isl_surf surf
;
544 isl_surf_init(&device
->isl_dev
, &surf
,
545 .dim
= ISL_SURF_DIM_2D
,
553 .usage
= ISL_SURF_USAGE_TEXTURE_BIT
|
554 ISL_SURF_USAGE_RENDER_TARGET_BIT
,
555 .tiling_flags
= ISL_TILING_LINEAR_BIT
);
556 assert(surf
.row_pitch
== width
* block_size
);
558 struct blorp_surf src_blorp_surf
= {
562 .offset
= src_offset
,
566 struct blorp_surf dst_blorp_surf
= {
570 .offset
= dst_offset
,
574 blorp_copy(batch
, &src_blorp_surf
, 0, 0, &dst_blorp_surf
, 0, 0,
575 0, 0, 0, 0, width
, height
);
579 * Returns the greatest common divisor of a and b that is a power of two.
581 static inline uint64_t
582 gcd_pow2_u64(uint64_t a
, uint64_t b
)
584 assert(a
> 0 || b
> 0);
586 unsigned a_log2
= ffsll(a
) - 1;
587 unsigned b_log2
= ffsll(b
) - 1;
589 /* If either a or b is 0, then a_log2 or b_log2 till be UINT_MAX in which
590 * case, the MIN2() will take the other one. If both are 0 then we will
591 * hit the assert above.
593 return 1 << MIN2(a_log2
, b_log2
);
596 /* This is maximum possible width/height our HW can handle */
597 #define MAX_SURFACE_DIM (1ull << 14)
599 void anv_CmdCopyBuffer(
600 VkCommandBuffer commandBuffer
,
603 uint32_t regionCount
,
604 const VkBufferCopy
* pRegions
)
606 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
607 ANV_FROM_HANDLE(anv_buffer
, src_buffer
, srcBuffer
);
608 ANV_FROM_HANDLE(anv_buffer
, dst_buffer
, dstBuffer
);
610 struct blorp_batch batch
;
611 blorp_batch_init(&cmd_buffer
->device
->blorp
, &batch
, cmd_buffer
, 0);
613 for (unsigned r
= 0; r
< regionCount
; r
++) {
614 uint64_t src_offset
= src_buffer
->offset
+ pRegions
[r
].srcOffset
;
615 uint64_t dst_offset
= dst_buffer
->offset
+ pRegions
[r
].dstOffset
;
616 uint64_t copy_size
= pRegions
[r
].size
;
618 /* First, we compute the biggest format that can be used with the
619 * given offsets and size.
622 bs
= gcd_pow2_u64(bs
, src_offset
);
623 bs
= gcd_pow2_u64(bs
, dst_offset
);
624 bs
= gcd_pow2_u64(bs
, pRegions
[r
].size
);
626 /* First, we make a bunch of max-sized copies */
627 uint64_t max_copy_size
= MAX_SURFACE_DIM
* MAX_SURFACE_DIM
* bs
;
628 while (copy_size
>= max_copy_size
) {
629 do_buffer_copy(&batch
, src_buffer
->bo
, src_offset
,
630 dst_buffer
->bo
, dst_offset
,
631 MAX_SURFACE_DIM
, MAX_SURFACE_DIM
, bs
);
632 copy_size
-= max_copy_size
;
633 src_offset
+= max_copy_size
;
634 dst_offset
+= max_copy_size
;
637 /* Now make a max-width copy */
638 uint64_t height
= copy_size
/ (MAX_SURFACE_DIM
* bs
);
639 assert(height
< MAX_SURFACE_DIM
);
641 uint64_t rect_copy_size
= height
* MAX_SURFACE_DIM
* bs
;
642 do_buffer_copy(&batch
, src_buffer
->bo
, src_offset
,
643 dst_buffer
->bo
, dst_offset
,
644 MAX_SURFACE_DIM
, height
, bs
);
645 copy_size
-= rect_copy_size
;
646 src_offset
+= rect_copy_size
;
647 dst_offset
+= rect_copy_size
;
650 /* Finally, make a small copy to finish it off */
651 if (copy_size
!= 0) {
652 do_buffer_copy(&batch
, src_buffer
->bo
, src_offset
,
653 dst_buffer
->bo
, dst_offset
,
654 copy_size
/ bs
, 1, bs
);
658 blorp_batch_finish(&batch
);
661 void anv_CmdUpdateBuffer(
662 VkCommandBuffer commandBuffer
,
664 VkDeviceSize dstOffset
,
665 VkDeviceSize dataSize
,
668 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
669 ANV_FROM_HANDLE(anv_buffer
, dst_buffer
, dstBuffer
);
671 struct blorp_batch batch
;
672 blorp_batch_init(&cmd_buffer
->device
->blorp
, &batch
, cmd_buffer
, 0);
674 /* We can't quite grab a full block because the state stream needs a
675 * little data at the top to build its linked list.
677 const uint32_t max_update_size
=
678 cmd_buffer
->device
->dynamic_state_block_pool
.block_size
- 64;
680 assert(max_update_size
< MAX_SURFACE_DIM
* 4);
683 const uint32_t copy_size
= MIN2(dataSize
, max_update_size
);
685 struct anv_state tmp_data
=
686 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer
, copy_size
, 64);
688 memcpy(tmp_data
.map
, pData
, copy_size
);
691 bs
= gcd_pow2_u64(bs
, dstOffset
);
692 bs
= gcd_pow2_u64(bs
, copy_size
);
694 do_buffer_copy(&batch
,
695 &cmd_buffer
->device
->dynamic_state_block_pool
.bo
,
697 dst_buffer
->bo
, dst_buffer
->offset
+ dstOffset
,
698 copy_size
/ bs
, 1, bs
);
700 dataSize
-= copy_size
;
701 dstOffset
+= copy_size
;
702 pData
= (void *)pData
+ copy_size
;
705 blorp_batch_finish(&batch
);
708 void anv_CmdFillBuffer(
709 VkCommandBuffer commandBuffer
,
711 VkDeviceSize dstOffset
,
712 VkDeviceSize fillSize
,
715 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
716 ANV_FROM_HANDLE(anv_buffer
, dst_buffer
, dstBuffer
);
717 struct blorp_surf surf
;
718 struct isl_surf isl_surf
;
720 struct blorp_batch batch
;
721 blorp_batch_init(&cmd_buffer
->device
->blorp
, &batch
, cmd_buffer
, 0);
723 if (fillSize
== VK_WHOLE_SIZE
) {
724 fillSize
= dst_buffer
->size
- dstOffset
;
725 /* Make sure fillSize is a multiple of 4 */
729 /* First, we compute the biggest format that can be used with the
730 * given offsets and size.
733 bs
= gcd_pow2_u64(bs
, dstOffset
);
734 bs
= gcd_pow2_u64(bs
, fillSize
);
735 enum isl_format isl_format
= isl_format_for_size(bs
);
737 union isl_color_value color
= {
738 .u32
= { data
, data
, data
, data
},
741 const uint64_t max_fill_size
= MAX_SURFACE_DIM
* MAX_SURFACE_DIM
* bs
;
742 while (fillSize
>= max_fill_size
) {
743 get_blorp_surf_for_anv_buffer(cmd_buffer
->device
,
744 dst_buffer
, dstOffset
,
745 MAX_SURFACE_DIM
, MAX_SURFACE_DIM
,
746 MAX_SURFACE_DIM
* bs
, isl_format
,
749 blorp_clear(&batch
, &surf
, isl_format
, ISL_SWIZZLE_IDENTITY
,
750 0, 0, 1, 0, 0, MAX_SURFACE_DIM
, MAX_SURFACE_DIM
,
752 fillSize
-= max_fill_size
;
753 dstOffset
+= max_fill_size
;
756 uint64_t height
= fillSize
/ (MAX_SURFACE_DIM
* bs
);
757 assert(height
< MAX_SURFACE_DIM
);
759 const uint64_t rect_fill_size
= height
* MAX_SURFACE_DIM
* bs
;
760 get_blorp_surf_for_anv_buffer(cmd_buffer
->device
,
761 dst_buffer
, dstOffset
,
762 MAX_SURFACE_DIM
, height
,
763 MAX_SURFACE_DIM
* bs
, isl_format
,
766 blorp_clear(&batch
, &surf
, isl_format
, ISL_SWIZZLE_IDENTITY
,
767 0, 0, 1, 0, 0, MAX_SURFACE_DIM
, height
,
769 fillSize
-= rect_fill_size
;
770 dstOffset
+= rect_fill_size
;
774 const uint32_t width
= fillSize
/ bs
;
775 get_blorp_surf_for_anv_buffer(cmd_buffer
->device
,
776 dst_buffer
, dstOffset
,
778 width
* bs
, isl_format
,
781 blorp_clear(&batch
, &surf
, isl_format
, ISL_SWIZZLE_IDENTITY
,
782 0, 0, 1, 0, 0, width
, 1,
786 blorp_batch_finish(&batch
);
789 void anv_CmdClearColorImage(
790 VkCommandBuffer commandBuffer
,
792 VkImageLayout imageLayout
,
793 const VkClearColorValue
* pColor
,
795 const VkImageSubresourceRange
* pRanges
)
797 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
798 ANV_FROM_HANDLE(anv_image
, image
, _image
);
800 static const bool color_write_disable
[4] = { false, false, false, false };
802 struct blorp_batch batch
;
803 blorp_batch_init(&cmd_buffer
->device
->blorp
, &batch
, cmd_buffer
, 0);
805 union isl_color_value clear_color
;
806 memcpy(clear_color
.u32
, pColor
->uint32
, sizeof(pColor
->uint32
));
808 struct blorp_surf surf
;
809 get_blorp_surf_for_anv_image(image
, VK_IMAGE_ASPECT_COLOR_BIT
,
810 image
->aux_usage
, &surf
);
812 for (unsigned r
= 0; r
< rangeCount
; r
++) {
813 if (pRanges
[r
].aspectMask
== 0)
816 assert(pRanges
[r
].aspectMask
== VK_IMAGE_ASPECT_COLOR_BIT
);
818 struct anv_format src_format
=
819 anv_get_format(&cmd_buffer
->device
->info
, image
->vk_format
,
820 VK_IMAGE_ASPECT_COLOR_BIT
, image
->tiling
);
822 unsigned base_layer
= pRanges
[r
].baseArrayLayer
;
823 unsigned layer_count
= pRanges
[r
].layerCount
;
825 for (unsigned i
= 0; i
< anv_get_levelCount(image
, &pRanges
[r
]); i
++) {
826 const unsigned level
= pRanges
[r
].baseMipLevel
+ i
;
827 const unsigned level_width
= anv_minify(image
->extent
.width
, level
);
828 const unsigned level_height
= anv_minify(image
->extent
.height
, level
);
830 if (image
->type
== VK_IMAGE_TYPE_3D
) {
832 layer_count
= anv_minify(image
->extent
.depth
, level
);
835 blorp_clear(&batch
, &surf
,
836 src_format
.isl_format
, src_format
.swizzle
,
837 level
, base_layer
, layer_count
,
838 0, 0, level_width
, level_height
,
839 clear_color
, color_write_disable
);
843 blorp_batch_finish(&batch
);
846 void anv_CmdClearDepthStencilImage(
847 VkCommandBuffer commandBuffer
,
849 VkImageLayout imageLayout
,
850 const VkClearDepthStencilValue
* pDepthStencil
,
852 const VkImageSubresourceRange
* pRanges
)
854 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
855 ANV_FROM_HANDLE(anv_image
, image
, image_h
);
857 struct blorp_batch batch
;
858 blorp_batch_init(&cmd_buffer
->device
->blorp
, &batch
, cmd_buffer
, 0);
860 struct blorp_surf depth
, stencil
;
861 if (image
->aspects
& VK_IMAGE_ASPECT_DEPTH_BIT
) {
862 get_blorp_surf_for_anv_image(image
, VK_IMAGE_ASPECT_DEPTH_BIT
,
863 image
->aux_usage
, &depth
);
865 memset(&depth
, 0, sizeof(depth
));
868 if (image
->aspects
& VK_IMAGE_ASPECT_STENCIL_BIT
) {
869 get_blorp_surf_for_anv_image(image
, VK_IMAGE_ASPECT_STENCIL_BIT
,
870 ISL_AUX_USAGE_NONE
, &stencil
);
872 memset(&stencil
, 0, sizeof(stencil
));
875 for (unsigned r
= 0; r
< rangeCount
; r
++) {
876 if (pRanges
[r
].aspectMask
== 0)
879 bool clear_depth
= pRanges
[r
].aspectMask
& VK_IMAGE_ASPECT_DEPTH_BIT
;
880 bool clear_stencil
= pRanges
[r
].aspectMask
& VK_IMAGE_ASPECT_STENCIL_BIT
;
882 unsigned base_layer
= pRanges
[r
].baseArrayLayer
;
883 unsigned layer_count
= pRanges
[r
].layerCount
;
885 for (unsigned i
= 0; i
< anv_get_levelCount(image
, &pRanges
[r
]); i
++) {
886 const unsigned level
= pRanges
[r
].baseMipLevel
+ i
;
887 const unsigned level_width
= anv_minify(image
->extent
.width
, level
);
888 const unsigned level_height
= anv_minify(image
->extent
.height
, level
);
890 if (image
->type
== VK_IMAGE_TYPE_3D
)
891 layer_count
= anv_minify(image
->extent
.depth
, level
);
893 blorp_clear_depth_stencil(&batch
, &depth
, &stencil
,
894 level
, base_layer
, layer_count
,
895 0, 0, level_width
, level_height
,
896 clear_depth
, pDepthStencil
->depth
,
897 clear_stencil
? 0xff : 0,
898 pDepthStencil
->stencil
);
902 blorp_batch_finish(&batch
);
906 anv_cmd_buffer_alloc_blorp_binding_table(struct anv_cmd_buffer
*cmd_buffer
,
907 uint32_t num_entries
,
908 uint32_t *state_offset
)
910 struct anv_state bt_state
=
911 anv_cmd_buffer_alloc_binding_table(cmd_buffer
, num_entries
,
913 if (bt_state
.map
== NULL
) {
914 /* We ran out of space. Grab a new binding table block. */
915 VkResult result
= anv_cmd_buffer_new_binding_table_block(cmd_buffer
);
916 assert(result
== VK_SUCCESS
);
918 /* Re-emit state base addresses so we get the new surface state base
919 * address before we start emitting binding tables etc.
921 anv_cmd_buffer_emit_state_base_address(cmd_buffer
);
923 bt_state
= anv_cmd_buffer_alloc_binding_table(cmd_buffer
, num_entries
,
925 assert(bt_state
.map
!= NULL
);
932 binding_table_for_surface_state(struct anv_cmd_buffer
*cmd_buffer
,
933 struct anv_state surface_state
)
935 uint32_t state_offset
;
936 struct anv_state bt_state
=
937 anv_cmd_buffer_alloc_blorp_binding_table(cmd_buffer
, 1, &state_offset
);
939 uint32_t *bt_map
= bt_state
.map
;
940 bt_map
[0] = surface_state
.offset
+ state_offset
;
942 return bt_state
.offset
;
946 clear_color_attachment(struct anv_cmd_buffer
*cmd_buffer
,
947 struct blorp_batch
*batch
,
948 const VkClearAttachment
*attachment
,
949 uint32_t rectCount
, const VkClearRect
*pRects
)
951 const struct anv_subpass
*subpass
= cmd_buffer
->state
.subpass
;
952 const uint32_t color_att
= attachment
->colorAttachment
;
953 const uint32_t att_idx
= subpass
->color_attachments
[color_att
];
955 if (att_idx
== VK_ATTACHMENT_UNUSED
)
958 struct anv_render_pass_attachment
*pass_att
=
959 &cmd_buffer
->state
.pass
->attachments
[att_idx
];
960 struct anv_attachment_state
*att_state
=
961 &cmd_buffer
->state
.attachments
[att_idx
];
963 uint32_t binding_table
=
964 binding_table_for_surface_state(cmd_buffer
, att_state
->color_rt_state
);
966 union isl_color_value clear_color
;
967 memcpy(clear_color
.u32
, attachment
->clearValue
.color
.uint32
,
968 sizeof(clear_color
.u32
));
970 for (uint32_t r
= 0; r
< rectCount
; ++r
) {
971 const VkOffset2D offset
= pRects
[r
].rect
.offset
;
972 const VkExtent2D extent
= pRects
[r
].rect
.extent
;
973 blorp_clear_attachments(batch
, binding_table
,
974 ISL_FORMAT_UNSUPPORTED
, pass_att
->samples
,
975 pRects
[r
].baseArrayLayer
,
976 pRects
[r
].layerCount
,
978 offset
.x
+ extent
.width
, offset
.y
+ extent
.height
,
979 true, clear_color
, false, 0.0f
, 0, 0);
984 clear_depth_stencil_attachment(struct anv_cmd_buffer
*cmd_buffer
,
985 struct blorp_batch
*batch
,
986 const VkClearAttachment
*attachment
,
987 uint32_t rectCount
, const VkClearRect
*pRects
)
989 static const union isl_color_value color_value
= { .u32
= { 0, } };
990 const struct anv_subpass
*subpass
= cmd_buffer
->state
.subpass
;
991 const uint32_t att_idx
= subpass
->depth_stencil_attachment
;
993 if (att_idx
== VK_ATTACHMENT_UNUSED
)
996 struct anv_render_pass_attachment
*pass_att
=
997 &cmd_buffer
->state
.pass
->attachments
[att_idx
];
999 bool clear_depth
= attachment
->aspectMask
& VK_IMAGE_ASPECT_DEPTH_BIT
;
1000 bool clear_stencil
= attachment
->aspectMask
& VK_IMAGE_ASPECT_STENCIL_BIT
;
1002 enum isl_format depth_format
= ISL_FORMAT_UNSUPPORTED
;
1004 depth_format
= anv_get_isl_format(&cmd_buffer
->device
->info
,
1006 VK_IMAGE_ASPECT_DEPTH_BIT
,
1007 VK_IMAGE_TILING_OPTIMAL
);
1010 uint32_t binding_table
=
1011 binding_table_for_surface_state(cmd_buffer
,
1012 cmd_buffer
->state
.null_surface_state
);
1014 for (uint32_t r
= 0; r
< rectCount
; ++r
) {
1015 const VkOffset2D offset
= pRects
[r
].rect
.offset
;
1016 const VkExtent2D extent
= pRects
[r
].rect
.extent
;
1017 VkClearDepthStencilValue value
= attachment
->clearValue
.depthStencil
;
1018 blorp_clear_attachments(batch
, binding_table
,
1019 depth_format
, pass_att
->samples
,
1020 pRects
[r
].baseArrayLayer
,
1021 pRects
[r
].layerCount
,
1023 offset
.x
+ extent
.width
, offset
.y
+ extent
.height
,
1025 clear_depth
, value
.depth
,
1026 clear_stencil
? 0xff : 0, value
.stencil
);
1030 void anv_CmdClearAttachments(
1031 VkCommandBuffer commandBuffer
,
1032 uint32_t attachmentCount
,
1033 const VkClearAttachment
* pAttachments
,
1035 const VkClearRect
* pRects
)
1037 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
1039 /* Because this gets called within a render pass, we tell blorp not to
1040 * trash our depth and stencil buffers.
1042 struct blorp_batch batch
;
1043 blorp_batch_init(&cmd_buffer
->device
->blorp
, &batch
, cmd_buffer
,
1044 BLORP_BATCH_NO_EMIT_DEPTH_STENCIL
);
1046 for (uint32_t a
= 0; a
< attachmentCount
; ++a
) {
1047 if (pAttachments
[a
].aspectMask
== VK_IMAGE_ASPECT_COLOR_BIT
) {
1048 clear_color_attachment(cmd_buffer
, &batch
,
1052 clear_depth_stencil_attachment(cmd_buffer
, &batch
,
1058 blorp_batch_finish(&batch
);
1062 subpass_needs_clear(const struct anv_cmd_buffer
*cmd_buffer
)
1064 const struct anv_cmd_state
*cmd_state
= &cmd_buffer
->state
;
1065 uint32_t ds
= cmd_state
->subpass
->depth_stencil_attachment
;
1067 for (uint32_t i
= 0; i
< cmd_state
->subpass
->color_count
; ++i
) {
1068 uint32_t a
= cmd_state
->subpass
->color_attachments
[i
];
1069 if (cmd_state
->attachments
[a
].pending_clear_aspects
) {
1074 if (ds
!= VK_ATTACHMENT_UNUSED
&&
1075 cmd_state
->attachments
[ds
].pending_clear_aspects
) {
1083 anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer
*cmd_buffer
)
1085 const struct anv_cmd_state
*cmd_state
= &cmd_buffer
->state
;
1087 if (!subpass_needs_clear(cmd_buffer
))
1090 /* Because this gets called within a render pass, we tell blorp not to
1091 * trash our depth and stencil buffers.
1093 struct blorp_batch batch
;
1094 blorp_batch_init(&cmd_buffer
->device
->blorp
, &batch
, cmd_buffer
,
1095 BLORP_BATCH_NO_EMIT_DEPTH_STENCIL
);
1097 VkClearRect clear_rect
= {
1098 .rect
= cmd_buffer
->state
.render_area
,
1099 .baseArrayLayer
= 0,
1100 .layerCount
= cmd_buffer
->state
.framebuffer
->layers
,
1103 for (uint32_t i
= 0; i
< cmd_state
->subpass
->color_count
; ++i
) {
1104 const uint32_t a
= cmd_state
->subpass
->color_attachments
[i
];
1106 if (!cmd_state
->attachments
[a
].pending_clear_aspects
)
1109 assert(cmd_state
->attachments
[a
].pending_clear_aspects
==
1110 VK_IMAGE_ASPECT_COLOR_BIT
);
1112 VkClearAttachment clear_att
= {
1113 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
1114 .colorAttachment
= i
, /* Use attachment index relative to subpass */
1115 .clearValue
= cmd_state
->attachments
[a
].clear_value
,
1118 clear_color_attachment(cmd_buffer
, &batch
, &clear_att
, 1, &clear_rect
);
1120 cmd_state
->attachments
[a
].pending_clear_aspects
= 0;
1123 const uint32_t ds
= cmd_state
->subpass
->depth_stencil_attachment
;
1125 if (ds
!= VK_ATTACHMENT_UNUSED
&&
1126 cmd_state
->attachments
[ds
].pending_clear_aspects
) {
1128 VkClearAttachment clear_att
= {
1129 .aspectMask
= cmd_state
->attachments
[ds
].pending_clear_aspects
,
1130 .clearValue
= cmd_state
->attachments
[ds
].clear_value
,
1133 clear_depth_stencil_attachment(cmd_buffer
, &batch
,
1134 &clear_att
, 1, &clear_rect
);
1136 cmd_state
->attachments
[ds
].pending_clear_aspects
= 0;
1139 blorp_batch_finish(&batch
);
1143 resolve_image(struct blorp_batch
*batch
,
1144 const struct anv_image
*src_image
,
1145 uint32_t src_level
, uint32_t src_layer
,
1146 const struct anv_image
*dst_image
,
1147 uint32_t dst_level
, uint32_t dst_layer
,
1148 VkImageAspectFlags aspect_mask
,
1149 uint32_t src_x
, uint32_t src_y
, uint32_t dst_x
, uint32_t dst_y
,
1150 uint32_t width
, uint32_t height
)
1152 assert(src_image
->type
== VK_IMAGE_TYPE_2D
);
1153 assert(src_image
->samples
> 1);
1154 assert(dst_image
->type
== VK_IMAGE_TYPE_2D
);
1155 assert(dst_image
->samples
== 1);
1158 for_each_bit(a
, aspect_mask
) {
1159 VkImageAspectFlagBits aspect
= 1 << a
;
1161 struct blorp_surf src_surf
, dst_surf
;
1162 get_blorp_surf_for_anv_image(src_image
, aspect
,
1163 src_image
->aux_usage
, &src_surf
);
1164 get_blorp_surf_for_anv_image(dst_image
, aspect
,
1165 dst_image
->aux_usage
, &dst_surf
);
1168 &src_surf
, src_level
, src_layer
,
1169 ISL_FORMAT_UNSUPPORTED
, ISL_SWIZZLE_IDENTITY
,
1170 &dst_surf
, dst_level
, dst_layer
,
1171 ISL_FORMAT_UNSUPPORTED
, ISL_SWIZZLE_IDENTITY
,
1172 src_x
, src_y
, src_x
+ width
, src_y
+ height
,
1173 dst_x
, dst_y
, dst_x
+ width
, dst_y
+ height
,
1174 0x2600 /* GL_NEAREST */, false, false);
1178 void anv_CmdResolveImage(
1179 VkCommandBuffer commandBuffer
,
1181 VkImageLayout srcImageLayout
,
1183 VkImageLayout dstImageLayout
,
1184 uint32_t regionCount
,
1185 const VkImageResolve
* pRegions
)
1187 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
1188 ANV_FROM_HANDLE(anv_image
, src_image
, srcImage
);
1189 ANV_FROM_HANDLE(anv_image
, dst_image
, dstImage
);
1191 struct blorp_batch batch
;
1192 blorp_batch_init(&cmd_buffer
->device
->blorp
, &batch
, cmd_buffer
, 0);
1194 for (uint32_t r
= 0; r
< regionCount
; r
++) {
1195 assert(pRegions
[r
].srcSubresource
.aspectMask
==
1196 pRegions
[r
].dstSubresource
.aspectMask
);
1197 assert(pRegions
[r
].srcSubresource
.layerCount
==
1198 pRegions
[r
].dstSubresource
.layerCount
);
1200 const uint32_t layer_count
= pRegions
[r
].dstSubresource
.layerCount
;
1202 for (uint32_t layer
= 0; layer
< layer_count
; layer
++) {
1203 resolve_image(&batch
,
1204 src_image
, pRegions
[r
].srcSubresource
.mipLevel
,
1205 pRegions
[r
].srcSubresource
.baseArrayLayer
+ layer
,
1206 dst_image
, pRegions
[r
].dstSubresource
.mipLevel
,
1207 pRegions
[r
].dstSubresource
.baseArrayLayer
+ layer
,
1208 pRegions
[r
].dstSubresource
.aspectMask
,
1209 pRegions
[r
].srcOffset
.x
, pRegions
[r
].srcOffset
.y
,
1210 pRegions
[r
].dstOffset
.x
, pRegions
[r
].dstOffset
.y
,
1211 pRegions
[r
].extent
.width
, pRegions
[r
].extent
.height
);
1215 blorp_batch_finish(&batch
);
1219 ccs_resolve_attachment(struct anv_cmd_buffer
*cmd_buffer
,
1220 struct blorp_batch
*batch
,
1223 struct anv_framebuffer
*fb
= cmd_buffer
->state
.framebuffer
;
1224 struct anv_attachment_state
*att_state
=
1225 &cmd_buffer
->state
.attachments
[att
];
1227 assert(att_state
->aux_usage
!= ISL_AUX_USAGE_CCS_D
);
1228 if (att_state
->aux_usage
!= ISL_AUX_USAGE_CCS_E
)
1229 return; /* Nothing to resolve */
1231 struct anv_render_pass
*pass
= cmd_buffer
->state
.pass
;
1232 struct anv_subpass
*subpass
= cmd_buffer
->state
.subpass
;
1233 unsigned subpass_idx
= subpass
- pass
->subpasses
;
1234 assert(subpass_idx
< pass
->subpass_count
);
1236 /* Scan forward to see what all ways this attachment will be used.
1237 * Ideally, we would like to resolve in the same subpass as the last write
1238 * of a particular attachment. That way we only resolve once but it's
1239 * still hot in the cache.
1241 for (uint32_t s
= subpass_idx
+ 1; s
< pass
->subpass_count
; s
++) {
1242 enum anv_subpass_usage usage
= pass
->attachments
[att
].subpass_usage
[s
];
1244 if (usage
& (ANV_SUBPASS_USAGE_DRAW
| ANV_SUBPASS_USAGE_RESOLVE_DST
)) {
1245 /* We found another subpass that draws to this attachment. We'll
1246 * wait to resolve until then.
1252 struct anv_image_view
*iview
= fb
->attachments
[att
];
1253 const struct anv_image
*image
= iview
->image
;
1254 assert(image
->aspects
== VK_IMAGE_ASPECT_COLOR_BIT
);
1256 struct blorp_surf surf
;
1257 get_blorp_surf_for_anv_image(image
, VK_IMAGE_ASPECT_COLOR_BIT
,
1258 att_state
->aux_usage
, &surf
);
1260 for (uint32_t layer
= 0; layer
< fb
->layers
; layer
++) {
1261 blorp_ccs_resolve(batch
, &surf
,
1262 iview
->isl
.base_level
,
1263 iview
->isl
.base_array_layer
+ layer
,
1265 BLORP_FAST_CLEAR_OP_RESOLVE_FULL
);
1270 anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer
*cmd_buffer
)
1272 struct anv_framebuffer
*fb
= cmd_buffer
->state
.framebuffer
;
1273 struct anv_subpass
*subpass
= cmd_buffer
->state
.subpass
;
1276 struct blorp_batch batch
;
1277 blorp_batch_init(&cmd_buffer
->device
->blorp
, &batch
, cmd_buffer
, 0);
1279 /* From the Sky Lake PRM Vol. 7, "Render Target Resolve":
1281 * "When performing a render target resolve, PIPE_CONTROL with end of
1282 * pipe sync must be delivered."
1284 cmd_buffer
->state
.pending_pipe_bits
|= ANV_PIPE_CS_STALL_BIT
;
1286 for (uint32_t i
= 0; i
< subpass
->color_count
; ++i
) {
1287 ccs_resolve_attachment(cmd_buffer
, &batch
,
1288 subpass
->color_attachments
[i
]);
1291 if (subpass
->has_resolve
) {
1292 for (uint32_t i
= 0; i
< subpass
->color_count
; ++i
) {
1293 uint32_t src_att
= subpass
->color_attachments
[i
];
1294 uint32_t dst_att
= subpass
->resolve_attachments
[i
];
1296 if (dst_att
== VK_ATTACHMENT_UNUSED
)
1299 if (cmd_buffer
->state
.attachments
[dst_att
].pending_clear_aspects
) {
1300 /* From the Vulkan 1.0 spec:
1302 * If the first use of an attachment in a render pass is as a
1303 * resolve attachment, then the loadOp is effectively ignored
1304 * as the resolve is guaranteed to overwrite all pixels in the
1307 cmd_buffer
->state
.attachments
[dst_att
].pending_clear_aspects
= 0;
1310 struct anv_image_view
*src_iview
= fb
->attachments
[src_att
];
1311 struct anv_image_view
*dst_iview
= fb
->attachments
[dst_att
];
1313 const VkRect2D render_area
= cmd_buffer
->state
.render_area
;
1315 assert(src_iview
->aspect_mask
== dst_iview
->aspect_mask
);
1316 resolve_image(&batch
, src_iview
->image
,
1317 src_iview
->isl
.base_level
,
1318 src_iview
->isl
.base_array_layer
,
1320 dst_iview
->isl
.base_level
,
1321 dst_iview
->isl
.base_array_layer
,
1322 src_iview
->aspect_mask
,
1323 render_area
.offset
.x
, render_area
.offset
.y
,
1324 render_area
.offset
.x
, render_area
.offset
.y
,
1325 render_area
.extent
.width
, render_area
.extent
.height
);
1327 /* From the Sky Lake PRM Vol. 7, "Render Target Resolve":
1329 * "When performing a render target resolve, PIPE_CONTROL with end
1330 * of pipe sync must be delivered."
1332 cmd_buffer
->state
.pending_pipe_bits
|= ANV_PIPE_CS_STALL_BIT
;
1334 ccs_resolve_attachment(cmd_buffer
, &batch
, dst_att
);
1338 blorp_batch_finish(&batch
);