2 * Copyright © 2015 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 "radv_meta.h"
25 #include "radv_private.h"
26 #include "nir/nir_builder.h"
28 #include "util/format_rgb9e5.h"
29 #include "vk_format.h"
30 /** Vertex attributes for color clears. */
31 struct color_clear_vattrs
{
33 VkClearColorValue color
;
36 /** Vertex attributes for depthstencil clears. */
37 struct depthstencil_clear_vattrs
{
44 DEPTH_CLEAR_FAST_EXPCLEAR
,
45 DEPTH_CLEAR_FAST_NO_EXPCLEAR
49 build_color_shaders(struct nir_shader
**out_vs
,
50 struct nir_shader
**out_fs
,
56 nir_builder_init_simple_shader(&vs_b
, NULL
, MESA_SHADER_VERTEX
, NULL
);
57 nir_builder_init_simple_shader(&fs_b
, NULL
, MESA_SHADER_FRAGMENT
, NULL
);
59 vs_b
.shader
->info
->name
= ralloc_strdup(vs_b
.shader
, "meta_clear_color_vs");
60 fs_b
.shader
->info
->name
= ralloc_strdup(fs_b
.shader
, "meta_clear_color_fs");
62 const struct glsl_type
*position_type
= glsl_vec4_type();
63 const struct glsl_type
*color_type
= glsl_vec4_type();
65 nir_variable
*vs_in_pos
=
66 nir_variable_create(vs_b
.shader
, nir_var_shader_in
, position_type
,
68 vs_in_pos
->data
.location
= VERT_ATTRIB_GENERIC0
;
70 nir_variable
*vs_out_pos
=
71 nir_variable_create(vs_b
.shader
, nir_var_shader_out
, position_type
,
73 vs_out_pos
->data
.location
= VARYING_SLOT_POS
;
75 nir_variable
*vs_in_color
=
76 nir_variable_create(vs_b
.shader
, nir_var_shader_in
, color_type
,
78 vs_in_color
->data
.location
= VERT_ATTRIB_GENERIC1
;
80 nir_variable
*vs_out_color
=
81 nir_variable_create(vs_b
.shader
, nir_var_shader_out
, color_type
,
83 vs_out_color
->data
.location
= VARYING_SLOT_VAR0
;
84 vs_out_color
->data
.interpolation
= INTERP_MODE_FLAT
;
86 nir_variable
*fs_in_color
=
87 nir_variable_create(fs_b
.shader
, nir_var_shader_in
, color_type
,
89 fs_in_color
->data
.location
= vs_out_color
->data
.location
;
90 fs_in_color
->data
.interpolation
= vs_out_color
->data
.interpolation
;
92 nir_variable
*fs_out_color
=
93 nir_variable_create(fs_b
.shader
, nir_var_shader_out
, color_type
,
95 fs_out_color
->data
.location
= FRAG_RESULT_DATA0
+ frag_output
;
97 nir_copy_var(&vs_b
, vs_out_pos
, vs_in_pos
);
98 nir_copy_var(&vs_b
, vs_out_color
, vs_in_color
);
99 nir_copy_var(&fs_b
, fs_out_color
, fs_in_color
);
101 *out_vs
= vs_b
.shader
;
102 *out_fs
= fs_b
.shader
;
106 create_pipeline(struct radv_device
*device
,
107 struct radv_render_pass
*render_pass
,
109 struct nir_shader
*vs_nir
,
110 struct nir_shader
*fs_nir
,
111 const VkPipelineVertexInputStateCreateInfo
*vi_state
,
112 const VkPipelineDepthStencilStateCreateInfo
*ds_state
,
113 const VkPipelineColorBlendStateCreateInfo
*cb_state
,
114 const struct radv_graphics_pipeline_create_info
*extra
,
115 const VkAllocationCallbacks
*alloc
,
116 struct radv_pipeline
**pipeline
)
118 VkDevice device_h
= radv_device_to_handle(device
);
121 struct radv_shader_module vs_m
= { .nir
= vs_nir
};
122 struct radv_shader_module fs_m
= { .nir
= fs_nir
};
124 VkPipeline pipeline_h
= VK_NULL_HANDLE
;
125 result
= radv_graphics_pipeline_create(device_h
,
126 radv_pipeline_cache_to_handle(&device
->meta_state
.cache
),
127 &(VkGraphicsPipelineCreateInfo
) {
128 .sType
= VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
,
129 .stageCount
= fs_nir
? 2 : 1,
130 .pStages
= (VkPipelineShaderStageCreateInfo
[]) {
132 .sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
,
133 .stage
= VK_SHADER_STAGE_VERTEX_BIT
,
134 .module
= radv_shader_module_to_handle(&vs_m
),
138 .sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
,
139 .stage
= VK_SHADER_STAGE_FRAGMENT_BIT
,
140 .module
= radv_shader_module_to_handle(&fs_m
),
144 .pVertexInputState
= vi_state
,
145 .pInputAssemblyState
= &(VkPipelineInputAssemblyStateCreateInfo
) {
146 .sType
= VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO
,
147 .topology
= VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
,
148 .primitiveRestartEnable
= false,
150 .pViewportState
= &(VkPipelineViewportStateCreateInfo
) {
151 .sType
= VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO
,
155 .pRasterizationState
= &(VkPipelineRasterizationStateCreateInfo
) {
156 .sType
= VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO
,
157 .rasterizerDiscardEnable
= false,
158 .polygonMode
= VK_POLYGON_MODE_FILL
,
159 .cullMode
= VK_CULL_MODE_NONE
,
160 .frontFace
= VK_FRONT_FACE_COUNTER_CLOCKWISE
,
161 .depthBiasEnable
= false,
163 .pMultisampleState
= &(VkPipelineMultisampleStateCreateInfo
) {
164 .sType
= VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO
,
165 .rasterizationSamples
= samples
,
166 .sampleShadingEnable
= false,
168 .alphaToCoverageEnable
= false,
169 .alphaToOneEnable
= false,
171 .pDepthStencilState
= ds_state
,
172 .pColorBlendState
= cb_state
,
173 .pDynamicState
= &(VkPipelineDynamicStateCreateInfo
) {
174 /* The meta clear pipeline declares all state as dynamic.
175 * As a consequence, vkCmdBindPipeline writes no dynamic state
176 * to the cmd buffer. Therefore, at the end of the meta clear,
177 * we need only restore dynamic state was vkCmdSet.
179 .sType
= VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO
,
180 .dynamicStateCount
= 6,
181 .pDynamicStates
= (VkDynamicState
[]) {
182 /* Everything except stencil write mask */
183 VK_DYNAMIC_STATE_LINE_WIDTH
,
184 VK_DYNAMIC_STATE_DEPTH_BIAS
,
185 VK_DYNAMIC_STATE_BLEND_CONSTANTS
,
186 VK_DYNAMIC_STATE_DEPTH_BOUNDS
,
187 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK
,
188 VK_DYNAMIC_STATE_STENCIL_REFERENCE
,
192 .renderPass
= radv_render_pass_to_handle(render_pass
),
202 *pipeline
= radv_pipeline_from_handle(pipeline_h
);
208 create_color_renderpass(struct radv_device
*device
,
213 return radv_CreateRenderPass(radv_device_to_handle(device
),
214 &(VkRenderPassCreateInfo
) {
215 .sType
= VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
,
216 .attachmentCount
= 1,
217 .pAttachments
= &(VkAttachmentDescription
) {
220 .loadOp
= VK_ATTACHMENT_LOAD_OP_LOAD
,
221 .storeOp
= VK_ATTACHMENT_STORE_OP_STORE
,
222 .initialLayout
= VK_IMAGE_LAYOUT_GENERAL
,
223 .finalLayout
= VK_IMAGE_LAYOUT_GENERAL
,
226 .pSubpasses
= &(VkSubpassDescription
) {
227 .pipelineBindPoint
= VK_PIPELINE_BIND_POINT_GRAPHICS
,
228 .inputAttachmentCount
= 0,
229 .colorAttachmentCount
= 1,
230 .pColorAttachments
= &(VkAttachmentReference
) {
232 .layout
= VK_IMAGE_LAYOUT_GENERAL
,
234 .pResolveAttachments
= NULL
,
235 .pDepthStencilAttachment
= &(VkAttachmentReference
) {
236 .attachment
= VK_ATTACHMENT_UNUSED
,
237 .layout
= VK_IMAGE_LAYOUT_GENERAL
,
239 .preserveAttachmentCount
= 1,
240 .pPreserveAttachments
= (uint32_t[]) { 0 },
242 .dependencyCount
= 0,
243 }, &device
->meta_state
.alloc
, pass
);
247 create_color_pipeline(struct radv_device
*device
,
249 uint32_t frag_output
,
250 struct radv_pipeline
**pipeline
,
253 struct nir_shader
*vs_nir
;
254 struct nir_shader
*fs_nir
;
256 build_color_shaders(&vs_nir
, &fs_nir
, frag_output
);
258 const VkPipelineVertexInputStateCreateInfo vi_state
= {
259 .sType
= VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO
,
260 .vertexBindingDescriptionCount
= 1,
261 .pVertexBindingDescriptions
= (VkVertexInputBindingDescription
[]) {
264 .stride
= sizeof(struct color_clear_vattrs
),
265 .inputRate
= VK_VERTEX_INPUT_RATE_VERTEX
268 .vertexAttributeDescriptionCount
= 2,
269 .pVertexAttributeDescriptions
= (VkVertexInputAttributeDescription
[]) {
274 .format
= VK_FORMAT_R32G32_SFLOAT
,
275 .offset
= offsetof(struct color_clear_vattrs
, position
),
281 .format
= VK_FORMAT_R32G32B32A32_SFLOAT
,
282 .offset
= offsetof(struct color_clear_vattrs
, color
),
287 const VkPipelineDepthStencilStateCreateInfo ds_state
= {
288 .sType
= VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
,
289 .depthTestEnable
= false,
290 .depthWriteEnable
= false,
291 .depthBoundsTestEnable
= false,
292 .stencilTestEnable
= false,
295 VkPipelineColorBlendAttachmentState blend_attachment_state
[MAX_RTS
] = { 0 };
296 blend_attachment_state
[frag_output
] = (VkPipelineColorBlendAttachmentState
) {
297 .blendEnable
= false,
298 .colorWriteMask
= VK_COLOR_COMPONENT_A_BIT
|
299 VK_COLOR_COMPONENT_R_BIT
|
300 VK_COLOR_COMPONENT_G_BIT
|
301 VK_COLOR_COMPONENT_B_BIT
,
304 const VkPipelineColorBlendStateCreateInfo cb_state
= {
305 .sType
= VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO
,
306 .logicOpEnable
= false,
307 .attachmentCount
= MAX_RTS
,
308 .pAttachments
= blend_attachment_state
312 struct radv_graphics_pipeline_create_info extra
= {
313 .use_rectlist
= true,
315 result
= create_pipeline(device
, radv_render_pass_from_handle(pass
),
316 samples
, vs_nir
, fs_nir
, &vi_state
, &ds_state
, &cb_state
,
317 &extra
, &device
->meta_state
.alloc
, pipeline
);
323 destroy_pipeline(struct radv_device
*device
, struct radv_pipeline
*pipeline
)
328 radv_DestroyPipeline(radv_device_to_handle(device
),
329 radv_pipeline_to_handle(pipeline
),
330 &device
->meta_state
.alloc
);
335 destroy_render_pass(struct radv_device
*device
, VkRenderPass renderpass
)
337 radv_DestroyRenderPass(radv_device_to_handle(device
), renderpass
,
338 &device
->meta_state
.alloc
);
342 radv_device_finish_meta_clear_state(struct radv_device
*device
)
344 struct radv_meta_state
*state
= &device
->meta_state
;
346 for (uint32_t i
= 0; i
< ARRAY_SIZE(state
->clear
); ++i
) {
347 for (uint32_t j
= 0; j
< ARRAY_SIZE(state
->clear
[i
].color_pipelines
); ++j
) {
348 destroy_pipeline(device
, state
->clear
[i
].color_pipelines
[j
]);
349 destroy_render_pass(device
, state
->clear
[i
].render_pass
[j
]);
352 for (uint32_t j
= 0; j
< NUM_DEPTH_CLEAR_PIPELINES
; j
++) {
353 destroy_pipeline(device
, state
->clear
[i
].depth_only_pipeline
[j
]);
354 destroy_pipeline(device
, state
->clear
[i
].stencil_only_pipeline
[j
]);
355 destroy_pipeline(device
, state
->clear
[i
].depthstencil_pipeline
[j
]);
357 destroy_render_pass(device
, state
->clear
[i
].depthstencil_rp
);
363 emit_color_clear(struct radv_cmd_buffer
*cmd_buffer
,
364 const VkClearAttachment
*clear_att
,
365 const VkClearRect
*clear_rect
)
367 struct radv_device
*device
= cmd_buffer
->device
;
368 const struct radv_subpass
*subpass
= cmd_buffer
->state
.subpass
;
369 const struct radv_framebuffer
*fb
= cmd_buffer
->state
.framebuffer
;
370 const uint32_t subpass_att
= clear_att
->colorAttachment
;
371 const uint32_t pass_att
= subpass
->color_attachments
[subpass_att
].attachment
;
372 const struct radv_image_view
*iview
= fb
->attachments
[pass_att
].attachment
;
373 const uint32_t samples
= iview
->image
->samples
;
374 const uint32_t samples_log2
= ffs(samples
) - 1;
375 unsigned fs_key
= radv_format_meta_fs_key(iview
->vk_format
);
376 struct radv_pipeline
*pipeline
;
377 VkClearColorValue clear_value
= clear_att
->clearValue
.color
;
378 VkCommandBuffer cmd_buffer_h
= radv_cmd_buffer_to_handle(cmd_buffer
);
379 VkPipeline pipeline_h
;
383 radv_finishme("color clears incomplete");
386 pipeline
= device
->meta_state
.clear
[samples_log2
].color_pipelines
[fs_key
];
387 pipeline_h
= radv_pipeline_to_handle(pipeline
);
390 radv_finishme("color clears incomplete");
393 assert(samples_log2
< ARRAY_SIZE(device
->meta_state
.clear
));
395 assert(clear_att
->aspectMask
== VK_IMAGE_ASPECT_COLOR_BIT
);
396 assert(clear_att
->colorAttachment
< subpass
->color_count
);
398 const struct color_clear_vattrs vertex_data
[3] = {
401 clear_rect
->rect
.offset
.x
,
402 clear_rect
->rect
.offset
.y
,
404 .color
= clear_value
,
408 clear_rect
->rect
.offset
.x
,
409 clear_rect
->rect
.offset
.y
+ clear_rect
->rect
.extent
.height
,
411 .color
= clear_value
,
415 clear_rect
->rect
.offset
.x
+ clear_rect
->rect
.extent
.width
,
416 clear_rect
->rect
.offset
.y
,
418 .color
= clear_value
,
422 struct radv_subpass clear_subpass
= {
424 .color_attachments
= (VkAttachmentReference
[]) {
425 subpass
->color_attachments
[clear_att
->colorAttachment
]
427 .depth_stencil_attachment
= (VkAttachmentReference
) { VK_ATTACHMENT_UNUSED
, VK_IMAGE_LAYOUT_UNDEFINED
}
430 radv_cmd_buffer_set_subpass(cmd_buffer
, &clear_subpass
, false);
432 radv_cmd_buffer_upload_data(cmd_buffer
, sizeof(vertex_data
), 16, vertex_data
, &offset
);
433 struct radv_buffer vertex_buffer
= {
435 .size
= sizeof(vertex_data
),
436 .bo
= cmd_buffer
->upload
.upload_bo
,
441 radv_CmdBindVertexBuffers(cmd_buffer_h
, 0, 1,
442 (VkBuffer
[]) { radv_buffer_to_handle(&vertex_buffer
) },
443 (VkDeviceSize
[]) { 0 });
445 if (cmd_buffer
->state
.pipeline
!= pipeline
) {
446 radv_CmdBindPipeline(cmd_buffer_h
, VK_PIPELINE_BIND_POINT_GRAPHICS
,
450 radv_CmdDraw(cmd_buffer_h
, 3, 1, 0, 0);
452 radv_cmd_buffer_set_subpass(cmd_buffer
, subpass
, false);
457 build_depthstencil_shader(struct nir_shader
**out_vs
, struct nir_shader
**out_fs
)
459 nir_builder vs_b
, fs_b
;
461 nir_builder_init_simple_shader(&vs_b
, NULL
, MESA_SHADER_VERTEX
, NULL
);
462 nir_builder_init_simple_shader(&fs_b
, NULL
, MESA_SHADER_FRAGMENT
, NULL
);
464 vs_b
.shader
->info
->name
= ralloc_strdup(vs_b
.shader
, "meta_clear_depthstencil_vs");
465 fs_b
.shader
->info
->name
= ralloc_strdup(fs_b
.shader
, "meta_clear_depthstencil_fs");
466 const struct glsl_type
*position_type
= glsl_vec4_type();
468 nir_variable
*vs_in_pos
=
469 nir_variable_create(vs_b
.shader
, nir_var_shader_in
, position_type
,
471 vs_in_pos
->data
.location
= VERT_ATTRIB_GENERIC0
;
473 nir_variable
*vs_out_pos
=
474 nir_variable_create(vs_b
.shader
, nir_var_shader_out
, position_type
,
476 vs_out_pos
->data
.location
= VARYING_SLOT_POS
;
478 nir_copy_var(&vs_b
, vs_out_pos
, vs_in_pos
);
480 *out_vs
= vs_b
.shader
;
481 *out_fs
= fs_b
.shader
;
485 create_depthstencil_renderpass(struct radv_device
*device
,
487 VkRenderPass
*render_pass
)
489 return radv_CreateRenderPass(radv_device_to_handle(device
),
490 &(VkRenderPassCreateInfo
) {
491 .sType
= VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
,
492 .attachmentCount
= 1,
493 .pAttachments
= &(VkAttachmentDescription
) {
494 .format
= VK_FORMAT_UNDEFINED
,
496 .loadOp
= VK_ATTACHMENT_LOAD_OP_LOAD
,
497 .storeOp
= VK_ATTACHMENT_STORE_OP_STORE
,
498 .initialLayout
= VK_IMAGE_LAYOUT_GENERAL
,
499 .finalLayout
= VK_IMAGE_LAYOUT_GENERAL
,
502 .pSubpasses
= &(VkSubpassDescription
) {
503 .pipelineBindPoint
= VK_PIPELINE_BIND_POINT_GRAPHICS
,
504 .inputAttachmentCount
= 0,
505 .colorAttachmentCount
= 0,
506 .pColorAttachments
= NULL
,
507 .pResolveAttachments
= NULL
,
508 .pDepthStencilAttachment
= &(VkAttachmentReference
) {
510 .layout
= VK_IMAGE_LAYOUT_GENERAL
,
512 .preserveAttachmentCount
= 1,
513 .pPreserveAttachments
= (uint32_t[]) { 0 },
515 .dependencyCount
= 0,
516 }, &device
->meta_state
.alloc
, render_pass
);
520 create_depthstencil_pipeline(struct radv_device
*device
,
521 VkImageAspectFlags aspects
,
524 struct radv_pipeline
**pipeline
,
525 VkRenderPass render_pass
)
527 struct nir_shader
*vs_nir
, *fs_nir
;
529 build_depthstencil_shader(&vs_nir
, &fs_nir
);
531 const VkPipelineVertexInputStateCreateInfo vi_state
= {
532 .sType
= VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO
,
533 .vertexBindingDescriptionCount
= 1,
534 .pVertexBindingDescriptions
= (VkVertexInputBindingDescription
[]) {
537 .stride
= sizeof(struct depthstencil_clear_vattrs
),
538 .inputRate
= VK_VERTEX_INPUT_RATE_VERTEX
541 .vertexAttributeDescriptionCount
= 1,
542 .pVertexAttributeDescriptions
= (VkVertexInputAttributeDescription
[]) {
547 .format
= VK_FORMAT_R32G32B32_SFLOAT
,
548 .offset
= offsetof(struct depthstencil_clear_vattrs
, position
),
553 const VkPipelineDepthStencilStateCreateInfo ds_state
= {
554 .sType
= VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
,
555 .depthTestEnable
= (aspects
& VK_IMAGE_ASPECT_DEPTH_BIT
),
556 .depthCompareOp
= VK_COMPARE_OP_ALWAYS
,
557 .depthWriteEnable
= (aspects
& VK_IMAGE_ASPECT_DEPTH_BIT
),
558 .depthBoundsTestEnable
= false,
559 .stencilTestEnable
= (aspects
& VK_IMAGE_ASPECT_STENCIL_BIT
),
561 .passOp
= VK_STENCIL_OP_REPLACE
,
562 .compareOp
= VK_COMPARE_OP_ALWAYS
,
563 .writeMask
= UINT32_MAX
,
564 .reference
= 0, /* dynamic */
566 .back
= { 0 /* dont care */ },
569 const VkPipelineColorBlendStateCreateInfo cb_state
= {
570 .sType
= VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO
,
571 .logicOpEnable
= false,
572 .attachmentCount
= 0,
573 .pAttachments
= NULL
,
576 struct radv_graphics_pipeline_create_info extra
= {
577 .use_rectlist
= true,
580 if (aspects
& VK_IMAGE_ASPECT_DEPTH_BIT
) {
581 extra
.db_depth_clear
= index
== DEPTH_CLEAR_SLOW
? false : true;
582 extra
.db_depth_disable_expclear
= index
== DEPTH_CLEAR_FAST_NO_EXPCLEAR
? true : false;
584 if (aspects
& VK_IMAGE_ASPECT_STENCIL_BIT
) {
585 extra
.db_stencil_clear
= index
== DEPTH_CLEAR_SLOW
? false : true;
586 extra
.db_stencil_disable_expclear
= index
== DEPTH_CLEAR_FAST_NO_EXPCLEAR
? true : false;
588 result
= create_pipeline(device
, radv_render_pass_from_handle(render_pass
),
589 samples
, vs_nir
, fs_nir
, &vi_state
, &ds_state
, &cb_state
,
590 &extra
, &device
->meta_state
.alloc
, pipeline
);
594 static bool depth_view_can_fast_clear(const struct radv_image_view
*iview
,
595 VkImageLayout layout
,
596 const VkClearRect
*clear_rect
)
598 if (clear_rect
->rect
.offset
.x
|| clear_rect
->rect
.offset
.y
||
599 clear_rect
->rect
.extent
.width
!= iview
->extent
.width
||
600 clear_rect
->rect
.extent
.height
!= iview
->extent
.height
)
602 if (iview
->image
->htile
.size
&&
603 iview
->base_mip
== 0 &&
604 iview
->base_layer
== 0 &&
605 radv_layout_can_expclear(iview
->image
, layout
) &&
606 memcmp(&iview
->extent
, &iview
->image
->extent
, sizeof(iview
->extent
)) == 0)
611 static struct radv_pipeline
*
612 pick_depthstencil_pipeline(struct radv_meta_state
*meta_state
,
613 const struct radv_image_view
*iview
,
615 VkImageAspectFlags aspects
,
616 VkImageLayout layout
,
617 const VkClearRect
*clear_rect
,
618 VkClearDepthStencilValue clear_value
)
620 bool fast
= depth_view_can_fast_clear(iview
, layout
, clear_rect
);
621 int index
= DEPTH_CLEAR_SLOW
;
624 /* we don't know the previous clear values, so we always have
625 * the NO_EXPCLEAR path */
626 index
= DEPTH_CLEAR_FAST_NO_EXPCLEAR
;
630 case VK_IMAGE_ASPECT_DEPTH_BIT
| VK_IMAGE_ASPECT_STENCIL_BIT
:
631 return meta_state
->clear
[samples_log2
].depthstencil_pipeline
[index
];
632 case VK_IMAGE_ASPECT_DEPTH_BIT
:
633 return meta_state
->clear
[samples_log2
].depth_only_pipeline
[index
];
634 case VK_IMAGE_ASPECT_STENCIL_BIT
:
635 return meta_state
->clear
[samples_log2
].stencil_only_pipeline
[index
];
637 unreachable("expected depth or stencil aspect");
641 emit_depthstencil_clear(struct radv_cmd_buffer
*cmd_buffer
,
642 const VkClearAttachment
*clear_att
,
643 const VkClearRect
*clear_rect
)
645 struct radv_device
*device
= cmd_buffer
->device
;
646 struct radv_meta_state
*meta_state
= &device
->meta_state
;
647 const struct radv_subpass
*subpass
= cmd_buffer
->state
.subpass
;
648 const struct radv_framebuffer
*fb
= cmd_buffer
->state
.framebuffer
;
649 const uint32_t pass_att
= subpass
->depth_stencil_attachment
.attachment
;
650 VkClearDepthStencilValue clear_value
= clear_att
->clearValue
.depthStencil
;
651 VkImageAspectFlags aspects
= clear_att
->aspectMask
;
652 const struct radv_image_view
*iview
= fb
->attachments
[pass_att
].attachment
;
653 const uint32_t samples
= iview
->image
->samples
;
654 const uint32_t samples_log2
= ffs(samples
) - 1;
655 VkCommandBuffer cmd_buffer_h
= radv_cmd_buffer_to_handle(cmd_buffer
);
658 assert(aspects
== VK_IMAGE_ASPECT_DEPTH_BIT
||
659 aspects
== VK_IMAGE_ASPECT_STENCIL_BIT
||
660 aspects
== (VK_IMAGE_ASPECT_DEPTH_BIT
|
661 VK_IMAGE_ASPECT_STENCIL_BIT
));
662 assert(pass_att
!= VK_ATTACHMENT_UNUSED
);
664 const struct depthstencil_clear_vattrs vertex_data
[3] = {
667 clear_rect
->rect
.offset
.x
,
668 clear_rect
->rect
.offset
.y
,
670 .depth_clear
= clear_value
.depth
,
674 clear_rect
->rect
.offset
.x
,
675 clear_rect
->rect
.offset
.y
+ clear_rect
->rect
.extent
.height
,
677 .depth_clear
= clear_value
.depth
,
681 clear_rect
->rect
.offset
.x
+ clear_rect
->rect
.extent
.width
,
682 clear_rect
->rect
.offset
.y
,
684 .depth_clear
= clear_value
.depth
,
688 radv_cmd_buffer_upload_data(cmd_buffer
, sizeof(vertex_data
), 16, vertex_data
, &offset
);
689 struct radv_buffer vertex_buffer
= {
691 .size
= sizeof(vertex_data
),
692 .bo
= cmd_buffer
->upload
.upload_bo
,
696 if (aspects
& VK_IMAGE_ASPECT_STENCIL_BIT
) {
697 radv_CmdSetStencilReference(cmd_buffer_h
, VK_STENCIL_FACE_FRONT_BIT
,
698 clear_value
.stencil
);
701 radv_CmdBindVertexBuffers(cmd_buffer_h
, 0, 1,
702 (VkBuffer
[]) { radv_buffer_to_handle(&vertex_buffer
) },
703 (VkDeviceSize
[]) { 0 });
705 struct radv_pipeline
*pipeline
= pick_depthstencil_pipeline(meta_state
,
709 subpass
->depth_stencil_attachment
.layout
,
712 if (cmd_buffer
->state
.pipeline
!= pipeline
) {
713 radv_CmdBindPipeline(cmd_buffer_h
, VK_PIPELINE_BIND_POINT_GRAPHICS
,
714 radv_pipeline_to_handle(pipeline
));
717 if (depth_view_can_fast_clear(iview
, subpass
->depth_stencil_attachment
.layout
, clear_rect
))
718 radv_set_depth_clear_regs(cmd_buffer
, iview
->image
, clear_value
, aspects
);
720 radv_CmdDraw(cmd_buffer_h
, 3, 1, 0, 0);
724 static VkFormat pipeline_formats
[] = {
725 VK_FORMAT_R8G8B8A8_UNORM
,
726 VK_FORMAT_R8G8B8A8_UINT
,
727 VK_FORMAT_R8G8B8A8_SINT
,
728 VK_FORMAT_R16G16B16A16_UNORM
,
729 VK_FORMAT_R16G16B16A16_SNORM
,
730 VK_FORMAT_R16G16B16A16_UINT
,
731 VK_FORMAT_R16G16B16A16_SINT
,
732 VK_FORMAT_R32_SFLOAT
,
733 VK_FORMAT_R32G32_SFLOAT
,
734 VK_FORMAT_R32G32B32A32_SFLOAT
738 radv_device_init_meta_clear_state(struct radv_device
*device
)
741 struct radv_meta_state
*state
= &device
->meta_state
;
743 memset(&device
->meta_state
.clear
, 0, sizeof(device
->meta_state
.clear
));
745 for (uint32_t i
= 0; i
< ARRAY_SIZE(state
->clear
); ++i
) {
746 uint32_t samples
= 1 << i
;
747 for (uint32_t j
= 0; j
< ARRAY_SIZE(pipeline_formats
); ++j
) {
748 VkFormat format
= pipeline_formats
[j
];
749 unsigned fs_key
= radv_format_meta_fs_key(format
);
750 assert(!state
->clear
[i
].color_pipelines
[fs_key
]);
752 res
= create_color_renderpass(device
, format
, samples
,
753 &state
->clear
[i
].render_pass
[fs_key
]);
754 if (res
!= VK_SUCCESS
)
757 res
= create_color_pipeline(device
, samples
, 0, &state
->clear
[i
].color_pipelines
[fs_key
],
758 state
->clear
[i
].render_pass
[fs_key
]);
759 if (res
!= VK_SUCCESS
)
764 res
= create_depthstencil_renderpass(device
,
766 &state
->clear
[i
].depthstencil_rp
);
767 if (res
!= VK_SUCCESS
)
770 for (uint32_t j
= 0; j
< NUM_DEPTH_CLEAR_PIPELINES
; j
++) {
771 res
= create_depthstencil_pipeline(device
,
772 VK_IMAGE_ASPECT_DEPTH_BIT
,
775 &state
->clear
[i
].depth_only_pipeline
[j
],
776 state
->clear
[i
].depthstencil_rp
);
777 if (res
!= VK_SUCCESS
)
780 res
= create_depthstencil_pipeline(device
,
781 VK_IMAGE_ASPECT_STENCIL_BIT
,
784 &state
->clear
[i
].stencil_only_pipeline
[j
],
785 state
->clear
[i
].depthstencil_rp
);
786 if (res
!= VK_SUCCESS
)
789 res
= create_depthstencil_pipeline(device
,
790 VK_IMAGE_ASPECT_DEPTH_BIT
|
791 VK_IMAGE_ASPECT_STENCIL_BIT
,
794 &state
->clear
[i
].depthstencil_pipeline
[j
],
795 state
->clear
[i
].depthstencil_rp
);
796 if (res
!= VK_SUCCESS
)
803 radv_device_finish_meta_clear_state(device
);
808 emit_fast_color_clear(struct radv_cmd_buffer
*cmd_buffer
,
809 const VkClearAttachment
*clear_att
,
810 const VkClearRect
*clear_rect
)
812 const struct radv_subpass
*subpass
= cmd_buffer
->state
.subpass
;
813 const uint32_t subpass_att
= clear_att
->colorAttachment
;
814 const uint32_t pass_att
= subpass
->color_attachments
[subpass_att
].attachment
;
815 VkImageLayout image_layout
= subpass
->color_attachments
[subpass_att
].layout
;
816 const struct radv_framebuffer
*fb
= cmd_buffer
->state
.framebuffer
;
817 const struct radv_image_view
*iview
= fb
->attachments
[pass_att
].attachment
;
818 VkClearColorValue clear_value
= clear_att
->clearValue
.color
;
819 uint32_t clear_color
[2];
822 if (!iview
->image
->cmask
.size
&& !iview
->image
->surface
.dcc_size
)
825 if (!(cmd_buffer
->device
->debug_flags
& RADV_DEBUG_FAST_CLEARS
))
828 if (!radv_layout_can_fast_clear(iview
->image
, image_layout
, radv_image_queue_family_mask(iview
->image
, cmd_buffer
->queue_family_index
)))
830 if (vk_format_get_blocksizebits(iview
->image
->vk_format
) > 64)
833 /* don't fast clear 3D */
834 if (iview
->image
->type
== VK_IMAGE_TYPE_3D
)
837 /* all layers are bound */
838 if (iview
->base_layer
> 0)
840 if (iview
->image
->array_size
!= iview
->layer_count
)
843 if (iview
->image
->levels
> 1)
846 if (iview
->image
->surface
.level
[0].mode
< RADEON_SURF_MODE_1D
)
849 if (memcmp(&iview
->extent
, &iview
->image
->extent
, sizeof(iview
->extent
)))
852 if (clear_rect
->rect
.offset
.x
|| clear_rect
->rect
.offset
.y
||
853 clear_rect
->rect
.extent
.width
!= iview
->image
->extent
.width
||
854 clear_rect
->rect
.extent
.height
!= iview
->image
->extent
.height
)
857 if (clear_rect
->baseArrayLayer
!= 0)
859 if (clear_rect
->layerCount
!= iview
->image
->array_size
)
863 ret
= radv_format_pack_clear_color(iview
->image
->vk_format
,
864 clear_color
, &clear_value
);
868 cmd_buffer
->state
.flush_bits
|= RADV_CMD_FLAG_FLUSH_AND_INV_CB
|
869 RADV_CMD_FLAG_FLUSH_AND_INV_CB_META
;
870 si_emit_cache_flush(cmd_buffer
);
871 /* clear cmask buffer */
872 if (iview
->image
->surface
.dcc_size
) {
873 radv_fill_buffer(cmd_buffer
, iview
->image
->bo
,
874 iview
->image
->offset
+ iview
->image
->dcc_offset
,
875 iview
->image
->surface
.dcc_size
, 0x20202020);
877 radv_fill_buffer(cmd_buffer
, iview
->image
->bo
,
878 iview
->image
->offset
+ iview
->image
->cmask
.offset
,
879 iview
->image
->cmask
.size
, 0);
881 cmd_buffer
->state
.flush_bits
|= RADV_CMD_FLAG_CS_PARTIAL_FLUSH
|
882 RADV_CMD_FLAG_INV_VMEM_L1
|
883 RADV_CMD_FLAG_INV_GLOBAL_L2
;
885 radv_set_color_clear_regs(cmd_buffer
, iview
->image
, subpass_att
, clear_color
);
893 * The parameters mean that same as those in vkCmdClearAttachments.
896 emit_clear(struct radv_cmd_buffer
*cmd_buffer
,
897 const VkClearAttachment
*clear_att
,
898 const VkClearRect
*clear_rect
)
900 if (clear_att
->aspectMask
& VK_IMAGE_ASPECT_COLOR_BIT
) {
902 if (!emit_fast_color_clear(cmd_buffer
, clear_att
, clear_rect
))
903 emit_color_clear(cmd_buffer
, clear_att
, clear_rect
);
905 assert(clear_att
->aspectMask
& (VK_IMAGE_ASPECT_DEPTH_BIT
|
906 VK_IMAGE_ASPECT_STENCIL_BIT
));
907 emit_depthstencil_clear(cmd_buffer
, clear_att
, clear_rect
);
912 subpass_needs_clear(const struct radv_cmd_buffer
*cmd_buffer
)
914 const struct radv_cmd_state
*cmd_state
= &cmd_buffer
->state
;
917 if (!cmd_state
->subpass
)
919 ds
= cmd_state
->subpass
->depth_stencil_attachment
.attachment
;
920 for (uint32_t i
= 0; i
< cmd_state
->subpass
->color_count
; ++i
) {
921 uint32_t a
= cmd_state
->subpass
->color_attachments
[i
].attachment
;
922 if (cmd_state
->attachments
[a
].pending_clear_aspects
) {
927 if (ds
!= VK_ATTACHMENT_UNUSED
&&
928 cmd_state
->attachments
[ds
].pending_clear_aspects
) {
936 * Emit any pending attachment clears for the current subpass.
938 * @see radv_attachment_state::pending_clear_aspects
941 radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer
*cmd_buffer
)
943 struct radv_cmd_state
*cmd_state
= &cmd_buffer
->state
;
944 struct radv_meta_saved_state saved_state
;
946 if (!subpass_needs_clear(cmd_buffer
))
949 radv_meta_save_graphics_reset_vport_scissor(&saved_state
, cmd_buffer
);
951 if (cmd_state
->framebuffer
->layers
> 1)
952 radv_finishme("clearing multi-layer framebuffer");
954 VkClearRect clear_rect
= {
955 .rect
= cmd_state
->render_area
,
957 .layerCount
= 1, /* FINISHME: clear multi-layer framebuffer */
960 for (uint32_t i
= 0; i
< cmd_state
->subpass
->color_count
; ++i
) {
961 uint32_t a
= cmd_state
->subpass
->color_attachments
[i
].attachment
;
963 if (!cmd_state
->attachments
[a
].pending_clear_aspects
)
966 assert(cmd_state
->attachments
[a
].pending_clear_aspects
==
967 VK_IMAGE_ASPECT_COLOR_BIT
);
969 VkClearAttachment clear_att
= {
970 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
971 .colorAttachment
= i
, /* Use attachment index relative to subpass */
972 .clearValue
= cmd_state
->attachments
[a
].clear_value
,
975 emit_clear(cmd_buffer
, &clear_att
, &clear_rect
);
976 cmd_state
->attachments
[a
].pending_clear_aspects
= 0;
979 uint32_t ds
= cmd_state
->subpass
->depth_stencil_attachment
.attachment
;
981 if (ds
!= VK_ATTACHMENT_UNUSED
) {
983 if (cmd_state
->attachments
[ds
].pending_clear_aspects
) {
985 VkClearAttachment clear_att
= {
986 .aspectMask
= cmd_state
->attachments
[ds
].pending_clear_aspects
,
987 .clearValue
= cmd_state
->attachments
[ds
].clear_value
,
990 emit_clear(cmd_buffer
, &clear_att
, &clear_rect
);
991 cmd_state
->attachments
[ds
].pending_clear_aspects
= 0;
995 radv_meta_restore(&saved_state
, cmd_buffer
);
999 radv_clear_image_layer(struct radv_cmd_buffer
*cmd_buffer
,
1000 struct radv_image
*image
,
1001 VkImageLayout image_layout
,
1002 const VkImageSubresourceRange
*range
,
1003 VkFormat format
, int level
, int layer
,
1004 const VkClearValue
*clear_val
)
1006 VkDevice device_h
= radv_device_to_handle(cmd_buffer
->device
);
1007 struct radv_image_view iview
;
1008 radv_image_view_init(&iview
, cmd_buffer
->device
,
1009 &(VkImageViewCreateInfo
) {
1010 .sType
= VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
,
1011 .image
= radv_image_to_handle(image
),
1012 .viewType
= radv_meta_get_view_type(image
),
1014 .subresourceRange
= {
1015 .aspectMask
= range
->aspectMask
,
1016 .baseMipLevel
= range
->baseMipLevel
+ level
,
1018 .baseArrayLayer
= range
->baseArrayLayer
+ layer
,
1022 cmd_buffer
, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
);
1025 radv_CreateFramebuffer(device_h
,
1026 &(VkFramebufferCreateInfo
) {
1027 .sType
= VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
,
1028 .attachmentCount
= 1,
1029 .pAttachments
= (VkImageView
[]) {
1030 radv_image_view_to_handle(&iview
),
1032 .width
= iview
.extent
.width
,
1033 .height
= iview
.extent
.height
,
1036 &cmd_buffer
->pool
->alloc
,
1039 VkAttachmentDescription att_desc
= {
1040 .format
= iview
.vk_format
,
1041 .loadOp
= VK_ATTACHMENT_LOAD_OP_LOAD
,
1042 .storeOp
= VK_ATTACHMENT_STORE_OP_STORE
,
1043 .stencilLoadOp
= VK_ATTACHMENT_LOAD_OP_LOAD
,
1044 .stencilStoreOp
= VK_ATTACHMENT_STORE_OP_STORE
,
1045 .initialLayout
= image_layout
,
1046 .finalLayout
= image_layout
,
1049 VkSubpassDescription subpass_desc
= {
1050 .pipelineBindPoint
= VK_PIPELINE_BIND_POINT_GRAPHICS
,
1051 .inputAttachmentCount
= 0,
1052 .colorAttachmentCount
= 0,
1053 .pColorAttachments
= NULL
,
1054 .pResolveAttachments
= NULL
,
1055 .pDepthStencilAttachment
= NULL
,
1056 .preserveAttachmentCount
= 0,
1057 .pPreserveAttachments
= NULL
,
1060 const VkAttachmentReference att_ref
= {
1062 .layout
= image_layout
,
1065 if (range
->aspectMask
& VK_IMAGE_ASPECT_COLOR_BIT
) {
1066 subpass_desc
.colorAttachmentCount
= 1;
1067 subpass_desc
.pColorAttachments
= &att_ref
;
1069 subpass_desc
.pDepthStencilAttachment
= &att_ref
;
1073 radv_CreateRenderPass(device_h
,
1074 &(VkRenderPassCreateInfo
) {
1075 .sType
= VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
,
1076 .attachmentCount
= 1,
1077 .pAttachments
= &att_desc
,
1079 .pSubpasses
= &subpass_desc
,
1081 &cmd_buffer
->pool
->alloc
,
1084 radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer
),
1085 &(VkRenderPassBeginInfo
) {
1086 .sType
= VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO
,
1088 .offset
= { 0, 0, },
1090 .width
= iview
.extent
.width
,
1091 .height
= iview
.extent
.height
,
1096 .clearValueCount
= 0,
1097 .pClearValues
= NULL
,
1099 VK_SUBPASS_CONTENTS_INLINE
);
1101 VkClearAttachment clear_att
= {
1102 .aspectMask
= range
->aspectMask
,
1103 .colorAttachment
= 0,
1104 .clearValue
= *clear_val
,
1107 VkClearRect clear_rect
= {
1110 .extent
= { iview
.extent
.width
, iview
.extent
.height
},
1112 .baseArrayLayer
= range
->baseArrayLayer
,
1113 .layerCount
= 1, /* FINISHME: clear multi-layer framebuffer */
1116 emit_clear(cmd_buffer
, &clear_att
, &clear_rect
);
1118 radv_CmdEndRenderPass(radv_cmd_buffer_to_handle(cmd_buffer
));
1119 radv_DestroyRenderPass(device_h
, pass
,
1120 &cmd_buffer
->pool
->alloc
);
1121 radv_DestroyFramebuffer(device_h
, fb
,
1122 &cmd_buffer
->pool
->alloc
);
1125 radv_cmd_clear_image(struct radv_cmd_buffer
*cmd_buffer
,
1126 struct radv_image
*image
,
1127 VkImageLayout image_layout
,
1128 const VkClearValue
*clear_value
,
1129 uint32_t range_count
,
1130 const VkImageSubresourceRange
*ranges
,
1133 VkFormat format
= image
->vk_format
;
1134 VkClearValue internal_clear_value
= *clear_value
;
1136 if (format
== VK_FORMAT_E5B9G9R9_UFLOAT_PACK32
) {
1138 format
= VK_FORMAT_R32_UINT
;
1139 value
= float3_to_rgb9e5(clear_value
->color
.float32
);
1140 internal_clear_value
.color
.uint32
[0] = value
;
1143 for (uint32_t r
= 0; r
< range_count
; r
++) {
1144 const VkImageSubresourceRange
*range
= &ranges
[r
];
1145 for (uint32_t l
= 0; l
< radv_get_levelCount(image
, range
); ++l
) {
1146 const uint32_t layer_count
= image
->type
== VK_IMAGE_TYPE_3D
?
1147 radv_minify(image
->extent
.depth
, range
->baseMipLevel
+ l
) :
1148 radv_get_layerCount(image
, range
);
1149 for (uint32_t s
= 0; s
< layer_count
; ++s
) {
1152 struct radv_meta_blit2d_surf surf
;
1153 surf
.format
= format
;
1155 surf
.level
= range
->baseMipLevel
+ l
;
1156 surf
.layer
= range
->baseArrayLayer
+ s
;
1157 surf
.aspect_mask
= range
->aspectMask
;
1158 radv_meta_clear_image_cs(cmd_buffer
, &surf
,
1159 &internal_clear_value
.color
);
1161 radv_clear_image_layer(cmd_buffer
, image
, image_layout
,
1162 range
, format
, l
, s
, &internal_clear_value
);
1169 union meta_saved_state
{
1170 struct radv_meta_saved_state gfx
;
1171 struct radv_meta_saved_compute_state compute
;
1174 void radv_CmdClearColorImage(
1175 VkCommandBuffer commandBuffer
,
1177 VkImageLayout imageLayout
,
1178 const VkClearColorValue
* pColor
,
1179 uint32_t rangeCount
,
1180 const VkImageSubresourceRange
* pRanges
)
1182 RADV_FROM_HANDLE(radv_cmd_buffer
, cmd_buffer
, commandBuffer
);
1183 RADV_FROM_HANDLE(radv_image
, image
, image_h
);
1184 union meta_saved_state saved_state
;
1185 bool cs
= cmd_buffer
->queue_family_index
== RADV_QUEUE_COMPUTE
;
1188 radv_meta_begin_cleari(cmd_buffer
, &saved_state
.compute
);
1190 radv_meta_save_graphics_reset_vport_scissor(&saved_state
.gfx
, cmd_buffer
);
1192 radv_cmd_clear_image(cmd_buffer
, image
, imageLayout
,
1193 (const VkClearValue
*) pColor
,
1194 rangeCount
, pRanges
, cs
);
1197 radv_meta_end_cleari(cmd_buffer
, &saved_state
.compute
);
1199 radv_meta_restore(&saved_state
.gfx
, cmd_buffer
);
1202 void radv_CmdClearDepthStencilImage(
1203 VkCommandBuffer commandBuffer
,
1205 VkImageLayout imageLayout
,
1206 const VkClearDepthStencilValue
* pDepthStencil
,
1207 uint32_t rangeCount
,
1208 const VkImageSubresourceRange
* pRanges
)
1210 RADV_FROM_HANDLE(radv_cmd_buffer
, cmd_buffer
, commandBuffer
);
1211 RADV_FROM_HANDLE(radv_image
, image
, image_h
);
1212 struct radv_meta_saved_state saved_state
;
1214 radv_meta_save_graphics_reset_vport_scissor(&saved_state
, cmd_buffer
);
1216 radv_cmd_clear_image(cmd_buffer
, image
, imageLayout
,
1217 (const VkClearValue
*) pDepthStencil
,
1218 rangeCount
, pRanges
, false);
1220 radv_meta_restore(&saved_state
, cmd_buffer
);
1223 void radv_CmdClearAttachments(
1224 VkCommandBuffer commandBuffer
,
1225 uint32_t attachmentCount
,
1226 const VkClearAttachment
* pAttachments
,
1228 const VkClearRect
* pRects
)
1230 RADV_FROM_HANDLE(radv_cmd_buffer
, cmd_buffer
, commandBuffer
);
1231 struct radv_meta_saved_state saved_state
;
1233 if (!cmd_buffer
->state
.subpass
)
1236 radv_meta_save_graphics_reset_vport_scissor(&saved_state
, cmd_buffer
);
1238 /* FINISHME: We can do better than this dumb loop. It thrashes too much
1241 for (uint32_t a
= 0; a
< attachmentCount
; ++a
) {
1242 for (uint32_t r
= 0; r
< rectCount
; ++r
) {
1243 emit_clear(cmd_buffer
, &pAttachments
[a
], &pRects
[r
]);
1247 radv_meta_restore(&saved_state
, cmd_buffer
);