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_nir_builder.h"
27 #include "anv_private.h"
29 struct clear_instance_data
{
30 struct anv_vue_header vue_header
;
31 VkClearColorValue color
;
35 meta_emit_clear(struct anv_cmd_buffer
*cmd_buffer
,
37 struct clear_instance_data
*instance_data
,
38 VkClearDepthStencilValue ds_clear_value
)
40 struct anv_device
*device
= cmd_buffer
->device
;
41 struct anv_framebuffer
*fb
= cmd_buffer
->state
.framebuffer
;
42 struct anv_state state
;
45 const float vertex_data
[] = {
46 /* Rect-list coordinates */
47 0.0, 0.0, ds_clear_value
.depth
,
48 fb
->width
, 0.0, ds_clear_value
.depth
,
49 fb
->width
, fb
->height
, ds_clear_value
.depth
,
51 /* Align to 16 bytes */
55 size
= sizeof(vertex_data
) + num_instances
* sizeof(*instance_data
);
56 state
= anv_cmd_buffer_alloc_dynamic_state(cmd_buffer
, size
, 16);
58 /* Copy in the vertex and instance data */
59 memcpy(state
.map
, vertex_data
, sizeof(vertex_data
));
60 memcpy(state
.map
+ sizeof(vertex_data
), instance_data
,
61 num_instances
* sizeof(*instance_data
));
63 struct anv_buffer vertex_buffer
= {
64 .device
= cmd_buffer
->device
,
66 .bo
= &device
->dynamic_state_block_pool
.bo
,
67 .offset
= state
.offset
70 anv_CmdBindVertexBuffers(anv_cmd_buffer_to_handle(cmd_buffer
), 0, 2,
72 anv_buffer_to_handle(&vertex_buffer
),
73 anv_buffer_to_handle(&vertex_buffer
)
80 if (cmd_buffer
->state
.pipeline
!= anv_pipeline_from_handle(device
->meta_state
.clear
.pipeline
))
81 anv_CmdBindPipeline(anv_cmd_buffer_to_handle(cmd_buffer
),
82 VK_PIPELINE_BIND_POINT_GRAPHICS
,
83 device
->meta_state
.clear
.pipeline
);
85 ANV_CALL(CmdDraw
)(anv_cmd_buffer_to_handle(cmd_buffer
),
86 3, num_instances
, 0, 0);
90 anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer
*cmd_buffer
,
91 struct anv_render_pass
*pass
,
92 const VkClearValue
*clear_values
)
94 struct anv_meta_saved_state saved_state
;
96 if (pass
->has_stencil_clear_attachment
)
97 anv_finishme("stencil clear");
99 /* FINISHME: Rethink how we count clear attachments in light of
100 * 0.138.2 -> 0.170.2 diff.
102 if (pass
->num_color_clear_attachments
== 0 &&
103 !pass
->has_depth_clear_attachment
)
106 struct clear_instance_data instance_data
[pass
->num_color_clear_attachments
];
107 uint32_t color_attachments
[pass
->num_color_clear_attachments
];
108 uint32_t ds_attachment
= VK_ATTACHMENT_UNUSED
;
109 VkClearDepthStencilValue ds_clear_value
= {0};
112 for (uint32_t i
= 0; i
< pass
->attachment_count
; i
++) {
113 const struct anv_render_pass_attachment
*att
= &pass
->attachments
[i
];
115 if (anv_format_is_color(att
->format
)) {
116 if (att
->load_op
== VK_ATTACHMENT_LOAD_OP_CLEAR
) {
117 instance_data
[layer
] = (struct clear_instance_data
) {
123 .color
= clear_values
[i
].color
,
125 color_attachments
[layer
] = i
;
129 if (att
->format
->depth_format
&&
130 att
->load_op
== VK_ATTACHMENT_LOAD_OP_CLEAR
) {
131 assert(ds_attachment
== VK_ATTACHMENT_UNUSED
);
133 ds_clear_value
= clear_values
[ds_attachment
].depthStencil
;
136 if (att
->format
->has_stencil
&&
137 att
->stencil_load_op
== VK_ATTACHMENT_LOAD_OP_CLEAR
) {
138 anv_finishme("stencil clear");
143 anv_meta_save(&saved_state
, cmd_buffer
,
144 (1 << VK_DYNAMIC_STATE_VIEWPORT
));
145 cmd_buffer
->state
.dynamic
.viewport
.count
= 0;
147 struct anv_subpass subpass
= {
149 .color_count
= pass
->num_color_clear_attachments
,
150 .color_attachments
= color_attachments
,
151 .depth_stencil_attachment
= ds_attachment
,
154 anv_cmd_buffer_begin_subpass(cmd_buffer
, &subpass
);
156 meta_emit_clear(cmd_buffer
, pass
->num_color_clear_attachments
,
157 instance_data
, ds_clear_value
);
159 anv_meta_restore(&saved_state
, cmd_buffer
);
163 build_nir_vertex_shader(void)
167 const struct glsl_type
*vertex_type
= glsl_vec4_type();
169 nir_builder_init_simple_shader(&b
, MESA_SHADER_VERTEX
);
171 nir_variable
*pos_in
= nir_variable_create(b
.shader
, nir_var_shader_in
,
172 vertex_type
, "a_pos");
173 pos_in
->data
.location
= VERT_ATTRIB_GENERIC0
;
174 nir_variable
*pos_out
= nir_variable_create(b
.shader
, nir_var_shader_out
,
175 vertex_type
, "gl_Position");
176 pos_in
->data
.location
= VARYING_SLOT_POS
;
177 nir_copy_var(&b
, pos_out
, pos_in
);
179 /* Add one more pass-through attribute. For clear shaders, this is used
180 * to store the color and for blit shaders it's the texture coordinate.
182 const struct glsl_type
*attr_type
= glsl_vec4_type();
183 nir_variable
*attr_in
= nir_variable_create(b
.shader
, nir_var_shader_in
,
184 attr_type
, "a_attr");
185 attr_in
->data
.location
= VERT_ATTRIB_GENERIC1
;
186 nir_variable
*attr_out
= nir_variable_create(b
.shader
, nir_var_shader_out
,
187 attr_type
, "v_attr");
188 attr_out
->data
.location
= VARYING_SLOT_VAR0
;
189 attr_out
->data
.interpolation
= INTERP_QUALIFIER_FLAT
;
190 nir_copy_var(&b
, attr_out
, attr_in
);
196 build_nir_clear_fragment_shader(void)
200 const struct glsl_type
*color_type
= glsl_vec4_type();
202 nir_builder_init_simple_shader(&b
, MESA_SHADER_FRAGMENT
);
204 nir_variable
*color_in
= nir_variable_create(b
.shader
, nir_var_shader_in
,
205 color_type
, "v_attr");
206 color_in
->data
.location
= VARYING_SLOT_VAR0
;
207 color_in
->data
.interpolation
= INTERP_QUALIFIER_FLAT
;
208 nir_variable
*color_out
= nir_variable_create(b
.shader
, nir_var_shader_out
,
209 color_type
, "f_color");
210 color_out
->data
.location
= FRAG_RESULT_DATA0
;
211 nir_copy_var(&b
, color_out
, color_in
);
217 anv_device_init_meta_clear_state(struct anv_device
*device
)
219 struct anv_shader_module vsm
= {
220 .nir
= build_nir_vertex_shader(),
223 struct anv_shader_module fsm
= {
224 .nir
= build_nir_clear_fragment_shader(),
228 anv_CreateShader(anv_device_to_handle(device
),
229 &(VkShaderCreateInfo
) {
230 .sType
= VK_STRUCTURE_TYPE_SHADER_CREATE_INFO
,
231 .module
= anv_shader_module_to_handle(&vsm
),
236 anv_CreateShader(anv_device_to_handle(device
),
237 &(VkShaderCreateInfo
) {
238 .sType
= VK_STRUCTURE_TYPE_SHADER_CREATE_INFO
,
239 .module
= anv_shader_module_to_handle(&fsm
),
243 /* We use instanced rendering to clear multiple render targets. We have two
244 * vertex buffers: the first vertex buffer holds per-vertex data and
245 * provides the vertices for the clear rectangle. The second one holds
246 * per-instance data, which consists of the VUE header (which selects the
247 * layer) and the color (Vulkan supports per-RT clear colors).
249 VkPipelineVertexInputStateCreateInfo vi_create_info
= {
250 .sType
= VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO
,
252 .pVertexBindingDescriptions
= (VkVertexInputBindingDescription
[]) {
256 .stepRate
= VK_VERTEX_INPUT_STEP_RATE_VERTEX
261 .stepRate
= VK_VERTEX_INPUT_STEP_RATE_INSTANCE
265 .pVertexAttributeDescriptions
= (VkVertexInputAttributeDescription
[]) {
270 .format
= VK_FORMAT_R32G32B32A32_UINT
,
277 .format
= VK_FORMAT_R32G32B32_SFLOAT
,
284 .format
= VK_FORMAT_R32G32B32A32_SFLOAT
,
290 anv_graphics_pipeline_create(anv_device_to_handle(device
),
291 &(VkGraphicsPipelineCreateInfo
) {
292 .sType
= VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
,
295 .pStages
= (VkPipelineShaderStageCreateInfo
[]) {
297 .sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
,
298 .stage
= VK_SHADER_STAGE_VERTEX
,
300 .pSpecializationInfo
= NULL
302 .sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
,
303 .stage
= VK_SHADER_STAGE_FRAGMENT
,
305 .pSpecializationInfo
= NULL
,
308 .pVertexInputState
= &vi_create_info
,
309 .pInputAssemblyState
= &(VkPipelineInputAssemblyStateCreateInfo
) {
310 .sType
= VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO
,
311 .topology
= VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
,
312 .primitiveRestartEnable
= false,
314 .pViewportState
= &(VkPipelineViewportStateCreateInfo
) {
315 .sType
= VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO
,
319 .pRasterState
= &(VkPipelineRasterStateCreateInfo
) {
320 .sType
= VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO
,
321 .depthClipEnable
= true,
322 .rasterizerDiscardEnable
= false,
323 .fillMode
= VK_FILL_MODE_SOLID
,
324 .cullMode
= VK_CULL_MODE_NONE
,
325 .frontFace
= VK_FRONT_FACE_CCW
327 .pMultisampleState
= &(VkPipelineMultisampleStateCreateInfo
) {
328 .sType
= VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO
,
330 .sampleShadingEnable
= false,
331 .pSampleMask
= (VkSampleMask
[]) { UINT32_MAX
},
333 .pDepthStencilState
= &(VkPipelineDepthStencilStateCreateInfo
) {
334 .sType
= VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
,
335 .depthTestEnable
= true,
336 .depthWriteEnable
= true,
337 .depthCompareOp
= VK_COMPARE_OP_ALWAYS
,
338 .depthBoundsTestEnable
= false,
339 .stencilTestEnable
= true,
340 .front
= (VkStencilOpState
) {
341 .stencilPassOp
= VK_STENCIL_OP_REPLACE
,
342 .stencilCompareOp
= VK_COMPARE_OP_ALWAYS
,
344 .back
= (VkStencilOpState
) {
345 .stencilPassOp
= VK_STENCIL_OP_REPLACE
,
346 .stencilCompareOp
= VK_COMPARE_OP_ALWAYS
,
349 .pColorBlendState
= &(VkPipelineColorBlendStateCreateInfo
) {
350 .sType
= VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO
,
351 .attachmentCount
= 1,
352 .pAttachments
= (VkPipelineColorBlendAttachmentState
[]) {
353 { .channelWriteMask
= VK_CHANNEL_A_BIT
|
354 VK_CHANNEL_R_BIT
| VK_CHANNEL_G_BIT
| VK_CHANNEL_B_BIT
},
357 .pDynamicState
= &(VkPipelineDynamicStateCreateInfo
) {
358 .sType
= VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO
,
359 .dynamicStateCount
= 9,
360 .pDynamicStates
= (VkDynamicState
[]) {
361 VK_DYNAMIC_STATE_VIEWPORT
,
362 VK_DYNAMIC_STATE_SCISSOR
,
363 VK_DYNAMIC_STATE_LINE_WIDTH
,
364 VK_DYNAMIC_STATE_DEPTH_BIAS
,
365 VK_DYNAMIC_STATE_BLEND_CONSTANTS
,
366 VK_DYNAMIC_STATE_DEPTH_BOUNDS
,
367 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK
,
368 VK_DYNAMIC_STATE_STENCIL_WRITE_MASK
,
369 VK_DYNAMIC_STATE_STENCIL_REFERENCE
,
373 .renderPass
= anv_render_pass_to_handle(&anv_meta_dummy_renderpass
),
376 &(struct anv_graphics_pipeline_create_info
) {
377 .use_repclear
= true,
378 .disable_viewport
= true,
382 &device
->meta_state
.clear
.pipeline
);
384 anv_DestroyShader(anv_device_to_handle(device
), vs
);
385 anv_DestroyShader(anv_device_to_handle(device
), fs
);
386 ralloc_free(vsm
.nir
);
387 ralloc_free(fsm
.nir
);
390 void anv_CmdClearColorImage(
391 VkCmdBuffer cmdBuffer
,
393 VkImageLayout imageLayout
,
394 const VkClearColorValue
* pColor
,
396 const VkImageSubresourceRange
* pRanges
)
398 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
399 ANV_FROM_HANDLE(anv_image
, image
, _image
);
400 struct anv_meta_saved_state saved_state
;
402 anv_meta_save(&saved_state
, cmd_buffer
,
403 (1 << VK_DYNAMIC_STATE_VIEWPORT
));
404 cmd_buffer
->state
.dynamic
.viewport
.count
= 0;
406 for (uint32_t r
= 0; r
< rangeCount
; r
++) {
407 for (uint32_t l
= 0; l
< pRanges
[r
].mipLevels
; l
++) {
408 for (uint32_t s
= 0; s
< pRanges
[r
].arraySize
; s
++) {
409 struct anv_image_view iview
;
410 anv_image_view_init(&iview
, cmd_buffer
->device
,
411 &(VkImageViewCreateInfo
) {
412 .sType
= VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
,
414 .viewType
= VK_IMAGE_VIEW_TYPE_2D
,
415 .format
= image
->format
->vk_format
,
417 VK_CHANNEL_SWIZZLE_R
,
418 VK_CHANNEL_SWIZZLE_G
,
419 VK_CHANNEL_SWIZZLE_B
,
422 .subresourceRange
= {
423 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
424 .baseMipLevel
= pRanges
[r
].baseMipLevel
+ l
,
426 .baseArrayLayer
= pRanges
[r
].baseArrayLayer
+ s
,
433 anv_CreateFramebuffer(anv_device_to_handle(cmd_buffer
->device
),
434 &(VkFramebufferCreateInfo
) {
435 .sType
= VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
,
436 .attachmentCount
= 1,
437 .pAttachments
= (VkImageView
[]) {
438 anv_image_view_to_handle(&iview
),
440 .width
= iview
.extent
.width
,
441 .height
= iview
.extent
.height
,
446 anv_CreateRenderPass(anv_device_to_handle(cmd_buffer
->device
),
447 &(VkRenderPassCreateInfo
) {
448 .sType
= VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
,
449 .attachmentCount
= 1,
450 .pAttachments
= &(VkAttachmentDescription
) {
451 .sType
= VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION
,
452 .format
= iview
.format
->vk_format
,
453 .loadOp
= VK_ATTACHMENT_LOAD_OP_LOAD
,
454 .storeOp
= VK_ATTACHMENT_STORE_OP_STORE
,
455 .initialLayout
= VK_IMAGE_LAYOUT_GENERAL
,
456 .finalLayout
= VK_IMAGE_LAYOUT_GENERAL
,
459 .pSubpasses
= &(VkSubpassDescription
) {
460 .sType
= VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION
,
461 .pipelineBindPoint
= VK_PIPELINE_BIND_POINT_GRAPHICS
,
464 .pColorAttachments
= &(VkAttachmentReference
) {
466 .layout
= VK_IMAGE_LAYOUT_GENERAL
,
468 .pResolveAttachments
= NULL
,
469 .depthStencilAttachment
= (VkAttachmentReference
) {
470 .attachment
= VK_ATTACHMENT_UNUSED
,
471 .layout
= VK_IMAGE_LAYOUT_GENERAL
,
474 .pPreserveAttachments
= &(VkAttachmentReference
) {
476 .layout
= VK_IMAGE_LAYOUT_GENERAL
,
479 .dependencyCount
= 0,
482 ANV_CALL(CmdBeginRenderPass
)(anv_cmd_buffer_to_handle(cmd_buffer
),
483 &(VkRenderPassBeginInfo
) {
484 .sType
= VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO
,
488 .width
= iview
.extent
.width
,
489 .height
= iview
.extent
.height
,
494 .clearValueCount
= 1,
495 .pClearValues
= NULL
,
496 }, VK_RENDER_PASS_CONTENTS_INLINE
);
498 struct clear_instance_data instance_data
= {
507 meta_emit_clear(cmd_buffer
, 1, &instance_data
,
508 (VkClearDepthStencilValue
) {0});
510 ANV_CALL(CmdEndRenderPass
)(anv_cmd_buffer_to_handle(cmd_buffer
));
515 anv_meta_restore(&saved_state
, cmd_buffer
);
518 void anv_CmdClearDepthStencilImage(
519 VkCmdBuffer cmdBuffer
,
521 VkImageLayout imageLayout
,
522 const VkClearDepthStencilValue
* pDepthStencil
,
524 const VkImageSubresourceRange
* pRanges
)
529 void anv_CmdClearColorAttachment(
530 VkCmdBuffer cmdBuffer
,
531 uint32_t colorAttachment
,
532 VkImageLayout imageLayout
,
533 const VkClearColorValue
* pColor
,
535 const VkRect3D
* pRects
)
540 void anv_CmdClearDepthStencilAttachment(
541 VkCmdBuffer cmdBuffer
,
542 VkImageAspectFlags aspectMask
,
543 VkImageLayout imageLayout
,
544 const VkClearDepthStencilValue
* pDepthStencil
,
546 const VkRect3D
* pRects
)