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
25 #include "anv_meta_clear.h"
26 #include "anv_private.h"
27 #include "glsl/nir/nir_builder.h"
29 /** Vertex attributes for color clears. */
30 struct color_clear_vattrs
{
31 struct anv_vue_header vue_header
;
32 float position
[2]; /**< 3DPRIM_RECTLIST */
33 VkClearColorValue color
;
36 /** Vertex attributes for depthstencil clears. */
37 struct depthstencil_clear_vattrs
{
38 struct anv_vue_header vue_header
;
39 float position
[2]; /*<< 3DPRIM_RECTLIST */
43 meta_clear_begin(struct anv_meta_saved_state
*saved_state
,
44 struct anv_cmd_buffer
*cmd_buffer
)
46 anv_meta_save(saved_state
, cmd_buffer
,
47 (1 << VK_DYNAMIC_STATE_VIEWPORT
) |
48 (1 << VK_DYNAMIC_STATE_SCISSOR
) |
49 (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE
));
51 cmd_buffer
->state
.dynamic
.viewport
.count
= 0;
52 cmd_buffer
->state
.dynamic
.scissor
.count
= 0;
56 meta_clear_end(struct anv_meta_saved_state
*saved_state
,
57 struct anv_cmd_buffer
*cmd_buffer
)
59 anv_meta_restore(saved_state
, cmd_buffer
);
63 build_color_shaders(struct nir_shader
**out_vs
,
64 struct nir_shader
**out_fs
,
70 nir_builder_init_simple_shader(&vs_b
, NULL
, MESA_SHADER_VERTEX
, NULL
);
71 nir_builder_init_simple_shader(&fs_b
, NULL
, MESA_SHADER_FRAGMENT
, NULL
);
73 vs_b
.shader
->info
.name
= ralloc_strdup(vs_b
.shader
, "meta_clear_color_vs");
74 fs_b
.shader
->info
.name
= ralloc_strdup(fs_b
.shader
, "meta_clear_color_fs");
76 const struct glsl_type
*position_type
= glsl_vec4_type();
77 const struct glsl_type
*color_type
= glsl_vec4_type();
79 nir_variable
*vs_in_pos
=
80 nir_variable_create(vs_b
.shader
, nir_var_shader_in
, position_type
,
82 vs_in_pos
->data
.location
= VERT_ATTRIB_GENERIC0
;
84 nir_variable
*vs_out_pos
=
85 nir_variable_create(vs_b
.shader
, nir_var_shader_out
, position_type
,
87 vs_out_pos
->data
.location
= VARYING_SLOT_POS
;
89 nir_variable
*vs_in_color
=
90 nir_variable_create(vs_b
.shader
, nir_var_shader_in
, color_type
,
92 vs_in_color
->data
.location
= VERT_ATTRIB_GENERIC1
;
94 nir_variable
*vs_out_color
=
95 nir_variable_create(vs_b
.shader
, nir_var_shader_out
, color_type
,
97 vs_out_color
->data
.location
= VARYING_SLOT_VAR0
;
98 vs_out_color
->data
.interpolation
= INTERP_QUALIFIER_FLAT
;
100 nir_variable
*fs_in_color
=
101 nir_variable_create(fs_b
.shader
, nir_var_shader_in
, color_type
,
103 fs_in_color
->data
.location
= vs_out_color
->data
.location
;
104 fs_in_color
->data
.interpolation
= vs_out_color
->data
.interpolation
;
106 nir_variable
*fs_out_color
=
107 nir_variable_create(fs_b
.shader
, nir_var_shader_out
, color_type
,
109 fs_out_color
->data
.location
= FRAG_RESULT_DATA0
+ frag_output
;
111 nir_copy_var(&vs_b
, vs_out_pos
, vs_in_pos
);
112 nir_copy_var(&vs_b
, vs_out_color
, vs_in_color
);
113 nir_copy_var(&fs_b
, fs_out_color
, fs_in_color
);
115 *out_vs
= vs_b
.shader
;
116 *out_fs
= fs_b
.shader
;
120 create_pipeline(struct anv_device
*device
,
121 struct nir_shader
*vs_nir
,
122 struct nir_shader
*fs_nir
,
123 const VkPipelineVertexInputStateCreateInfo
*vi_state
,
124 const VkPipelineDepthStencilStateCreateInfo
*ds_state
,
125 const VkPipelineColorBlendStateCreateInfo
*cb_state
,
126 const VkAllocationCallbacks
*alloc
,
128 struct anv_pipeline
**pipeline
)
130 VkDevice device_h
= anv_device_to_handle(device
);
133 struct anv_shader_module vs_m
= { .nir
= vs_nir
};
134 struct anv_shader_module fs_m
= { .nir
= fs_nir
};
136 VkPipeline pipeline_h
;
137 result
= anv_graphics_pipeline_create(device_h
,
139 &(VkGraphicsPipelineCreateInfo
) {
140 .sType
= VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
,
142 .pStages
= (VkPipelineShaderStageCreateInfo
[]) {
144 .sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
,
145 .stage
= VK_SHADER_STAGE_VERTEX_BIT
,
146 .module
= anv_shader_module_to_handle(&vs_m
),
150 .sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
,
151 .stage
= VK_SHADER_STAGE_FRAGMENT_BIT
,
152 .module
= anv_shader_module_to_handle(&fs_m
),
156 .pVertexInputState
= vi_state
,
157 .pInputAssemblyState
= &(VkPipelineInputAssemblyStateCreateInfo
) {
158 .sType
= VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO
,
159 .topology
= VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
,
160 .primitiveRestartEnable
= false,
162 .pViewportState
= &(VkPipelineViewportStateCreateInfo
) {
163 .sType
= VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO
,
165 .pViewports
= NULL
, /* dynamic */
167 .pScissors
= NULL
, /* dynamic */
169 .pRasterizationState
= &(VkPipelineRasterizationStateCreateInfo
) {
170 .sType
= VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO
,
171 .rasterizerDiscardEnable
= false,
172 .polygonMode
= VK_POLYGON_MODE_FILL
,
173 .cullMode
= VK_CULL_MODE_NONE
,
174 .frontFace
= VK_FRONT_FACE_COUNTER_CLOCKWISE
,
175 .depthBiasEnable
= false,
177 .pMultisampleState
= &(VkPipelineMultisampleStateCreateInfo
) {
178 .sType
= VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO
,
179 .rasterizationSamples
= 1, /* FINISHME: Multisampling */
180 .sampleShadingEnable
= false,
181 .pSampleMask
= (VkSampleMask
[]) { UINT32_MAX
},
182 .alphaToCoverageEnable
= false,
183 .alphaToOneEnable
= false,
185 .pDepthStencilState
= ds_state
,
186 .pColorBlendState
= cb_state
,
187 .pDynamicState
= &(VkPipelineDynamicStateCreateInfo
) {
188 /* The meta clear pipeline declares all state as dynamic.
189 * As a consequence, vkCmdBindPipeline writes no dynamic state
190 * to the cmd buffer. Therefore, at the end of the meta clear,
191 * we need only restore dynamic state was vkCmdSet.
193 .sType
= VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO
,
194 .dynamicStateCount
= 9,
195 .pDynamicStates
= (VkDynamicState
[]) {
196 VK_DYNAMIC_STATE_VIEWPORT
,
197 VK_DYNAMIC_STATE_SCISSOR
,
198 VK_DYNAMIC_STATE_LINE_WIDTH
,
199 VK_DYNAMIC_STATE_DEPTH_BIAS
,
200 VK_DYNAMIC_STATE_BLEND_CONSTANTS
,
201 VK_DYNAMIC_STATE_DEPTH_BOUNDS
,
202 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK
,
203 VK_DYNAMIC_STATE_STENCIL_WRITE_MASK
,
204 VK_DYNAMIC_STATE_STENCIL_REFERENCE
,
208 .renderPass
= anv_render_pass_to_handle(&anv_meta_dummy_renderpass
),
211 &(struct anv_graphics_pipeline_create_info
) {
212 .color_attachment_count
= MAX_RTS
,
213 .use_repclear
= use_repclear
,
214 .disable_viewport
= true,
224 *pipeline
= anv_pipeline_from_handle(pipeline_h
);
230 create_color_pipeline(struct anv_device
*device
, uint32_t frag_output
,
231 struct anv_pipeline
**pipeline
)
233 struct nir_shader
*vs_nir
;
234 struct nir_shader
*fs_nir
;
235 build_color_shaders(&vs_nir
, &fs_nir
, frag_output
);
237 const VkPipelineVertexInputStateCreateInfo vi_state
= {
238 .sType
= VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO
,
239 .vertexBindingDescriptionCount
= 1,
240 .pVertexBindingDescriptions
= (VkVertexInputBindingDescription
[]) {
243 .stride
= sizeof(struct color_clear_vattrs
),
244 .inputRate
= VK_VERTEX_INPUT_RATE_VERTEX
247 .vertexAttributeDescriptionCount
= 3,
248 .pVertexAttributeDescriptions
= (VkVertexInputAttributeDescription
[]) {
253 .format
= VK_FORMAT_R32G32B32A32_UINT
,
254 .offset
= offsetof(struct color_clear_vattrs
, vue_header
),
260 .format
= VK_FORMAT_R32G32_SFLOAT
,
261 .offset
= offsetof(struct color_clear_vattrs
, position
),
267 .format
= VK_FORMAT_R32G32B32A32_SFLOAT
,
268 .offset
= offsetof(struct color_clear_vattrs
, color
),
273 const VkPipelineDepthStencilStateCreateInfo ds_state
= {
274 .sType
= VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
,
275 .depthTestEnable
= false,
276 .depthWriteEnable
= false,
277 .depthBoundsTestEnable
= false,
278 .stencilTestEnable
= false,
281 const VkPipelineColorBlendStateCreateInfo cb_state
= {
282 .sType
= VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO
,
283 .logicOpEnable
= false,
284 .attachmentCount
= 1,
285 .pAttachments
= (VkPipelineColorBlendAttachmentState
[]) {
287 .blendEnable
= false,
288 .colorWriteMask
= VK_COLOR_COMPONENT_A_BIT
|
289 VK_COLOR_COMPONENT_R_BIT
|
290 VK_COLOR_COMPONENT_G_BIT
|
291 VK_COLOR_COMPONENT_B_BIT
,
296 /* Disable repclear because we do not want the compiler to replace the
297 * shader. We need the shader to write to the specified color attachment,
298 * but the repclear shader writes to all color attachments.
301 create_pipeline(device
, vs_nir
, fs_nir
, &vi_state
, &ds_state
,
302 &cb_state
, NULL
, /*use_repclear*/ false,
307 init_color_pipelines(struct anv_device
*device
)
310 struct anv_pipeline
**pipelines
= device
->meta_state
.clear
.color_pipelines
;
311 uint32_t n
= ARRAY_SIZE(device
->meta_state
.clear
.color_pipelines
);
313 zero(device
->meta_state
.clear
.color_pipelines
);
315 for (uint32_t i
= 0; i
< n
; ++i
) {
316 result
= create_color_pipeline(device
, i
, &pipelines
[i
]);
324 for (uint32_t i
= 0; i
< n
; ++i
) {
325 if (pipelines
[i
] == NULL
)
328 anv_DestroyPipeline(anv_device_to_handle(device
),
329 anv_pipeline_to_handle(pipelines
[i
]),
337 emit_color_clear(struct anv_cmd_buffer
*cmd_buffer
,
338 const VkClearAttachment
*clear_att
)
340 struct anv_device
*device
= cmd_buffer
->device
;
341 const struct anv_subpass
*subpass
= cmd_buffer
->state
.subpass
;
342 const struct anv_framebuffer
*fb
= cmd_buffer
->state
.framebuffer
;
343 VkClearColorValue clear_value
= clear_att
->clearValue
.color
;
344 struct anv_pipeline
*pipeline
=
345 device
->meta_state
.clear
.color_pipelines
[clear_att
->colorAttachment
];
347 VkCommandBuffer cmd_buffer_h
= anv_cmd_buffer_to_handle(cmd_buffer
);
348 VkPipeline pipeline_h
= anv_pipeline_to_handle(pipeline
);
350 assert(clear_att
->aspectMask
== VK_IMAGE_ASPECT_COLOR_BIT
);
351 assert(clear_att
->colorAttachment
< subpass
->color_count
);
353 const struct color_clear_vattrs vertex_data
[3] = {
356 .position
= { 0.0, 0.0 },
357 .color
= clear_value
,
361 .position
= { fb
->width
, 0.0 },
362 .color
= clear_value
,
366 .position
= { fb
->width
, fb
->height
},
367 .color
= clear_value
,
371 struct anv_state state
=
372 anv_cmd_buffer_emit_dynamic(cmd_buffer
, vertex_data
, sizeof(vertex_data
), 16);
374 struct anv_buffer vertex_buffer
= {
376 .size
= sizeof(vertex_data
),
377 .bo
= &device
->dynamic_state_block_pool
.bo
,
378 .offset
= state
.offset
,
381 ANV_CALL(CmdSetViewport
)(cmd_buffer_h
, 0, 1,
387 .height
= fb
->height
,
393 ANV_CALL(CmdSetScissor
)(cmd_buffer_h
, 0, 1,
397 .extent
= { fb
->width
, fb
->height
},
401 ANV_CALL(CmdBindVertexBuffers
)(cmd_buffer_h
, 0, 1,
402 (VkBuffer
[]) { anv_buffer_to_handle(&vertex_buffer
) },
403 (VkDeviceSize
[]) { 0 });
405 if (cmd_buffer
->state
.pipeline
!= pipeline
) {
406 ANV_CALL(CmdBindPipeline
)(cmd_buffer_h
, VK_PIPELINE_BIND_POINT_GRAPHICS
,
410 ANV_CALL(CmdDraw
)(cmd_buffer_h
, 3, 1, 0, 0);
415 build_depthstencil_shaders(struct nir_shader
**out_vs
,
416 struct nir_shader
**out_fs
)
421 nir_builder_init_simple_shader(&vs_b
, NULL
, MESA_SHADER_VERTEX
, NULL
);
422 nir_builder_init_simple_shader(&fs_b
, NULL
, MESA_SHADER_FRAGMENT
, NULL
);
424 vs_b
.shader
->info
.name
= ralloc_strdup(vs_b
.shader
, "meta_clear_depthstencil_vs");
425 fs_b
.shader
->info
.name
= ralloc_strdup(fs_b
.shader
, "meta_clear_depthstencil_fs");
427 const struct glsl_type
*position_type
= glsl_vec4_type();
429 nir_variable
*vs_in_pos
=
430 nir_variable_create(vs_b
.shader
, nir_var_shader_in
, position_type
,
432 vs_in_pos
->data
.location
= VERT_ATTRIB_GENERIC0
;
434 nir_variable
*vs_out_pos
=
435 nir_variable_create(vs_b
.shader
, nir_var_shader_out
, position_type
,
437 vs_out_pos
->data
.location
= VARYING_SLOT_POS
;
439 nir_copy_var(&vs_b
, vs_out_pos
, vs_in_pos
);
441 *out_vs
= vs_b
.shader
;
442 *out_fs
= fs_b
.shader
;
446 create_depthstencil_pipeline(struct anv_device
*device
,
447 VkImageAspectFlags aspects
,
448 struct anv_pipeline
**pipeline
)
450 struct nir_shader
*vs_nir
;
451 struct nir_shader
*fs_nir
;
453 build_depthstencil_shaders(&vs_nir
, &fs_nir
);
455 const VkPipelineVertexInputStateCreateInfo vi_state
= {
456 .sType
= VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO
,
457 .vertexBindingDescriptionCount
= 1,
458 .pVertexBindingDescriptions
= (VkVertexInputBindingDescription
[]) {
461 .stride
= sizeof(struct depthstencil_clear_vattrs
),
462 .inputRate
= VK_VERTEX_INPUT_RATE_VERTEX
465 .vertexAttributeDescriptionCount
= 2,
466 .pVertexAttributeDescriptions
= (VkVertexInputAttributeDescription
[]) {
471 .format
= VK_FORMAT_R32G32B32A32_UINT
,
472 .offset
= offsetof(struct depthstencil_clear_vattrs
, vue_header
),
478 .format
= VK_FORMAT_R32G32_SFLOAT
,
479 .offset
= offsetof(struct depthstencil_clear_vattrs
, position
),
484 const VkPipelineDepthStencilStateCreateInfo ds_state
= {
485 .sType
= VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
,
486 .depthTestEnable
= (aspects
& VK_IMAGE_ASPECT_DEPTH_BIT
),
487 .depthCompareOp
= VK_COMPARE_OP_ALWAYS
,
488 .depthWriteEnable
= (aspects
& VK_IMAGE_ASPECT_DEPTH_BIT
),
489 .depthBoundsTestEnable
= false,
490 .stencilTestEnable
= (aspects
& VK_IMAGE_ASPECT_STENCIL_BIT
),
492 .passOp
= VK_STENCIL_OP_REPLACE
,
493 .compareOp
= VK_COMPARE_OP_ALWAYS
,
494 .writeMask
= UINT32_MAX
,
495 .reference
= 0, /* dynamic */
497 .back
= { 0 /* dont care */ },
500 const VkPipelineColorBlendStateCreateInfo cb_state
= {
501 .sType
= VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO
,
502 .logicOpEnable
= false,
503 .attachmentCount
= 0,
504 .pAttachments
= NULL
,
507 return create_pipeline(device
, vs_nir
, fs_nir
, &vi_state
, &ds_state
,
508 &cb_state
, NULL
, /*use_repclear*/ true, pipeline
);
512 emit_depthstencil_clear(struct anv_cmd_buffer
*cmd_buffer
,
513 const VkClearAttachment
*clear_att
)
515 struct anv_device
*device
= cmd_buffer
->device
;
516 const struct anv_subpass
*subpass
= cmd_buffer
->state
.subpass
;
517 const struct anv_framebuffer
*fb
= cmd_buffer
->state
.framebuffer
;
518 uint32_t attachment
= subpass
->depth_stencil_attachment
;
519 VkClearDepthStencilValue clear_value
= clear_att
->clearValue
.depthStencil
;
520 VkImageAspectFlags aspects
= clear_att
->aspectMask
;
522 VkCommandBuffer cmd_buffer_h
= anv_cmd_buffer_to_handle(cmd_buffer
);
524 assert(aspects
== VK_IMAGE_ASPECT_DEPTH_BIT
||
525 aspects
== VK_IMAGE_ASPECT_STENCIL_BIT
||
526 aspects
== (VK_IMAGE_ASPECT_DEPTH_BIT
|
527 VK_IMAGE_ASPECT_STENCIL_BIT
));
528 assert(attachment
!= VK_ATTACHMENT_UNUSED
);
530 const struct depthstencil_clear_vattrs vertex_data
[3] = {
533 .position
= { 0.0, 0.0 },
537 .position
= { fb
->width
, 0.0 },
541 .position
= { fb
->width
, fb
->height
},
545 struct anv_state state
=
546 anv_cmd_buffer_emit_dynamic(cmd_buffer
, vertex_data
, sizeof(vertex_data
), 16);
548 struct anv_buffer vertex_buffer
= {
550 .size
= sizeof(vertex_data
),
551 .bo
= &device
->dynamic_state_block_pool
.bo
,
552 .offset
= state
.offset
,
555 ANV_CALL(CmdSetViewport
)(cmd_buffer_h
, 0, 1,
561 .height
= fb
->height
,
563 /* Ignored when clearing only stencil. */
564 .minDepth
= clear_value
.depth
,
565 .maxDepth
= clear_value
.depth
,
569 ANV_CALL(CmdSetScissor
)(cmd_buffer_h
, 0, 1,
573 .extent
= { fb
->width
, fb
->height
},
577 if (aspects
& VK_IMAGE_ASPECT_STENCIL_BIT
) {
578 ANV_CALL(CmdSetStencilReference
)(cmd_buffer_h
, VK_STENCIL_FACE_FRONT_BIT
,
579 clear_value
.stencil
);
582 ANV_CALL(CmdBindVertexBuffers
)(cmd_buffer_h
, 0, 1,
583 (VkBuffer
[]) { anv_buffer_to_handle(&vertex_buffer
) },
584 (VkDeviceSize
[]) { 0 });
586 struct anv_pipeline
*pipeline
;
588 case VK_IMAGE_ASPECT_DEPTH_BIT
| VK_IMAGE_ASPECT_STENCIL_BIT
:
589 pipeline
= device
->meta_state
.clear
.depthstencil_pipeline
;
591 case VK_IMAGE_ASPECT_DEPTH_BIT
:
592 pipeline
= device
->meta_state
.clear
.depth_only_pipeline
;
594 case VK_IMAGE_ASPECT_STENCIL_BIT
:
595 pipeline
= device
->meta_state
.clear
.stencil_only_pipeline
;
598 unreachable("expected depth or stencil aspect");
601 if (cmd_buffer
->state
.pipeline
!= pipeline
) {
602 ANV_CALL(CmdBindPipeline
)(cmd_buffer_h
, VK_PIPELINE_BIND_POINT_GRAPHICS
,
603 anv_pipeline_to_handle(pipeline
));
606 ANV_CALL(CmdDraw
)(cmd_buffer_h
, 3, 1, 0, 0);
610 init_depthstencil_pipelines(struct anv_device
*device
)
613 struct anv_meta_state
*state
= &device
->meta_state
;
616 create_depthstencil_pipeline(device
, VK_IMAGE_ASPECT_DEPTH_BIT
,
617 &state
->clear
.depth_only_pipeline
);
618 if (result
!= VK_SUCCESS
)
622 create_depthstencil_pipeline(device
, VK_IMAGE_ASPECT_STENCIL_BIT
,
623 &state
->clear
.stencil_only_pipeline
);
624 if (result
!= VK_SUCCESS
)
625 goto fail_depth_only
;
628 create_depthstencil_pipeline(device
,
629 VK_IMAGE_ASPECT_DEPTH_BIT
|
630 VK_IMAGE_ASPECT_STENCIL_BIT
,
631 &state
->clear
.depthstencil_pipeline
);
632 if (result
!= VK_SUCCESS
)
633 goto fail_stencil_only
;
638 anv_DestroyPipeline(anv_device_to_handle(device
),
639 anv_pipeline_to_handle(state
->clear
.stencil_only_pipeline
),
642 anv_DestroyPipeline(anv_device_to_handle(device
),
643 anv_pipeline_to_handle(state
->clear
.depth_only_pipeline
),
650 anv_device_init_meta_clear_state(struct anv_device
*device
)
654 result
= init_color_pipelines(device
);
655 if (result
!= VK_SUCCESS
)
658 result
= init_depthstencil_pipelines(device
);
659 if (result
!= VK_SUCCESS
)
666 anv_device_finish_meta_clear_state(struct anv_device
*device
)
668 VkDevice device_h
= anv_device_to_handle(device
);
671 i
< ARRAY_SIZE(device
->meta_state
.clear
.color_pipelines
); ++i
) {
672 ANV_CALL(DestroyPipeline
)(device_h
,
673 anv_pipeline_to_handle(device
->meta_state
.clear
.color_pipelines
[i
]),
677 ANV_CALL(DestroyPipeline
)(device_h
,
678 anv_pipeline_to_handle(device
->meta_state
.clear
.depth_only_pipeline
),
680 ANV_CALL(DestroyPipeline
)(device_h
,
681 anv_pipeline_to_handle(device
->meta_state
.clear
.stencil_only_pipeline
),
683 ANV_CALL(DestroyPipeline
)(device_h
,
684 anv_pipeline_to_handle(device
->meta_state
.clear
.depthstencil_pipeline
),
689 * The parameters mean that same as those in vkCmdClearAttachments.
692 emit_clear(struct anv_cmd_buffer
*cmd_buffer
,
693 const VkClearAttachment
*clear_att
)
695 if (clear_att
->aspectMask
& VK_IMAGE_ASPECT_COLOR_BIT
) {
696 emit_color_clear(cmd_buffer
, clear_att
);
698 assert(clear_att
->aspectMask
& (VK_IMAGE_ASPECT_DEPTH_BIT
|
699 VK_IMAGE_ASPECT_STENCIL_BIT
));
700 emit_depthstencil_clear(cmd_buffer
, clear_att
);
705 subpass_needs_clear(const struct anv_cmd_buffer
*cmd_buffer
)
707 const struct anv_cmd_state
*cmd_state
= &cmd_buffer
->state
;
708 uint32_t ds
= cmd_state
->subpass
->depth_stencil_attachment
;
710 for (uint32_t i
= 0; i
< cmd_state
->subpass
->color_count
; ++i
) {
711 uint32_t a
= cmd_state
->subpass
->color_attachments
[i
];
712 if (cmd_state
->attachments
[a
].pending_clear_aspects
) {
717 if (ds
!= VK_ATTACHMENT_UNUSED
&&
718 cmd_state
->attachments
[ds
].pending_clear_aspects
) {
726 * Emit any pending attachment clears for the current subpass.
728 * @see anv_attachment_state::pending_clear_aspects
731 anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer
*cmd_buffer
)
733 struct anv_cmd_state
*cmd_state
= &cmd_buffer
->state
;
734 struct anv_meta_saved_state saved_state
;
736 if (!subpass_needs_clear(cmd_buffer
))
739 meta_clear_begin(&saved_state
, cmd_buffer
);
741 if (cmd_state
->framebuffer
->layers
> 1)
742 anv_finishme("clearing multi-layer framebuffer");
744 for (uint32_t i
= 0; i
< cmd_state
->subpass
->color_count
; ++i
) {
745 uint32_t a
= cmd_state
->subpass
->color_attachments
[i
];
747 if (!cmd_state
->attachments
[a
].pending_clear_aspects
)
750 assert(cmd_state
->attachments
[a
].pending_clear_aspects
==
751 VK_IMAGE_ASPECT_COLOR_BIT
);
753 VkClearAttachment clear_att
= {
754 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
755 .colorAttachment
= i
, /* Use attachment index relative to subpass */
756 .clearValue
= cmd_state
->attachments
[a
].clear_value
,
759 emit_clear(cmd_buffer
, &clear_att
);
760 cmd_state
->attachments
[a
].pending_clear_aspects
= 0;
763 uint32_t ds
= cmd_state
->subpass
->depth_stencil_attachment
;
765 if (ds
!= VK_ATTACHMENT_UNUSED
&&
766 cmd_state
->attachments
[ds
].pending_clear_aspects
) {
768 VkClearAttachment clear_att
= {
769 .aspectMask
= cmd_state
->attachments
[ds
].pending_clear_aspects
,
770 .clearValue
= cmd_state
->attachments
[ds
].clear_value
,
773 emit_clear(cmd_buffer
, &clear_att
);
774 cmd_state
->attachments
[ds
].pending_clear_aspects
= 0;
777 meta_clear_end(&saved_state
, cmd_buffer
);
780 void anv_CmdClearColorImage(
781 VkCommandBuffer commandBuffer
,
783 VkImageLayout imageLayout
,
784 const VkClearColorValue
* pColor
,
786 const VkImageSubresourceRange
* pRanges
)
788 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
789 ANV_FROM_HANDLE(anv_image
, image
, _image
);
790 struct anv_meta_saved_state saved_state
;
792 meta_clear_begin(&saved_state
, cmd_buffer
);
794 for (uint32_t r
= 0; r
< rangeCount
; r
++) {
795 for (uint32_t l
= 0; l
< pRanges
[r
].levelCount
; l
++) {
796 for (uint32_t s
= 0; s
< pRanges
[r
].layerCount
; s
++) {
797 struct anv_image_view iview
;
798 anv_image_view_init(&iview
, cmd_buffer
->device
,
799 &(VkImageViewCreateInfo
) {
800 .sType
= VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
,
802 .viewType
= anv_meta_get_view_type(image
),
803 .format
= image
->vk_format
,
804 .subresourceRange
= {
805 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
806 .baseMipLevel
= pRanges
[r
].baseMipLevel
+ l
,
808 .baseArrayLayer
= pRanges
[r
].baseArrayLayer
+ s
,
815 anv_CreateFramebuffer(anv_device_to_handle(cmd_buffer
->device
),
816 &(VkFramebufferCreateInfo
) {
817 .sType
= VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
,
818 .attachmentCount
= 1,
819 .pAttachments
= (VkImageView
[]) {
820 anv_image_view_to_handle(&iview
),
822 .width
= iview
.extent
.width
,
823 .height
= iview
.extent
.height
,
825 }, &cmd_buffer
->pool
->alloc
, &fb
);
828 anv_CreateRenderPass(anv_device_to_handle(cmd_buffer
->device
),
829 &(VkRenderPassCreateInfo
) {
830 .sType
= VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
,
831 .attachmentCount
= 1,
832 .pAttachments
= &(VkAttachmentDescription
) {
833 .format
= iview
.vk_format
,
834 .loadOp
= VK_ATTACHMENT_LOAD_OP_LOAD
,
835 .storeOp
= VK_ATTACHMENT_STORE_OP_STORE
,
836 .initialLayout
= VK_IMAGE_LAYOUT_GENERAL
,
837 .finalLayout
= VK_IMAGE_LAYOUT_GENERAL
,
840 .pSubpasses
= &(VkSubpassDescription
) {
841 .pipelineBindPoint
= VK_PIPELINE_BIND_POINT_GRAPHICS
,
842 .inputAttachmentCount
= 0,
843 .colorAttachmentCount
= 1,
844 .pColorAttachments
= &(VkAttachmentReference
) {
846 .layout
= VK_IMAGE_LAYOUT_GENERAL
,
848 .pResolveAttachments
= NULL
,
849 .pDepthStencilAttachment
= &(VkAttachmentReference
) {
850 .attachment
= VK_ATTACHMENT_UNUSED
,
851 .layout
= VK_IMAGE_LAYOUT_GENERAL
,
853 .preserveAttachmentCount
= 1,
854 .pPreserveAttachments
= (uint32_t[]) { 0 },
856 .dependencyCount
= 0,
857 }, &cmd_buffer
->pool
->alloc
, &pass
);
859 ANV_CALL(CmdBeginRenderPass
)(anv_cmd_buffer_to_handle(cmd_buffer
),
860 &(VkRenderPassBeginInfo
) {
861 .sType
= VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO
,
865 .width
= iview
.extent
.width
,
866 .height
= iview
.extent
.height
,
871 .clearValueCount
= 1,
872 .pClearValues
= (VkClearValue
[]) {
873 { .color
= *pColor
},
875 }, VK_SUBPASS_CONTENTS_INLINE
);
877 ANV_CALL(CmdEndRenderPass
)(anv_cmd_buffer_to_handle(cmd_buffer
));
879 /* XXX: We're leaking the render pass and framebuffer */
884 meta_clear_end(&saved_state
, cmd_buffer
);
887 void anv_CmdClearDepthStencilImage(
888 VkCommandBuffer commandBuffer
,
890 VkImageLayout imageLayout
,
891 const VkClearDepthStencilValue
* pDepthStencil
,
893 const VkImageSubresourceRange
* pRanges
)
898 void anv_CmdClearAttachments(
899 VkCommandBuffer commandBuffer
,
900 uint32_t attachmentCount
,
901 const VkClearAttachment
* pAttachments
,
903 const VkClearRect
* pRects
)