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_private.h"
26 #include "nir/nir_builder.h"
28 /** Vertex attributes for color clears. */
29 struct color_clear_vattrs
{
30 struct anv_vue_header vue_header
;
31 float position
[2]; /**< 3DPRIM_RECTLIST */
32 VkClearColorValue color
;
35 /** Vertex attributes for depthstencil clears. */
36 struct depthstencil_clear_vattrs
{
37 struct anv_vue_header vue_header
;
38 float position
[2]; /*<< 3DPRIM_RECTLIST */
42 meta_clear_begin(struct anv_meta_saved_state
*saved_state
,
43 struct anv_cmd_buffer
*cmd_buffer
)
45 anv_meta_save(saved_state
, cmd_buffer
,
46 (1 << VK_DYNAMIC_STATE_VIEWPORT
) |
47 (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE
) |
48 (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK
));
50 /* Avoid uploading more viewport states than necessary */
51 cmd_buffer
->state
.dynamic
.viewport
.count
= 0;
55 meta_clear_end(struct anv_meta_saved_state
*saved_state
,
56 struct anv_cmd_buffer
*cmd_buffer
)
58 anv_meta_restore(saved_state
, cmd_buffer
);
62 build_color_shaders(struct nir_shader
**out_vs
,
63 struct nir_shader
**out_fs
,
69 nir_builder_init_simple_shader(&vs_b
, NULL
, MESA_SHADER_VERTEX
, NULL
);
70 nir_builder_init_simple_shader(&fs_b
, NULL
, MESA_SHADER_FRAGMENT
, NULL
);
72 vs_b
.shader
->info
.name
= ralloc_strdup(vs_b
.shader
, "meta_clear_color_vs");
73 fs_b
.shader
->info
.name
= ralloc_strdup(fs_b
.shader
, "meta_clear_color_fs");
75 const struct glsl_type
*position_type
= glsl_vec4_type();
76 const struct glsl_type
*color_type
= glsl_vec4_type();
78 nir_variable
*vs_in_pos
=
79 nir_variable_create(vs_b
.shader
, nir_var_shader_in
, position_type
,
81 vs_in_pos
->data
.location
= VERT_ATTRIB_GENERIC0
;
83 nir_variable
*vs_out_pos
=
84 nir_variable_create(vs_b
.shader
, nir_var_shader_out
, position_type
,
86 vs_out_pos
->data
.location
= VARYING_SLOT_POS
;
88 nir_variable
*vs_in_color
=
89 nir_variable_create(vs_b
.shader
, nir_var_shader_in
, color_type
,
91 vs_in_color
->data
.location
= VERT_ATTRIB_GENERIC1
;
93 nir_variable
*vs_out_color
=
94 nir_variable_create(vs_b
.shader
, nir_var_shader_out
, color_type
,
96 vs_out_color
->data
.location
= VARYING_SLOT_VAR0
;
97 vs_out_color
->data
.interpolation
= INTERP_MODE_FLAT
;
99 nir_variable
*fs_in_color
=
100 nir_variable_create(fs_b
.shader
, nir_var_shader_in
, color_type
,
102 fs_in_color
->data
.location
= vs_out_color
->data
.location
;
103 fs_in_color
->data
.interpolation
= vs_out_color
->data
.interpolation
;
105 nir_variable
*fs_out_color
=
106 nir_variable_create(fs_b
.shader
, nir_var_shader_out
, color_type
,
108 fs_out_color
->data
.location
= FRAG_RESULT_DATA0
+ frag_output
;
110 nir_copy_var(&vs_b
, vs_out_pos
, vs_in_pos
);
111 nir_copy_var(&vs_b
, vs_out_color
, vs_in_color
);
112 nir_copy_var(&fs_b
, fs_out_color
, fs_in_color
);
114 *out_vs
= vs_b
.shader
;
115 *out_fs
= fs_b
.shader
;
119 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
= VK_NULL_HANDLE
;
137 result
= anv_graphics_pipeline_create(device_h
,
139 &(VkGraphicsPipelineCreateInfo
) {
140 .sType
= VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
,
141 .stageCount
= fs_nir
? 2 : 1,
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,
176 .depthClampEnable
= true,
178 .pMultisampleState
= &(VkPipelineMultisampleStateCreateInfo
) {
179 .sType
= VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO
,
180 .rasterizationSamples
= samples
,
181 .sampleShadingEnable
= false,
182 .pSampleMask
= (VkSampleMask
[]) { ~0 },
183 .alphaToCoverageEnable
= false,
184 .alphaToOneEnable
= false,
186 .pDepthStencilState
= ds_state
,
187 .pColorBlendState
= cb_state
,
188 .pDynamicState
= &(VkPipelineDynamicStateCreateInfo
) {
189 /* The meta clear pipeline declares all state as dynamic.
190 * As a consequence, vkCmdBindPipeline writes no dynamic state
191 * to the cmd buffer. Therefore, at the end of the meta clear,
192 * we need only restore dynamic state was vkCmdSet.
194 .sType
= VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO
,
195 .dynamicStateCount
= 8,
196 .pDynamicStates
= (VkDynamicState
[]) {
197 /* Everything except stencil write mask */
198 VK_DYNAMIC_STATE_VIEWPORT
,
199 VK_DYNAMIC_STATE_SCISSOR
,
200 VK_DYNAMIC_STATE_LINE_WIDTH
,
201 VK_DYNAMIC_STATE_DEPTH_BIAS
,
202 VK_DYNAMIC_STATE_BLEND_CONSTANTS
,
203 VK_DYNAMIC_STATE_DEPTH_BOUNDS
,
204 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK
,
205 VK_DYNAMIC_STATE_STENCIL_REFERENCE
,
209 .renderPass
= anv_render_pass_to_handle(&anv_meta_dummy_renderpass
),
212 &(struct anv_graphics_pipeline_create_info
) {
213 .color_attachment_count
= MAX_RTS
,
214 .use_repclear
= use_repclear
,
224 *pipeline
= anv_pipeline_from_handle(pipeline_h
);
230 create_color_pipeline(struct anv_device
*device
,
232 uint32_t frag_output
,
233 struct anv_pipeline
**pipeline
)
235 struct nir_shader
*vs_nir
;
236 struct nir_shader
*fs_nir
;
237 build_color_shaders(&vs_nir
, &fs_nir
, frag_output
);
239 const VkPipelineVertexInputStateCreateInfo vi_state
= {
240 .sType
= VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO
,
241 .vertexBindingDescriptionCount
= 1,
242 .pVertexBindingDescriptions
= (VkVertexInputBindingDescription
[]) {
245 .stride
= sizeof(struct color_clear_vattrs
),
246 .inputRate
= VK_VERTEX_INPUT_RATE_VERTEX
249 .vertexAttributeDescriptionCount
= 3,
250 .pVertexAttributeDescriptions
= (VkVertexInputAttributeDescription
[]) {
255 .format
= VK_FORMAT_R32G32B32A32_UINT
,
256 .offset
= offsetof(struct color_clear_vattrs
, vue_header
),
262 .format
= VK_FORMAT_R32G32_SFLOAT
,
263 .offset
= offsetof(struct color_clear_vattrs
, position
),
269 .format
= VK_FORMAT_R32G32B32A32_SFLOAT
,
270 .offset
= offsetof(struct color_clear_vattrs
, color
),
275 const VkPipelineDepthStencilStateCreateInfo ds_state
= {
276 .sType
= VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
,
277 .depthTestEnable
= false,
278 .depthWriteEnable
= false,
279 .depthBoundsTestEnable
= false,
280 .stencilTestEnable
= false,
283 VkPipelineColorBlendAttachmentState blend_attachment_state
[MAX_RTS
] = { 0 };
284 blend_attachment_state
[frag_output
] = (VkPipelineColorBlendAttachmentState
) {
285 .blendEnable
= false,
286 .colorWriteMask
= VK_COLOR_COMPONENT_A_BIT
|
287 VK_COLOR_COMPONENT_R_BIT
|
288 VK_COLOR_COMPONENT_G_BIT
|
289 VK_COLOR_COMPONENT_B_BIT
,
292 const VkPipelineColorBlendStateCreateInfo cb_state
= {
293 .sType
= VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO
,
294 .logicOpEnable
= false,
295 .attachmentCount
= MAX_RTS
,
296 .pAttachments
= blend_attachment_state
299 /* Use the repclear shader. Since the NIR shader we are providing has
300 * exactly one output, that output will get compacted down to binding
301 * table entry 0. The hard-coded repclear shader is then exactly what
302 * we want regardless of what attachment we are actually clearing.
305 create_pipeline(device
, samples
, vs_nir
, fs_nir
, &vi_state
, &ds_state
,
306 &cb_state
, &device
->meta_state
.alloc
,
307 /*use_repclear*/ true, pipeline
);
311 destroy_pipeline(struct anv_device
*device
, struct anv_pipeline
*pipeline
)
316 ANV_CALL(DestroyPipeline
)(anv_device_to_handle(device
),
317 anv_pipeline_to_handle(pipeline
),
318 &device
->meta_state
.alloc
);
322 anv_device_finish_meta_clear_state(struct anv_device
*device
)
324 struct anv_meta_state
*state
= &device
->meta_state
;
326 for (uint32_t i
= 0; i
< ARRAY_SIZE(state
->clear
); ++i
) {
327 for (uint32_t j
= 0; j
< ARRAY_SIZE(state
->clear
[i
].color_pipelines
); ++j
) {
328 destroy_pipeline(device
, state
->clear
[i
].color_pipelines
[j
]);
331 destroy_pipeline(device
, state
->clear
[i
].depth_only_pipeline
);
332 destroy_pipeline(device
, state
->clear
[i
].stencil_only_pipeline
);
333 destroy_pipeline(device
, state
->clear
[i
].depthstencil_pipeline
);
338 emit_color_clear(struct anv_cmd_buffer
*cmd_buffer
,
339 const VkClearAttachment
*clear_att
,
340 const VkClearRect
*clear_rect
)
342 struct anv_device
*device
= cmd_buffer
->device
;
343 const struct anv_subpass
*subpass
= cmd_buffer
->state
.subpass
;
344 const struct anv_framebuffer
*fb
= cmd_buffer
->state
.framebuffer
;
345 const uint32_t subpass_att
= clear_att
->colorAttachment
;
346 const uint32_t pass_att
= subpass
->color_attachments
[subpass_att
];
347 const struct anv_image_view
*iview
= fb
->attachments
[pass_att
];
348 const uint32_t samples
= iview
->image
->samples
;
349 const uint32_t samples_log2
= ffs(samples
) - 1;
350 struct anv_pipeline
*pipeline
=
351 device
->meta_state
.clear
[samples_log2
].color_pipelines
[subpass_att
];
352 VkClearColorValue clear_value
= clear_att
->clearValue
.color
;
354 VkCommandBuffer cmd_buffer_h
= anv_cmd_buffer_to_handle(cmd_buffer
);
355 VkPipeline pipeline_h
= anv_pipeline_to_handle(pipeline
);
357 assert(samples_log2
< ARRAY_SIZE(device
->meta_state
.clear
));
358 assert(clear_att
->aspectMask
== VK_IMAGE_ASPECT_COLOR_BIT
);
359 assert(clear_att
->colorAttachment
< subpass
->color_count
);
361 const struct color_clear_vattrs vertex_data
[3] = {
365 clear_rect
->rect
.offset
.x
,
366 clear_rect
->rect
.offset
.y
,
368 .color
= clear_value
,
373 clear_rect
->rect
.offset
.x
+ clear_rect
->rect
.extent
.width
,
374 clear_rect
->rect
.offset
.y
,
376 .color
= clear_value
,
381 clear_rect
->rect
.offset
.x
+ clear_rect
->rect
.extent
.width
,
382 clear_rect
->rect
.offset
.y
+ clear_rect
->rect
.extent
.height
,
384 .color
= clear_value
,
388 struct anv_state state
=
389 anv_cmd_buffer_emit_dynamic(cmd_buffer
, vertex_data
, sizeof(vertex_data
), 16);
391 struct anv_buffer vertex_buffer
= {
393 .size
= sizeof(vertex_data
),
394 .bo
= &device
->dynamic_state_block_pool
.bo
,
395 .offset
= state
.offset
,
398 ANV_CALL(CmdBindVertexBuffers
)(cmd_buffer_h
, 0, 1,
399 (VkBuffer
[]) { anv_buffer_to_handle(&vertex_buffer
) },
400 (VkDeviceSize
[]) { 0 });
402 if (cmd_buffer
->state
.pipeline
!= pipeline
) {
403 ANV_CALL(CmdBindPipeline
)(cmd_buffer_h
, VK_PIPELINE_BIND_POINT_GRAPHICS
,
407 ANV_CALL(CmdDraw
)(cmd_buffer_h
, 3, 1, 0, 0);
412 build_depthstencil_shader(struct nir_shader
**out_vs
)
416 nir_builder_init_simple_shader(&vs_b
, NULL
, MESA_SHADER_VERTEX
, NULL
);
418 vs_b
.shader
->info
.name
= ralloc_strdup(vs_b
.shader
, "meta_clear_depthstencil_vs");
420 const struct glsl_type
*position_type
= glsl_vec4_type();
422 nir_variable
*vs_in_pos
=
423 nir_variable_create(vs_b
.shader
, nir_var_shader_in
, position_type
,
425 vs_in_pos
->data
.location
= VERT_ATTRIB_GENERIC0
;
427 nir_variable
*vs_out_pos
=
428 nir_variable_create(vs_b
.shader
, nir_var_shader_out
, position_type
,
430 vs_out_pos
->data
.location
= VARYING_SLOT_POS
;
432 nir_copy_var(&vs_b
, vs_out_pos
, vs_in_pos
);
434 *out_vs
= vs_b
.shader
;
438 create_depthstencil_pipeline(struct anv_device
*device
,
439 VkImageAspectFlags aspects
,
441 struct anv_pipeline
**pipeline
)
443 struct nir_shader
*vs_nir
;
445 build_depthstencil_shader(&vs_nir
);
447 const VkPipelineVertexInputStateCreateInfo vi_state
= {
448 .sType
= VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO
,
449 .vertexBindingDescriptionCount
= 1,
450 .pVertexBindingDescriptions
= (VkVertexInputBindingDescription
[]) {
453 .stride
= sizeof(struct depthstencil_clear_vattrs
),
454 .inputRate
= VK_VERTEX_INPUT_RATE_VERTEX
457 .vertexAttributeDescriptionCount
= 2,
458 .pVertexAttributeDescriptions
= (VkVertexInputAttributeDescription
[]) {
463 .format
= VK_FORMAT_R32G32B32A32_UINT
,
464 .offset
= offsetof(struct depthstencil_clear_vattrs
, vue_header
),
470 .format
= VK_FORMAT_R32G32_SFLOAT
,
471 .offset
= offsetof(struct depthstencil_clear_vattrs
, position
),
476 const VkPipelineDepthStencilStateCreateInfo ds_state
= {
477 .sType
= VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
,
478 .depthTestEnable
= (aspects
& VK_IMAGE_ASPECT_DEPTH_BIT
),
479 .depthCompareOp
= VK_COMPARE_OP_ALWAYS
,
480 .depthWriteEnable
= (aspects
& VK_IMAGE_ASPECT_DEPTH_BIT
),
481 .depthBoundsTestEnable
= false,
482 .stencilTestEnable
= (aspects
& VK_IMAGE_ASPECT_STENCIL_BIT
),
484 .passOp
= VK_STENCIL_OP_REPLACE
,
485 .compareOp
= VK_COMPARE_OP_ALWAYS
,
486 .writeMask
= UINT32_MAX
,
487 .reference
= 0, /* dynamic */
489 .back
= { 0 /* dont care */ },
492 const VkPipelineColorBlendStateCreateInfo cb_state
= {
493 .sType
= VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO
,
494 .logicOpEnable
= false,
495 .attachmentCount
= 0,
496 .pAttachments
= NULL
,
499 return create_pipeline(device
, samples
, vs_nir
, NULL
, &vi_state
, &ds_state
,
500 &cb_state
, &device
->meta_state
.alloc
,
501 /*use_repclear*/ true, pipeline
);
505 emit_depthstencil_clear(struct anv_cmd_buffer
*cmd_buffer
,
506 const VkClearAttachment
*clear_att
,
507 const VkClearRect
*clear_rect
)
509 struct anv_device
*device
= cmd_buffer
->device
;
510 struct anv_meta_state
*meta_state
= &device
->meta_state
;
511 const struct anv_subpass
*subpass
= cmd_buffer
->state
.subpass
;
512 const struct anv_framebuffer
*fb
= cmd_buffer
->state
.framebuffer
;
513 const uint32_t pass_att
= subpass
->depth_stencil_attachment
;
514 const struct anv_image_view
*iview
= fb
->attachments
[pass_att
];
515 const uint32_t samples
= iview
->image
->samples
;
516 const uint32_t samples_log2
= ffs(samples
) - 1;
517 VkClearDepthStencilValue clear_value
= clear_att
->clearValue
.depthStencil
;
518 VkImageAspectFlags aspects
= clear_att
->aspectMask
;
520 VkCommandBuffer cmd_buffer_h
= anv_cmd_buffer_to_handle(cmd_buffer
);
522 assert(samples_log2
< ARRAY_SIZE(meta_state
->clear
));
523 assert(aspects
== VK_IMAGE_ASPECT_DEPTH_BIT
||
524 aspects
== VK_IMAGE_ASPECT_STENCIL_BIT
||
525 aspects
== (VK_IMAGE_ASPECT_DEPTH_BIT
|
526 VK_IMAGE_ASPECT_STENCIL_BIT
));
527 assert(pass_att
!= VK_ATTACHMENT_UNUSED
);
529 const struct depthstencil_clear_vattrs vertex_data
[3] = {
533 clear_rect
->rect
.offset
.x
,
534 clear_rect
->rect
.offset
.y
,
540 clear_rect
->rect
.offset
.x
+ clear_rect
->rect
.extent
.width
,
541 clear_rect
->rect
.offset
.y
,
547 clear_rect
->rect
.offset
.x
+ clear_rect
->rect
.extent
.width
,
548 clear_rect
->rect
.offset
.y
+ clear_rect
->rect
.extent
.height
,
553 struct anv_state state
=
554 anv_cmd_buffer_emit_dynamic(cmd_buffer
, vertex_data
, sizeof(vertex_data
), 16);
556 struct anv_buffer vertex_buffer
= {
558 .size
= sizeof(vertex_data
),
559 .bo
= &device
->dynamic_state_block_pool
.bo
,
560 .offset
= state
.offset
,
563 ANV_CALL(CmdSetViewport
)(cmd_buffer_h
, 0, 1,
569 .height
= fb
->height
,
571 /* Ignored when clearing only stencil. */
572 .minDepth
= clear_value
.depth
,
573 .maxDepth
= clear_value
.depth
,
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
= meta_state
->clear
[samples_log2
].depthstencil_pipeline
;
591 case VK_IMAGE_ASPECT_DEPTH_BIT
:
592 pipeline
= meta_state
->clear
[samples_log2
].depth_only_pipeline
;
594 case VK_IMAGE_ASPECT_STENCIL_BIT
:
595 pipeline
= meta_state
->clear
[samples_log2
].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 anv_device_init_meta_clear_state(struct anv_device
*device
)
613 struct anv_meta_state
*state
= &device
->meta_state
;
615 zero(device
->meta_state
.clear
);
617 for (uint32_t i
= 0; i
< ARRAY_SIZE(state
->clear
); ++i
) {
618 uint32_t samples
= 1 << i
;
620 for (uint32_t j
= 0; j
< ARRAY_SIZE(state
->clear
[i
].color_pipelines
); ++j
) {
621 res
= create_color_pipeline(device
, samples
, /* frag_output */ j
,
622 &state
->clear
[i
].color_pipelines
[j
]);
623 if (res
!= VK_SUCCESS
)
627 res
= create_depthstencil_pipeline(device
,
628 VK_IMAGE_ASPECT_DEPTH_BIT
, samples
,
629 &state
->clear
[i
].depth_only_pipeline
);
630 if (res
!= VK_SUCCESS
)
633 res
= create_depthstencil_pipeline(device
,
634 VK_IMAGE_ASPECT_STENCIL_BIT
, samples
,
635 &state
->clear
[i
].stencil_only_pipeline
);
636 if (res
!= VK_SUCCESS
)
639 res
= create_depthstencil_pipeline(device
,
640 VK_IMAGE_ASPECT_DEPTH_BIT
|
641 VK_IMAGE_ASPECT_STENCIL_BIT
, samples
,
642 &state
->clear
[i
].depthstencil_pipeline
);
643 if (res
!= VK_SUCCESS
)
650 anv_device_finish_meta_clear_state(device
);
655 * The parameters mean that same as those in vkCmdClearAttachments.
658 emit_clear(struct anv_cmd_buffer
*cmd_buffer
,
659 const VkClearAttachment
*clear_att
,
660 const VkClearRect
*clear_rect
)
662 if (clear_att
->aspectMask
& VK_IMAGE_ASPECT_COLOR_BIT
) {
663 emit_color_clear(cmd_buffer
, clear_att
, clear_rect
);
665 assert(clear_att
->aspectMask
& (VK_IMAGE_ASPECT_DEPTH_BIT
|
666 VK_IMAGE_ASPECT_STENCIL_BIT
));
667 emit_depthstencil_clear(cmd_buffer
, clear_att
, clear_rect
);
672 subpass_needs_clear(const struct anv_cmd_buffer
*cmd_buffer
)
674 const struct anv_cmd_state
*cmd_state
= &cmd_buffer
->state
;
675 uint32_t ds
= cmd_state
->subpass
->depth_stencil_attachment
;
677 for (uint32_t i
= 0; i
< cmd_state
->subpass
->color_count
; ++i
) {
678 uint32_t a
= cmd_state
->subpass
->color_attachments
[i
];
679 if (cmd_state
->attachments
[a
].pending_clear_aspects
) {
684 if (ds
!= VK_ATTACHMENT_UNUSED
&&
685 cmd_state
->attachments
[ds
].pending_clear_aspects
) {
693 * Emit any pending attachment clears for the current subpass.
695 * @see anv_attachment_state::pending_clear_aspects
698 anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer
*cmd_buffer
)
700 struct anv_cmd_state
*cmd_state
= &cmd_buffer
->state
;
701 struct anv_meta_saved_state saved_state
;
703 if (!subpass_needs_clear(cmd_buffer
))
706 meta_clear_begin(&saved_state
, cmd_buffer
);
708 if (cmd_state
->framebuffer
->layers
> 1)
709 anv_finishme("clearing multi-layer framebuffer");
711 VkClearRect clear_rect
= {
712 .rect
= cmd_state
->render_area
,
714 .layerCount
= 1, /* FINISHME: clear multi-layer framebuffer */
717 for (uint32_t i
= 0; i
< cmd_state
->subpass
->color_count
; ++i
) {
718 uint32_t a
= cmd_state
->subpass
->color_attachments
[i
];
720 if (!cmd_state
->attachments
[a
].pending_clear_aspects
)
723 assert(cmd_state
->attachments
[a
].pending_clear_aspects
==
724 VK_IMAGE_ASPECT_COLOR_BIT
);
726 VkClearAttachment clear_att
= {
727 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
728 .colorAttachment
= i
, /* Use attachment index relative to subpass */
729 .clearValue
= cmd_state
->attachments
[a
].clear_value
,
732 emit_clear(cmd_buffer
, &clear_att
, &clear_rect
);
733 cmd_state
->attachments
[a
].pending_clear_aspects
= 0;
736 uint32_t ds
= cmd_state
->subpass
->depth_stencil_attachment
;
738 if (ds
!= VK_ATTACHMENT_UNUSED
&&
739 cmd_state
->attachments
[ds
].pending_clear_aspects
) {
741 VkClearAttachment clear_att
= {
742 .aspectMask
= cmd_state
->attachments
[ds
].pending_clear_aspects
,
743 .clearValue
= cmd_state
->attachments
[ds
].clear_value
,
746 emit_clear(cmd_buffer
, &clear_att
, &clear_rect
);
747 cmd_state
->attachments
[ds
].pending_clear_aspects
= 0;
750 meta_clear_end(&saved_state
, cmd_buffer
);
754 anv_cmd_clear_image(struct anv_cmd_buffer
*cmd_buffer
,
755 struct anv_image
*image
,
756 VkImageLayout image_layout
,
757 const VkClearValue
*clear_value
,
758 uint32_t range_count
,
759 const VkImageSubresourceRange
*ranges
)
761 VkDevice device_h
= anv_device_to_handle(cmd_buffer
->device
);
763 for (uint32_t r
= 0; r
< range_count
; r
++) {
764 const VkImageSubresourceRange
*range
= &ranges
[r
];
765 for (uint32_t l
= 0; l
< anv_get_levelCount(image
, range
); ++l
) {
766 const uint32_t layer_count
= image
->type
== VK_IMAGE_TYPE_3D
?
767 anv_minify(image
->extent
.depth
, l
) :
768 anv_get_layerCount(image
, range
);
769 for (uint32_t s
= 0; s
< layer_count
; ++s
) {
770 struct anv_image_view iview
;
771 anv_image_view_init(&iview
, cmd_buffer
->device
,
772 &(VkImageViewCreateInfo
) {
773 .sType
= VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
,
774 .image
= anv_image_to_handle(image
),
775 .viewType
= anv_meta_get_view_type(image
),
776 .format
= image
->vk_format
,
777 .subresourceRange
= {
778 .aspectMask
= range
->aspectMask
,
779 .baseMipLevel
= range
->baseMipLevel
+ l
,
781 .baseArrayLayer
= range
->baseArrayLayer
+ s
,
785 cmd_buffer
, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
);
788 anv_CreateFramebuffer(device_h
,
789 &(VkFramebufferCreateInfo
) {
790 .sType
= VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
,
791 .attachmentCount
= 1,
792 .pAttachments
= (VkImageView
[]) {
793 anv_image_view_to_handle(&iview
),
795 .width
= iview
.extent
.width
,
796 .height
= iview
.extent
.height
,
799 &cmd_buffer
->pool
->alloc
,
802 VkAttachmentDescription att_desc
= {
803 .format
= iview
.vk_format
,
804 .loadOp
= VK_ATTACHMENT_LOAD_OP_LOAD
,
805 .storeOp
= VK_ATTACHMENT_STORE_OP_STORE
,
806 .stencilLoadOp
= VK_ATTACHMENT_LOAD_OP_LOAD
,
807 .stencilStoreOp
= VK_ATTACHMENT_STORE_OP_STORE
,
808 .initialLayout
= image_layout
,
809 .finalLayout
= image_layout
,
812 VkSubpassDescription subpass_desc
= {
813 .pipelineBindPoint
= VK_PIPELINE_BIND_POINT_GRAPHICS
,
814 .inputAttachmentCount
= 0,
815 .colorAttachmentCount
= 0,
816 .pColorAttachments
= NULL
,
817 .pResolveAttachments
= NULL
,
818 .pDepthStencilAttachment
= NULL
,
819 .preserveAttachmentCount
= 0,
820 .pPreserveAttachments
= NULL
,
823 const VkAttachmentReference att_ref
= {
825 .layout
= image_layout
,
828 if (range
->aspectMask
& VK_IMAGE_ASPECT_COLOR_BIT
) {
829 subpass_desc
.colorAttachmentCount
= 1;
830 subpass_desc
.pColorAttachments
= &att_ref
;
832 subpass_desc
.pDepthStencilAttachment
= &att_ref
;
836 anv_CreateRenderPass(device_h
,
837 &(VkRenderPassCreateInfo
) {
838 .sType
= VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
,
839 .attachmentCount
= 1,
840 .pAttachments
= &att_desc
,
842 .pSubpasses
= &subpass_desc
,
844 &cmd_buffer
->pool
->alloc
,
847 ANV_CALL(CmdBeginRenderPass
)(anv_cmd_buffer_to_handle(cmd_buffer
),
848 &(VkRenderPassBeginInfo
) {
849 .sType
= VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO
,
853 .width
= iview
.extent
.width
,
854 .height
= iview
.extent
.height
,
859 .clearValueCount
= 0,
860 .pClearValues
= NULL
,
862 VK_SUBPASS_CONTENTS_INLINE
);
864 VkClearAttachment clear_att
= {
865 .aspectMask
= range
->aspectMask
,
866 .colorAttachment
= 0,
867 .clearValue
= *clear_value
,
870 VkClearRect clear_rect
= {
873 .extent
= { iview
.extent
.width
, iview
.extent
.height
},
875 .baseArrayLayer
= range
->baseArrayLayer
,
876 .layerCount
= 1, /* FINISHME: clear multi-layer framebuffer */
879 emit_clear(cmd_buffer
, &clear_att
, &clear_rect
);
881 ANV_CALL(CmdEndRenderPass
)(anv_cmd_buffer_to_handle(cmd_buffer
));
882 ANV_CALL(DestroyRenderPass
)(device_h
, pass
,
883 &cmd_buffer
->pool
->alloc
);
884 ANV_CALL(DestroyFramebuffer
)(device_h
, fb
,
885 &cmd_buffer
->pool
->alloc
);
891 void anv_CmdClearColorImage(
892 VkCommandBuffer commandBuffer
,
894 VkImageLayout imageLayout
,
895 const VkClearColorValue
* pColor
,
897 const VkImageSubresourceRange
* pRanges
)
899 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
900 ANV_FROM_HANDLE(anv_image
, image
, image_h
);
901 struct anv_meta_saved_state saved_state
;
903 meta_clear_begin(&saved_state
, cmd_buffer
);
905 anv_cmd_clear_image(cmd_buffer
, image
, imageLayout
,
906 (const VkClearValue
*) pColor
,
907 rangeCount
, pRanges
);
909 meta_clear_end(&saved_state
, cmd_buffer
);
912 void anv_CmdClearDepthStencilImage(
913 VkCommandBuffer commandBuffer
,
915 VkImageLayout imageLayout
,
916 const VkClearDepthStencilValue
* pDepthStencil
,
918 const VkImageSubresourceRange
* pRanges
)
920 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
921 ANV_FROM_HANDLE(anv_image
, image
, image_h
);
922 struct anv_meta_saved_state saved_state
;
924 meta_clear_begin(&saved_state
, cmd_buffer
);
926 anv_cmd_clear_image(cmd_buffer
, image
, imageLayout
,
927 (const VkClearValue
*) pDepthStencil
,
928 rangeCount
, pRanges
);
930 meta_clear_end(&saved_state
, cmd_buffer
);
933 void anv_CmdClearAttachments(
934 VkCommandBuffer commandBuffer
,
935 uint32_t attachmentCount
,
936 const VkClearAttachment
* pAttachments
,
938 const VkClearRect
* pRects
)
940 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
941 struct anv_meta_saved_state saved_state
;
943 meta_clear_begin(&saved_state
, cmd_buffer
);
945 /* FINISHME: We can do better than this dumb loop. It thrashes too much
948 for (uint32_t a
= 0; a
< attachmentCount
; ++a
) {
949 for (uint32_t r
= 0; r
< rectCount
; ++r
) {
950 emit_clear(cmd_buffer
, &pAttachments
[a
], &pRects
[r
]);
954 meta_clear_end(&saved_state
, cmd_buffer
);
958 do_buffer_fill(struct anv_cmd_buffer
*cmd_buffer
,
959 struct anv_bo
*dest
, uint64_t dest_offset
,
960 int width
, int height
, VkFormat fill_format
, uint32_t data
)
962 VkDevice vk_device
= anv_device_to_handle(cmd_buffer
->device
);
964 VkImageCreateInfo image_info
= {
965 .sType
= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
,
966 .imageType
= VK_IMAGE_TYPE_2D
,
967 .format
= fill_format
,
976 .tiling
= VK_IMAGE_TILING_LINEAR
,
977 .usage
= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
,
982 image_info
.usage
= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
;
983 anv_CreateImage(vk_device
, &image_info
,
984 &cmd_buffer
->pool
->alloc
, &dest_image
);
986 /* We could use a vk call to bind memory, but that would require
987 * creating a dummy memory object etc. so there's really no point.
989 anv_image_from_handle(dest_image
)->bo
= dest
;
990 anv_image_from_handle(dest_image
)->offset
= dest_offset
;
992 const VkClearValue clear_value
= {
994 .uint32
= { data
, data
, data
, data
}
998 const VkImageSubresourceRange range
= {
999 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
1002 .baseArrayLayer
= 0,
1006 anv_cmd_clear_image(cmd_buffer
, anv_image_from_handle(dest_image
),
1007 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
,
1008 &clear_value
, 1, &range
);
1011 void anv_CmdFillBuffer(
1012 VkCommandBuffer commandBuffer
,
1014 VkDeviceSize dstOffset
,
1015 VkDeviceSize fillSize
,
1018 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
1019 ANV_FROM_HANDLE(anv_buffer
, dst_buffer
, dstBuffer
);
1020 struct anv_meta_saved_state saved_state
;
1022 meta_clear_begin(&saved_state
, cmd_buffer
);
1026 if ((fillSize
& 15) == 0 && (dstOffset
& 15) == 0) {
1027 format
= VK_FORMAT_R32G32B32A32_UINT
;
1029 } else if ((fillSize
& 7) == 0 && (dstOffset
& 15) == 0) {
1030 format
= VK_FORMAT_R32G32_UINT
;
1033 assert((fillSize
& 3) == 0 && (dstOffset
& 3) == 0);
1034 format
= VK_FORMAT_R32_UINT
;
1038 /* This is maximum possible width/height our HW can handle */
1039 const uint64_t max_surface_dim
= 1 << 14;
1041 /* First, we make a bunch of max-sized copies */
1042 const uint64_t max_fill_size
= max_surface_dim
* max_surface_dim
* bs
;
1043 while (fillSize
> max_fill_size
) {
1044 do_buffer_fill(cmd_buffer
, dst_buffer
->bo
,
1045 dst_buffer
->offset
+ dstOffset
,
1046 max_surface_dim
, max_surface_dim
, format
, data
);
1047 fillSize
-= max_fill_size
;
1048 dstOffset
+= max_fill_size
;
1051 uint64_t height
= fillSize
/ (max_surface_dim
* bs
);
1052 assert(height
< max_surface_dim
);
1054 const uint64_t rect_fill_size
= height
* max_surface_dim
* bs
;
1055 do_buffer_fill(cmd_buffer
, dst_buffer
->bo
,
1056 dst_buffer
->offset
+ dstOffset
,
1057 max_surface_dim
, height
, format
, data
);
1058 fillSize
-= rect_fill_size
;
1059 dstOffset
+= rect_fill_size
;
1062 if (fillSize
!= 0) {
1063 do_buffer_fill(cmd_buffer
, dst_buffer
->bo
,
1064 dst_buffer
->offset
+ dstOffset
,
1065 fillSize
/ bs
, 1, format
, data
);
1068 meta_clear_end(&saved_state
, cmd_buffer
);