1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2016 Dave Airlie 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include <assert.h> 25bf215546Sopenharmony_ci#include <stdbool.h> 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "nir/nir_builder.h" 28bf215546Sopenharmony_ci#include "radv_meta.h" 29bf215546Sopenharmony_ci#include "radv_private.h" 30bf215546Sopenharmony_ci#include "sid.h" 31bf215546Sopenharmony_ci#include "vk_format.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_cistatic nir_shader * 34bf215546Sopenharmony_cibuild_resolve_fragment_shader(struct radv_device *dev, bool is_integer, int samples) 35bf215546Sopenharmony_ci{ 36bf215546Sopenharmony_ci enum glsl_base_type img_base_type = is_integer ? GLSL_TYPE_UINT : GLSL_TYPE_FLOAT; 37bf215546Sopenharmony_ci const struct glsl_type *vec4 = glsl_vec4_type(); 38bf215546Sopenharmony_ci const struct glsl_type *sampler_type = 39bf215546Sopenharmony_ci glsl_sampler_type(GLSL_SAMPLER_DIM_MS, false, false, img_base_type); 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci nir_builder b = radv_meta_init_shader(dev, MESA_SHADER_FRAGMENT, "meta_resolve_fs-%d-%s", 42bf215546Sopenharmony_ci samples, is_integer ? "int" : "float"); 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex"); 45bf215546Sopenharmony_ci input_img->data.descriptor_set = 0; 46bf215546Sopenharmony_ci input_img->data.binding = 0; 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color"); 49bf215546Sopenharmony_ci color_out->data.location = FRAG_RESULT_DATA0; 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci nir_ssa_def *pos_in = nir_channels(&b, nir_load_frag_coord(&b), 0x3); 52bf215546Sopenharmony_ci nir_ssa_def *src_offset = nir_load_push_constant(&b, 2, 32, nir_imm_int(&b, 0), .range = 8); 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ci nir_ssa_def *pos_int = nir_f2i32(&b, pos_in); 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci nir_ssa_def *img_coord = nir_channels(&b, nir_iadd(&b, pos_int, src_offset), 0x3); 57bf215546Sopenharmony_ci nir_variable *color = nir_local_variable_create(b.impl, glsl_vec4_type(), "color"); 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci radv_meta_build_resolve_shader_core(&b, is_integer, samples, input_img, color, img_coord); 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci nir_ssa_def *outval = nir_load_var(&b, color); 62bf215546Sopenharmony_ci nir_store_var(&b, color_out, outval, 0xf); 63bf215546Sopenharmony_ci return b.shader; 64bf215546Sopenharmony_ci} 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_cistatic VkResult 67bf215546Sopenharmony_cicreate_layout(struct radv_device *device) 68bf215546Sopenharmony_ci{ 69bf215546Sopenharmony_ci VkResult result; 70bf215546Sopenharmony_ci /* 71bf215546Sopenharmony_ci * one descriptors for the image being sampled 72bf215546Sopenharmony_ci */ 73bf215546Sopenharmony_ci VkDescriptorSetLayoutCreateInfo ds_create_info = { 74bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 75bf215546Sopenharmony_ci .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, 76bf215546Sopenharmony_ci .bindingCount = 1, 77bf215546Sopenharmony_ci .pBindings = (VkDescriptorSetLayoutBinding[]){ 78bf215546Sopenharmony_ci {.binding = 0, 79bf215546Sopenharmony_ci .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 80bf215546Sopenharmony_ci .descriptorCount = 1, 81bf215546Sopenharmony_ci .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, 82bf215546Sopenharmony_ci .pImmutableSamplers = NULL}, 83bf215546Sopenharmony_ci }}; 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ci result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &ds_create_info, 86bf215546Sopenharmony_ci &device->meta_state.alloc, 87bf215546Sopenharmony_ci &device->meta_state.resolve_fragment.ds_layout); 88bf215546Sopenharmony_ci if (result != VK_SUCCESS) 89bf215546Sopenharmony_ci goto fail; 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci VkPipelineLayoutCreateInfo pl_create_info = { 92bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 93bf215546Sopenharmony_ci .setLayoutCount = 1, 94bf215546Sopenharmony_ci .pSetLayouts = &device->meta_state.resolve_fragment.ds_layout, 95bf215546Sopenharmony_ci .pushConstantRangeCount = 1, 96bf215546Sopenharmony_ci .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_FRAGMENT_BIT, 0, 8}, 97bf215546Sopenharmony_ci }; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci result = radv_CreatePipelineLayout(radv_device_to_handle(device), &pl_create_info, 100bf215546Sopenharmony_ci &device->meta_state.alloc, 101bf215546Sopenharmony_ci &device->meta_state.resolve_fragment.p_layout); 102bf215546Sopenharmony_ci if (result != VK_SUCCESS) 103bf215546Sopenharmony_ci goto fail; 104bf215546Sopenharmony_ci return VK_SUCCESS; 105bf215546Sopenharmony_cifail: 106bf215546Sopenharmony_ci return result; 107bf215546Sopenharmony_ci} 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_cistatic const VkPipelineVertexInputStateCreateInfo normal_vi_create_info = { 110bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, 111bf215546Sopenharmony_ci .vertexBindingDescriptionCount = 0, 112bf215546Sopenharmony_ci .vertexAttributeDescriptionCount = 0, 113bf215546Sopenharmony_ci}; 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_cistatic VkResult 116bf215546Sopenharmony_cicreate_resolve_pipeline(struct radv_device *device, int samples_log2, VkFormat format) 117bf215546Sopenharmony_ci{ 118bf215546Sopenharmony_ci mtx_lock(&device->meta_state.mtx); 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci unsigned fs_key = radv_format_meta_fs_key(device, format); 121bf215546Sopenharmony_ci VkPipeline *pipeline = &device->meta_state.resolve_fragment.rc[samples_log2].pipeline[fs_key]; 122bf215546Sopenharmony_ci if (*pipeline) { 123bf215546Sopenharmony_ci mtx_unlock(&device->meta_state.mtx); 124bf215546Sopenharmony_ci return VK_SUCCESS; 125bf215546Sopenharmony_ci } 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci VkResult result; 128bf215546Sopenharmony_ci bool is_integer = false; 129bf215546Sopenharmony_ci uint32_t samples = 1 << samples_log2; 130bf215546Sopenharmony_ci const VkPipelineVertexInputStateCreateInfo *vi_create_info; 131bf215546Sopenharmony_ci vi_create_info = &normal_vi_create_info; 132bf215546Sopenharmony_ci if (vk_format_is_int(format)) 133bf215546Sopenharmony_ci is_integer = true; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci nir_shader *fs = build_resolve_fragment_shader(device, is_integer, samples); 136bf215546Sopenharmony_ci nir_shader *vs = radv_meta_build_nir_vs_generate_vertices(device); 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = { 139bf215546Sopenharmony_ci {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 140bf215546Sopenharmony_ci .stage = VK_SHADER_STAGE_VERTEX_BIT, 141bf215546Sopenharmony_ci .module = vk_shader_module_handle_from_nir(vs), 142bf215546Sopenharmony_ci .pName = "main", 143bf215546Sopenharmony_ci .pSpecializationInfo = NULL}, 144bf215546Sopenharmony_ci {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 145bf215546Sopenharmony_ci .stage = VK_SHADER_STAGE_FRAGMENT_BIT, 146bf215546Sopenharmony_ci .module = vk_shader_module_handle_from_nir(fs), 147bf215546Sopenharmony_ci .pName = "main", 148bf215546Sopenharmony_ci .pSpecializationInfo = NULL}, 149bf215546Sopenharmony_ci }; 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci const VkPipelineRenderingCreateInfo rendering_create_info = { 152bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, 153bf215546Sopenharmony_ci .colorAttachmentCount = 1, 154bf215546Sopenharmony_ci .pColorAttachmentFormats = &format, 155bf215546Sopenharmony_ci }; 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci const VkGraphicsPipelineCreateInfo vk_pipeline_info = { 158bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, 159bf215546Sopenharmony_ci .pNext = &rendering_create_info, 160bf215546Sopenharmony_ci .stageCount = ARRAY_SIZE(pipeline_shader_stages), 161bf215546Sopenharmony_ci .pStages = pipeline_shader_stages, 162bf215546Sopenharmony_ci .pVertexInputState = vi_create_info, 163bf215546Sopenharmony_ci .pInputAssemblyState = 164bf215546Sopenharmony_ci &(VkPipelineInputAssemblyStateCreateInfo){ 165bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, 166bf215546Sopenharmony_ci .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 167bf215546Sopenharmony_ci .primitiveRestartEnable = false, 168bf215546Sopenharmony_ci }, 169bf215546Sopenharmony_ci .pViewportState = 170bf215546Sopenharmony_ci &(VkPipelineViewportStateCreateInfo){ 171bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, 172bf215546Sopenharmony_ci .viewportCount = 1, 173bf215546Sopenharmony_ci .scissorCount = 1, 174bf215546Sopenharmony_ci }, 175bf215546Sopenharmony_ci .pRasterizationState = 176bf215546Sopenharmony_ci &(VkPipelineRasterizationStateCreateInfo){ 177bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, 178bf215546Sopenharmony_ci .rasterizerDiscardEnable = false, 179bf215546Sopenharmony_ci .polygonMode = VK_POLYGON_MODE_FILL, 180bf215546Sopenharmony_ci .cullMode = VK_CULL_MODE_NONE, 181bf215546Sopenharmony_ci .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, 182bf215546Sopenharmony_ci .depthBiasConstantFactor = 0.0f, 183bf215546Sopenharmony_ci .depthBiasClamp = 0.0f, 184bf215546Sopenharmony_ci .depthBiasSlopeFactor = 0.0f, 185bf215546Sopenharmony_ci .lineWidth = 1.0f}, 186bf215546Sopenharmony_ci .pMultisampleState = 187bf215546Sopenharmony_ci &(VkPipelineMultisampleStateCreateInfo){ 188bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, 189bf215546Sopenharmony_ci .rasterizationSamples = 1, 190bf215546Sopenharmony_ci .sampleShadingEnable = false, 191bf215546Sopenharmony_ci .pSampleMask = (VkSampleMask[]){UINT32_MAX}, 192bf215546Sopenharmony_ci }, 193bf215546Sopenharmony_ci .pColorBlendState = 194bf215546Sopenharmony_ci &(VkPipelineColorBlendStateCreateInfo){ 195bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, 196bf215546Sopenharmony_ci .attachmentCount = 1, 197bf215546Sopenharmony_ci .pAttachments = 198bf215546Sopenharmony_ci (VkPipelineColorBlendAttachmentState[]){ 199bf215546Sopenharmony_ci {.colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_R_BIT | 200bf215546Sopenharmony_ci VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT}, 201bf215546Sopenharmony_ci }, 202bf215546Sopenharmony_ci .blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f }}, 203bf215546Sopenharmony_ci .pDynamicState = 204bf215546Sopenharmony_ci &(VkPipelineDynamicStateCreateInfo){ 205bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, 206bf215546Sopenharmony_ci .dynamicStateCount = 2, 207bf215546Sopenharmony_ci .pDynamicStates = 208bf215546Sopenharmony_ci (VkDynamicState[]){ 209bf215546Sopenharmony_ci VK_DYNAMIC_STATE_VIEWPORT, 210bf215546Sopenharmony_ci VK_DYNAMIC_STATE_SCISSOR, 211bf215546Sopenharmony_ci }, 212bf215546Sopenharmony_ci }, 213bf215546Sopenharmony_ci .flags = 0, 214bf215546Sopenharmony_ci .layout = device->meta_state.resolve_fragment.p_layout, 215bf215546Sopenharmony_ci .renderPass = VK_NULL_HANDLE, 216bf215546Sopenharmony_ci .subpass = 0, 217bf215546Sopenharmony_ci }; 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true}; 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci result = radv_graphics_pipeline_create( 222bf215546Sopenharmony_ci radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache), 223bf215546Sopenharmony_ci &vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc, pipeline); 224bf215546Sopenharmony_ci ralloc_free(vs); 225bf215546Sopenharmony_ci ralloc_free(fs); 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci mtx_unlock(&device->meta_state.mtx); 228bf215546Sopenharmony_ci return result; 229bf215546Sopenharmony_ci} 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_cienum { DEPTH_RESOLVE, STENCIL_RESOLVE }; 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_cistatic const char * 234bf215546Sopenharmony_ciget_resolve_mode_str(VkResolveModeFlagBits resolve_mode) 235bf215546Sopenharmony_ci{ 236bf215546Sopenharmony_ci switch (resolve_mode) { 237bf215546Sopenharmony_ci case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT: 238bf215546Sopenharmony_ci return "zero"; 239bf215546Sopenharmony_ci case VK_RESOLVE_MODE_AVERAGE_BIT: 240bf215546Sopenharmony_ci return "average"; 241bf215546Sopenharmony_ci case VK_RESOLVE_MODE_MIN_BIT: 242bf215546Sopenharmony_ci return "min"; 243bf215546Sopenharmony_ci case VK_RESOLVE_MODE_MAX_BIT: 244bf215546Sopenharmony_ci return "max"; 245bf215546Sopenharmony_ci default: 246bf215546Sopenharmony_ci unreachable("invalid resolve mode"); 247bf215546Sopenharmony_ci } 248bf215546Sopenharmony_ci} 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_cistatic nir_shader * 251bf215546Sopenharmony_cibuild_depth_stencil_resolve_fragment_shader(struct radv_device *dev, int samples, int index, 252bf215546Sopenharmony_ci VkResolveModeFlagBits resolve_mode) 253bf215546Sopenharmony_ci{ 254bf215546Sopenharmony_ci enum glsl_base_type img_base_type = index == DEPTH_RESOLVE ? GLSL_TYPE_FLOAT : GLSL_TYPE_UINT; 255bf215546Sopenharmony_ci const struct glsl_type *vec4 = glsl_vec4_type(); 256bf215546Sopenharmony_ci const struct glsl_type *sampler_type = 257bf215546Sopenharmony_ci glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false, img_base_type); 258bf215546Sopenharmony_ci 259bf215546Sopenharmony_ci nir_builder b = radv_meta_init_shader(dev, MESA_SHADER_FRAGMENT, "meta_resolve_fs_%s-%s-%d", 260bf215546Sopenharmony_ci index == DEPTH_RESOLVE ? "depth" : "stencil", 261bf215546Sopenharmony_ci get_resolve_mode_str(resolve_mode), samples); 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex"); 264bf215546Sopenharmony_ci input_img->data.descriptor_set = 0; 265bf215546Sopenharmony_ci input_img->data.binding = 0; 266bf215546Sopenharmony_ci 267bf215546Sopenharmony_ci nir_variable *fs_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_out"); 268bf215546Sopenharmony_ci fs_out->data.location = index == DEPTH_RESOLVE ? FRAG_RESULT_DEPTH : FRAG_RESULT_STENCIL; 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_ci nir_ssa_def *pos_in = nir_channels(&b, nir_load_frag_coord(&b), 0x3); 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci nir_ssa_def *pos_int = nir_f2i32(&b, pos_in); 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci nir_ssa_def *img_coord = nir_channels(&b, pos_int, 0x3); 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ci nir_ssa_def *input_img_deref = &nir_build_deref_var(&b, input_img)->dest.ssa; 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci nir_alu_type type = index == DEPTH_RESOLVE ? nir_type_float32 : nir_type_uint32; 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3); 281bf215546Sopenharmony_ci tex->sampler_dim = GLSL_SAMPLER_DIM_MS; 282bf215546Sopenharmony_ci tex->op = nir_texop_txf_ms; 283bf215546Sopenharmony_ci tex->src[0].src_type = nir_tex_src_coord; 284bf215546Sopenharmony_ci tex->src[0].src = nir_src_for_ssa(img_coord); 285bf215546Sopenharmony_ci tex->src[1].src_type = nir_tex_src_ms_index; 286bf215546Sopenharmony_ci tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0)); 287bf215546Sopenharmony_ci tex->src[2].src_type = nir_tex_src_texture_deref; 288bf215546Sopenharmony_ci tex->src[2].src = nir_src_for_ssa(input_img_deref); 289bf215546Sopenharmony_ci tex->dest_type = type; 290bf215546Sopenharmony_ci tex->is_array = false; 291bf215546Sopenharmony_ci tex->coord_components = 2; 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex"); 294bf215546Sopenharmony_ci nir_builder_instr_insert(&b, &tex->instr); 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci nir_ssa_def *outval = &tex->dest.ssa; 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci if (resolve_mode != VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) { 299bf215546Sopenharmony_ci for (int i = 1; i < samples; i++) { 300bf215546Sopenharmony_ci nir_tex_instr *tex_add = nir_tex_instr_create(b.shader, 3); 301bf215546Sopenharmony_ci tex_add->sampler_dim = GLSL_SAMPLER_DIM_MS; 302bf215546Sopenharmony_ci tex_add->op = nir_texop_txf_ms; 303bf215546Sopenharmony_ci tex_add->src[0].src_type = nir_tex_src_coord; 304bf215546Sopenharmony_ci tex_add->src[0].src = nir_src_for_ssa(img_coord); 305bf215546Sopenharmony_ci tex_add->src[1].src_type = nir_tex_src_ms_index; 306bf215546Sopenharmony_ci tex_add->src[1].src = nir_src_for_ssa(nir_imm_int(&b, i)); 307bf215546Sopenharmony_ci tex_add->src[2].src_type = nir_tex_src_texture_deref; 308bf215546Sopenharmony_ci tex_add->src[2].src = nir_src_for_ssa(input_img_deref); 309bf215546Sopenharmony_ci tex_add->dest_type = type; 310bf215546Sopenharmony_ci tex_add->is_array = false; 311bf215546Sopenharmony_ci tex_add->coord_components = 2; 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci nir_ssa_dest_init(&tex_add->instr, &tex_add->dest, 4, 32, "tex"); 314bf215546Sopenharmony_ci nir_builder_instr_insert(&b, &tex_add->instr); 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_ci switch (resolve_mode) { 317bf215546Sopenharmony_ci case VK_RESOLVE_MODE_AVERAGE_BIT: 318bf215546Sopenharmony_ci assert(index == DEPTH_RESOLVE); 319bf215546Sopenharmony_ci outval = nir_fadd(&b, outval, &tex_add->dest.ssa); 320bf215546Sopenharmony_ci break; 321bf215546Sopenharmony_ci case VK_RESOLVE_MODE_MIN_BIT: 322bf215546Sopenharmony_ci if (index == DEPTH_RESOLVE) 323bf215546Sopenharmony_ci outval = nir_fmin(&b, outval, &tex_add->dest.ssa); 324bf215546Sopenharmony_ci else 325bf215546Sopenharmony_ci outval = nir_umin(&b, outval, &tex_add->dest.ssa); 326bf215546Sopenharmony_ci break; 327bf215546Sopenharmony_ci case VK_RESOLVE_MODE_MAX_BIT: 328bf215546Sopenharmony_ci if (index == DEPTH_RESOLVE) 329bf215546Sopenharmony_ci outval = nir_fmax(&b, outval, &tex_add->dest.ssa); 330bf215546Sopenharmony_ci else 331bf215546Sopenharmony_ci outval = nir_umax(&b, outval, &tex_add->dest.ssa); 332bf215546Sopenharmony_ci break; 333bf215546Sopenharmony_ci default: 334bf215546Sopenharmony_ci unreachable("invalid resolve mode"); 335bf215546Sopenharmony_ci } 336bf215546Sopenharmony_ci } 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_ci if (resolve_mode == VK_RESOLVE_MODE_AVERAGE_BIT) 339bf215546Sopenharmony_ci outval = nir_fdiv(&b, outval, nir_imm_float(&b, samples)); 340bf215546Sopenharmony_ci } 341bf215546Sopenharmony_ci 342bf215546Sopenharmony_ci nir_store_var(&b, fs_out, outval, 0x1); 343bf215546Sopenharmony_ci 344bf215546Sopenharmony_ci return b.shader; 345bf215546Sopenharmony_ci} 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_cistatic VkResult 348bf215546Sopenharmony_cicreate_depth_stencil_resolve_pipeline(struct radv_device *device, int samples_log2, int index, 349bf215546Sopenharmony_ci VkResolveModeFlagBits resolve_mode) 350bf215546Sopenharmony_ci{ 351bf215546Sopenharmony_ci VkPipeline *pipeline; 352bf215546Sopenharmony_ci VkResult result; 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci mtx_lock(&device->meta_state.mtx); 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci switch (resolve_mode) { 357bf215546Sopenharmony_ci case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT: 358bf215546Sopenharmony_ci if (index == DEPTH_RESOLVE) 359bf215546Sopenharmony_ci pipeline = &device->meta_state.resolve_fragment.depth_zero_pipeline; 360bf215546Sopenharmony_ci else 361bf215546Sopenharmony_ci pipeline = &device->meta_state.resolve_fragment.stencil_zero_pipeline; 362bf215546Sopenharmony_ci break; 363bf215546Sopenharmony_ci case VK_RESOLVE_MODE_AVERAGE_BIT: 364bf215546Sopenharmony_ci assert(index == DEPTH_RESOLVE); 365bf215546Sopenharmony_ci pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].average_pipeline; 366bf215546Sopenharmony_ci break; 367bf215546Sopenharmony_ci case VK_RESOLVE_MODE_MIN_BIT: 368bf215546Sopenharmony_ci if (index == DEPTH_RESOLVE) 369bf215546Sopenharmony_ci pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].min_pipeline; 370bf215546Sopenharmony_ci else 371bf215546Sopenharmony_ci pipeline = &device->meta_state.resolve_fragment.stencil[samples_log2].min_pipeline; 372bf215546Sopenharmony_ci break; 373bf215546Sopenharmony_ci case VK_RESOLVE_MODE_MAX_BIT: 374bf215546Sopenharmony_ci if (index == DEPTH_RESOLVE) 375bf215546Sopenharmony_ci pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].max_pipeline; 376bf215546Sopenharmony_ci else 377bf215546Sopenharmony_ci pipeline = &device->meta_state.resolve_fragment.stencil[samples_log2].max_pipeline; 378bf215546Sopenharmony_ci break; 379bf215546Sopenharmony_ci default: 380bf215546Sopenharmony_ci unreachable("invalid resolve mode"); 381bf215546Sopenharmony_ci } 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci if (*pipeline) { 384bf215546Sopenharmony_ci mtx_unlock(&device->meta_state.mtx); 385bf215546Sopenharmony_ci return VK_SUCCESS; 386bf215546Sopenharmony_ci } 387bf215546Sopenharmony_ci 388bf215546Sopenharmony_ci uint32_t samples = 1 << samples_log2; 389bf215546Sopenharmony_ci nir_shader *fs = 390bf215546Sopenharmony_ci build_depth_stencil_resolve_fragment_shader(device, samples, index, resolve_mode); 391bf215546Sopenharmony_ci nir_shader *vs = radv_meta_build_nir_vs_generate_vertices(device); 392bf215546Sopenharmony_ci 393bf215546Sopenharmony_ci VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = { 394bf215546Sopenharmony_ci {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 395bf215546Sopenharmony_ci .stage = VK_SHADER_STAGE_VERTEX_BIT, 396bf215546Sopenharmony_ci .module = vk_shader_module_handle_from_nir(vs), 397bf215546Sopenharmony_ci .pName = "main", 398bf215546Sopenharmony_ci .pSpecializationInfo = NULL}, 399bf215546Sopenharmony_ci {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 400bf215546Sopenharmony_ci .stage = VK_SHADER_STAGE_FRAGMENT_BIT, 401bf215546Sopenharmony_ci .module = vk_shader_module_handle_from_nir(fs), 402bf215546Sopenharmony_ci .pName = "main", 403bf215546Sopenharmony_ci .pSpecializationInfo = NULL}, 404bf215546Sopenharmony_ci }; 405bf215546Sopenharmony_ci 406bf215546Sopenharmony_ci VkStencilOp stencil_op = index == DEPTH_RESOLVE ? VK_STENCIL_OP_KEEP : VK_STENCIL_OP_REPLACE; 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci VkPipelineDepthStencilStateCreateInfo depth_stencil_state = { 409bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, 410bf215546Sopenharmony_ci .depthTestEnable = true, 411bf215546Sopenharmony_ci .depthWriteEnable = index == DEPTH_RESOLVE, 412bf215546Sopenharmony_ci .stencilTestEnable = index == STENCIL_RESOLVE, 413bf215546Sopenharmony_ci .depthCompareOp = VK_COMPARE_OP_ALWAYS, 414bf215546Sopenharmony_ci .front = 415bf215546Sopenharmony_ci { 416bf215546Sopenharmony_ci .failOp = stencil_op, 417bf215546Sopenharmony_ci .passOp = stencil_op, 418bf215546Sopenharmony_ci .depthFailOp = stencil_op, 419bf215546Sopenharmony_ci .compareOp = VK_COMPARE_OP_ALWAYS, 420bf215546Sopenharmony_ci .compareMask = UINT32_MAX, 421bf215546Sopenharmony_ci .writeMask = UINT32_MAX, 422bf215546Sopenharmony_ci .reference = 0u, 423bf215546Sopenharmony_ci }, 424bf215546Sopenharmony_ci .back = { 425bf215546Sopenharmony_ci .failOp = stencil_op, 426bf215546Sopenharmony_ci .passOp = stencil_op, 427bf215546Sopenharmony_ci .depthFailOp = stencil_op, 428bf215546Sopenharmony_ci .compareOp = VK_COMPARE_OP_ALWAYS, 429bf215546Sopenharmony_ci .compareMask = UINT32_MAX, 430bf215546Sopenharmony_ci .writeMask = UINT32_MAX, 431bf215546Sopenharmony_ci .reference = 0u, 432bf215546Sopenharmony_ci }, 433bf215546Sopenharmony_ci .minDepthBounds = 0.0f, 434bf215546Sopenharmony_ci .maxDepthBounds = 1.0f}; 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_ci const VkPipelineVertexInputStateCreateInfo *vi_create_info; 437bf215546Sopenharmony_ci vi_create_info = &normal_vi_create_info; 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_ci const VkPipelineRenderingCreateInfo rendering_create_info = { 440bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, 441bf215546Sopenharmony_ci .depthAttachmentFormat = index == DEPTH_RESOLVE ? VK_FORMAT_D32_SFLOAT : VK_FORMAT_UNDEFINED, 442bf215546Sopenharmony_ci .stencilAttachmentFormat = index == STENCIL_RESOLVE ? VK_FORMAT_S8_UINT : VK_FORMAT_UNDEFINED, 443bf215546Sopenharmony_ci }; 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_ci const VkGraphicsPipelineCreateInfo vk_pipeline_info = { 446bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, 447bf215546Sopenharmony_ci .pNext = &rendering_create_info, 448bf215546Sopenharmony_ci .stageCount = ARRAY_SIZE(pipeline_shader_stages), 449bf215546Sopenharmony_ci .pStages = pipeline_shader_stages, 450bf215546Sopenharmony_ci .pVertexInputState = vi_create_info, 451bf215546Sopenharmony_ci .pInputAssemblyState = 452bf215546Sopenharmony_ci &(VkPipelineInputAssemblyStateCreateInfo){ 453bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, 454bf215546Sopenharmony_ci .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 455bf215546Sopenharmony_ci .primitiveRestartEnable = false, 456bf215546Sopenharmony_ci }, 457bf215546Sopenharmony_ci .pViewportState = 458bf215546Sopenharmony_ci &(VkPipelineViewportStateCreateInfo){ 459bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, 460bf215546Sopenharmony_ci .viewportCount = 1, 461bf215546Sopenharmony_ci .scissorCount = 1, 462bf215546Sopenharmony_ci }, 463bf215546Sopenharmony_ci .pDepthStencilState = &depth_stencil_state, 464bf215546Sopenharmony_ci .pRasterizationState = 465bf215546Sopenharmony_ci &(VkPipelineRasterizationStateCreateInfo){ 466bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, 467bf215546Sopenharmony_ci .rasterizerDiscardEnable = false, 468bf215546Sopenharmony_ci .polygonMode = VK_POLYGON_MODE_FILL, 469bf215546Sopenharmony_ci .cullMode = VK_CULL_MODE_NONE, 470bf215546Sopenharmony_ci .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, 471bf215546Sopenharmony_ci .depthBiasConstantFactor = 0.0f, 472bf215546Sopenharmony_ci .depthBiasClamp = 0.0f, 473bf215546Sopenharmony_ci .depthBiasSlopeFactor = 0.0f, 474bf215546Sopenharmony_ci .lineWidth = 1.0f}, 475bf215546Sopenharmony_ci .pMultisampleState = 476bf215546Sopenharmony_ci &(VkPipelineMultisampleStateCreateInfo){ 477bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, 478bf215546Sopenharmony_ci .rasterizationSamples = 1, 479bf215546Sopenharmony_ci .sampleShadingEnable = false, 480bf215546Sopenharmony_ci .pSampleMask = (VkSampleMask[]){UINT32_MAX}, 481bf215546Sopenharmony_ci }, 482bf215546Sopenharmony_ci .pColorBlendState = 483bf215546Sopenharmony_ci &(VkPipelineColorBlendStateCreateInfo){ 484bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, 485bf215546Sopenharmony_ci .attachmentCount = 0, 486bf215546Sopenharmony_ci .pAttachments = 487bf215546Sopenharmony_ci (VkPipelineColorBlendAttachmentState[]){ 488bf215546Sopenharmony_ci {.colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_R_BIT | 489bf215546Sopenharmony_ci VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT}, 490bf215546Sopenharmony_ci }, 491bf215546Sopenharmony_ci .blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f }}, 492bf215546Sopenharmony_ci .pDynamicState = 493bf215546Sopenharmony_ci &(VkPipelineDynamicStateCreateInfo){ 494bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, 495bf215546Sopenharmony_ci .dynamicStateCount = 2, 496bf215546Sopenharmony_ci .pDynamicStates = 497bf215546Sopenharmony_ci (VkDynamicState[]){ 498bf215546Sopenharmony_ci VK_DYNAMIC_STATE_VIEWPORT, 499bf215546Sopenharmony_ci VK_DYNAMIC_STATE_SCISSOR, 500bf215546Sopenharmony_ci }, 501bf215546Sopenharmony_ci }, 502bf215546Sopenharmony_ci .flags = 0, 503bf215546Sopenharmony_ci .layout = device->meta_state.resolve_fragment.p_layout, 504bf215546Sopenharmony_ci .renderPass = VK_NULL_HANDLE, 505bf215546Sopenharmony_ci .subpass = 0, 506bf215546Sopenharmony_ci }; 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_ci const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true}; 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci result = radv_graphics_pipeline_create( 511bf215546Sopenharmony_ci radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache), 512bf215546Sopenharmony_ci &vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc, pipeline); 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci ralloc_free(vs); 515bf215546Sopenharmony_ci ralloc_free(fs); 516bf215546Sopenharmony_ci 517bf215546Sopenharmony_ci mtx_unlock(&device->meta_state.mtx); 518bf215546Sopenharmony_ci return result; 519bf215546Sopenharmony_ci} 520bf215546Sopenharmony_ci 521bf215546Sopenharmony_ciVkResult 522bf215546Sopenharmony_ciradv_device_init_meta_resolve_fragment_state(struct radv_device *device, bool on_demand) 523bf215546Sopenharmony_ci{ 524bf215546Sopenharmony_ci VkResult res; 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci res = create_layout(device); 527bf215546Sopenharmony_ci if (res != VK_SUCCESS) 528bf215546Sopenharmony_ci return res; 529bf215546Sopenharmony_ci 530bf215546Sopenharmony_ci if (on_demand) 531bf215546Sopenharmony_ci return VK_SUCCESS; 532bf215546Sopenharmony_ci 533bf215546Sopenharmony_ci for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; ++i) { 534bf215546Sopenharmony_ci for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) { 535bf215546Sopenharmony_ci res = create_resolve_pipeline(device, i, radv_fs_key_format_exemplars[j]); 536bf215546Sopenharmony_ci if (res != VK_SUCCESS) 537bf215546Sopenharmony_ci return res; 538bf215546Sopenharmony_ci } 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci res = create_depth_stencil_resolve_pipeline(device, i, DEPTH_RESOLVE, 541bf215546Sopenharmony_ci VK_RESOLVE_MODE_AVERAGE_BIT); 542bf215546Sopenharmony_ci if (res != VK_SUCCESS) 543bf215546Sopenharmony_ci return res; 544bf215546Sopenharmony_ci 545bf215546Sopenharmony_ci res = create_depth_stencil_resolve_pipeline(device, i, DEPTH_RESOLVE, 546bf215546Sopenharmony_ci VK_RESOLVE_MODE_MIN_BIT); 547bf215546Sopenharmony_ci if (res != VK_SUCCESS) 548bf215546Sopenharmony_ci return res; 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ci res = create_depth_stencil_resolve_pipeline(device, i, DEPTH_RESOLVE, 551bf215546Sopenharmony_ci VK_RESOLVE_MODE_MAX_BIT); 552bf215546Sopenharmony_ci if (res != VK_SUCCESS) 553bf215546Sopenharmony_ci return res; 554bf215546Sopenharmony_ci 555bf215546Sopenharmony_ci res = create_depth_stencil_resolve_pipeline(device, i, STENCIL_RESOLVE, 556bf215546Sopenharmony_ci VK_RESOLVE_MODE_MIN_BIT); 557bf215546Sopenharmony_ci if (res != VK_SUCCESS) 558bf215546Sopenharmony_ci return res; 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_ci res = create_depth_stencil_resolve_pipeline(device, i, STENCIL_RESOLVE, 561bf215546Sopenharmony_ci VK_RESOLVE_MODE_MAX_BIT); 562bf215546Sopenharmony_ci if (res != VK_SUCCESS) 563bf215546Sopenharmony_ci return res; 564bf215546Sopenharmony_ci } 565bf215546Sopenharmony_ci 566bf215546Sopenharmony_ci res = create_depth_stencil_resolve_pipeline(device, 0, DEPTH_RESOLVE, 567bf215546Sopenharmony_ci VK_RESOLVE_MODE_SAMPLE_ZERO_BIT); 568bf215546Sopenharmony_ci if (res != VK_SUCCESS) 569bf215546Sopenharmony_ci return res; 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ci return create_depth_stencil_resolve_pipeline(device, 0, STENCIL_RESOLVE, 572bf215546Sopenharmony_ci VK_RESOLVE_MODE_SAMPLE_ZERO_BIT); 573bf215546Sopenharmony_ci} 574bf215546Sopenharmony_ci 575bf215546Sopenharmony_civoid 576bf215546Sopenharmony_ciradv_device_finish_meta_resolve_fragment_state(struct radv_device *device) 577bf215546Sopenharmony_ci{ 578bf215546Sopenharmony_ci struct radv_meta_state *state = &device->meta_state; 579bf215546Sopenharmony_ci for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; ++i) { 580bf215546Sopenharmony_ci for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) { 581bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 582bf215546Sopenharmony_ci state->resolve_fragment.rc[i].pipeline[j], &state->alloc); 583bf215546Sopenharmony_ci } 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 586bf215546Sopenharmony_ci state->resolve_fragment.depth[i].average_pipeline, &state->alloc); 587bf215546Sopenharmony_ci 588bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 589bf215546Sopenharmony_ci state->resolve_fragment.depth[i].max_pipeline, &state->alloc); 590bf215546Sopenharmony_ci 591bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 592bf215546Sopenharmony_ci state->resolve_fragment.depth[i].min_pipeline, &state->alloc); 593bf215546Sopenharmony_ci 594bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 595bf215546Sopenharmony_ci state->resolve_fragment.stencil[i].max_pipeline, &state->alloc); 596bf215546Sopenharmony_ci 597bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 598bf215546Sopenharmony_ci state->resolve_fragment.stencil[i].min_pipeline, &state->alloc); 599bf215546Sopenharmony_ci } 600bf215546Sopenharmony_ci 601bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), state->resolve_fragment.depth_zero_pipeline, 602bf215546Sopenharmony_ci &state->alloc); 603bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 604bf215546Sopenharmony_ci state->resolve_fragment.stencil_zero_pipeline, &state->alloc); 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_ci device->vk.dispatch_table.DestroyDescriptorSetLayout( 607bf215546Sopenharmony_ci radv_device_to_handle(device), state->resolve_fragment.ds_layout, &state->alloc); 608bf215546Sopenharmony_ci radv_DestroyPipelineLayout(radv_device_to_handle(device), state->resolve_fragment.p_layout, 609bf215546Sopenharmony_ci &state->alloc); 610bf215546Sopenharmony_ci} 611bf215546Sopenharmony_ci 612bf215546Sopenharmony_cistatic VkPipeline * 613bf215546Sopenharmony_ciradv_get_resolve_pipeline(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview, 614bf215546Sopenharmony_ci struct radv_image_view *dst_iview) 615bf215546Sopenharmony_ci{ 616bf215546Sopenharmony_ci struct radv_device *device = cmd_buffer->device; 617bf215546Sopenharmony_ci unsigned fs_key = radv_format_meta_fs_key(cmd_buffer->device, dst_iview->vk.format); 618bf215546Sopenharmony_ci const uint32_t samples = src_iview->image->info.samples; 619bf215546Sopenharmony_ci const uint32_t samples_log2 = ffs(samples) - 1; 620bf215546Sopenharmony_ci VkPipeline *pipeline; 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ci pipeline = &device->meta_state.resolve_fragment.rc[samples_log2].pipeline[fs_key]; 623bf215546Sopenharmony_ci if (!*pipeline) { 624bf215546Sopenharmony_ci VkResult ret; 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci ret = create_resolve_pipeline(device, samples_log2, radv_fs_key_format_exemplars[fs_key]); 627bf215546Sopenharmony_ci if (ret != VK_SUCCESS) { 628bf215546Sopenharmony_ci cmd_buffer->record_result = ret; 629bf215546Sopenharmony_ci return NULL; 630bf215546Sopenharmony_ci } 631bf215546Sopenharmony_ci } 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_ci return pipeline; 634bf215546Sopenharmony_ci} 635bf215546Sopenharmony_ci 636bf215546Sopenharmony_cistatic void 637bf215546Sopenharmony_ciemit_resolve(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview, 638bf215546Sopenharmony_ci struct radv_image_view *dest_iview, const VkOffset2D *src_offset, 639bf215546Sopenharmony_ci const VkOffset2D *dest_offset, const VkExtent2D *resolve_extent) 640bf215546Sopenharmony_ci{ 641bf215546Sopenharmony_ci struct radv_device *device = cmd_buffer->device; 642bf215546Sopenharmony_ci VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer); 643bf215546Sopenharmony_ci VkPipeline *pipeline; 644bf215546Sopenharmony_ci 645bf215546Sopenharmony_ci radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, 646bf215546Sopenharmony_ci cmd_buffer->device->meta_state.resolve_fragment.p_layout, 647bf215546Sopenharmony_ci 0, /* set */ 648bf215546Sopenharmony_ci 1, /* descriptorWriteCount */ 649bf215546Sopenharmony_ci (VkWriteDescriptorSet[]){ 650bf215546Sopenharmony_ci {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 651bf215546Sopenharmony_ci .dstBinding = 0, 652bf215546Sopenharmony_ci .dstArrayElement = 0, 653bf215546Sopenharmony_ci .descriptorCount = 1, 654bf215546Sopenharmony_ci .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 655bf215546Sopenharmony_ci .pImageInfo = 656bf215546Sopenharmony_ci (VkDescriptorImageInfo[]){ 657bf215546Sopenharmony_ci { 658bf215546Sopenharmony_ci .sampler = VK_NULL_HANDLE, 659bf215546Sopenharmony_ci .imageView = radv_image_view_to_handle(src_iview), 660bf215546Sopenharmony_ci .imageLayout = VK_IMAGE_LAYOUT_GENERAL, 661bf215546Sopenharmony_ci }, 662bf215546Sopenharmony_ci }}, 663bf215546Sopenharmony_ci }); 664bf215546Sopenharmony_ci 665bf215546Sopenharmony_ci cmd_buffer->state.flush_bits |= 666bf215546Sopenharmony_ci radv_dst_access_flush(cmd_buffer, VK_ACCESS_2_SHADER_READ_BIT, src_iview->image) | 667bf215546Sopenharmony_ci radv_dst_access_flush(cmd_buffer, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, dest_iview->image); 668bf215546Sopenharmony_ci 669bf215546Sopenharmony_ci unsigned push_constants[2] = { 670bf215546Sopenharmony_ci src_offset->x - dest_offset->x, 671bf215546Sopenharmony_ci src_offset->y - dest_offset->y, 672bf215546Sopenharmony_ci }; 673bf215546Sopenharmony_ci radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), 674bf215546Sopenharmony_ci device->meta_state.resolve_fragment.p_layout, VK_SHADER_STAGE_FRAGMENT_BIT, 675bf215546Sopenharmony_ci 0, 8, push_constants); 676bf215546Sopenharmony_ci 677bf215546Sopenharmony_ci pipeline = radv_get_resolve_pipeline(cmd_buffer, src_iview, dest_iview); 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_ci radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); 680bf215546Sopenharmony_ci 681bf215546Sopenharmony_ci radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, 682bf215546Sopenharmony_ci &(VkViewport){.x = dest_offset->x, 683bf215546Sopenharmony_ci .y = dest_offset->y, 684bf215546Sopenharmony_ci .width = resolve_extent->width, 685bf215546Sopenharmony_ci .height = resolve_extent->height, 686bf215546Sopenharmony_ci .minDepth = 0.0f, 687bf215546Sopenharmony_ci .maxDepth = 1.0f}); 688bf215546Sopenharmony_ci 689bf215546Sopenharmony_ci radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, 690bf215546Sopenharmony_ci &(VkRect2D){ 691bf215546Sopenharmony_ci .offset = *dest_offset, 692bf215546Sopenharmony_ci .extent = *resolve_extent, 693bf215546Sopenharmony_ci }); 694bf215546Sopenharmony_ci 695bf215546Sopenharmony_ci radv_CmdDraw(cmd_buffer_h, 3, 1, 0, 0); 696bf215546Sopenharmony_ci cmd_buffer->state.flush_bits |= 697bf215546Sopenharmony_ci radv_src_access_flush(cmd_buffer, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, dest_iview->image); 698bf215546Sopenharmony_ci} 699bf215546Sopenharmony_ci 700bf215546Sopenharmony_cistatic void 701bf215546Sopenharmony_ciemit_depth_stencil_resolve(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview, 702bf215546Sopenharmony_ci struct radv_image_view *dst_iview, const VkExtent2D *resolve_extent, 703bf215546Sopenharmony_ci VkImageAspectFlags aspects, VkResolveModeFlagBits resolve_mode) 704bf215546Sopenharmony_ci{ 705bf215546Sopenharmony_ci struct radv_device *device = cmd_buffer->device; 706bf215546Sopenharmony_ci const uint32_t samples = src_iview->image->info.samples; 707bf215546Sopenharmony_ci const uint32_t samples_log2 = ffs(samples) - 1; 708bf215546Sopenharmony_ci VkPipeline *pipeline; 709bf215546Sopenharmony_ci 710bf215546Sopenharmony_ci radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, 711bf215546Sopenharmony_ci cmd_buffer->device->meta_state.resolve_fragment.p_layout, 712bf215546Sopenharmony_ci 0, /* set */ 713bf215546Sopenharmony_ci 1, /* descriptorWriteCount */ 714bf215546Sopenharmony_ci (VkWriteDescriptorSet[]){ 715bf215546Sopenharmony_ci {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 716bf215546Sopenharmony_ci .dstBinding = 0, 717bf215546Sopenharmony_ci .dstArrayElement = 0, 718bf215546Sopenharmony_ci .descriptorCount = 1, 719bf215546Sopenharmony_ci .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 720bf215546Sopenharmony_ci .pImageInfo = 721bf215546Sopenharmony_ci (VkDescriptorImageInfo[]){ 722bf215546Sopenharmony_ci { 723bf215546Sopenharmony_ci .sampler = VK_NULL_HANDLE, 724bf215546Sopenharmony_ci .imageView = radv_image_view_to_handle(src_iview), 725bf215546Sopenharmony_ci .imageLayout = VK_IMAGE_LAYOUT_GENERAL, 726bf215546Sopenharmony_ci }, 727bf215546Sopenharmony_ci }}, 728bf215546Sopenharmony_ci }); 729bf215546Sopenharmony_ci 730bf215546Sopenharmony_ci switch (resolve_mode) { 731bf215546Sopenharmony_ci case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT: 732bf215546Sopenharmony_ci if (aspects == VK_IMAGE_ASPECT_DEPTH_BIT) 733bf215546Sopenharmony_ci pipeline = &device->meta_state.resolve_fragment.depth_zero_pipeline; 734bf215546Sopenharmony_ci else 735bf215546Sopenharmony_ci pipeline = &device->meta_state.resolve_fragment.stencil_zero_pipeline; 736bf215546Sopenharmony_ci break; 737bf215546Sopenharmony_ci case VK_RESOLVE_MODE_AVERAGE_BIT: 738bf215546Sopenharmony_ci assert(aspects == VK_IMAGE_ASPECT_DEPTH_BIT); 739bf215546Sopenharmony_ci pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].average_pipeline; 740bf215546Sopenharmony_ci break; 741bf215546Sopenharmony_ci case VK_RESOLVE_MODE_MIN_BIT: 742bf215546Sopenharmony_ci if (aspects == VK_IMAGE_ASPECT_DEPTH_BIT) 743bf215546Sopenharmony_ci pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].min_pipeline; 744bf215546Sopenharmony_ci else 745bf215546Sopenharmony_ci pipeline = &device->meta_state.resolve_fragment.stencil[samples_log2].min_pipeline; 746bf215546Sopenharmony_ci break; 747bf215546Sopenharmony_ci case VK_RESOLVE_MODE_MAX_BIT: 748bf215546Sopenharmony_ci if (aspects == VK_IMAGE_ASPECT_DEPTH_BIT) 749bf215546Sopenharmony_ci pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].max_pipeline; 750bf215546Sopenharmony_ci else 751bf215546Sopenharmony_ci pipeline = &device->meta_state.resolve_fragment.stencil[samples_log2].max_pipeline; 752bf215546Sopenharmony_ci break; 753bf215546Sopenharmony_ci default: 754bf215546Sopenharmony_ci unreachable("invalid resolve mode"); 755bf215546Sopenharmony_ci } 756bf215546Sopenharmony_ci 757bf215546Sopenharmony_ci if (!*pipeline) { 758bf215546Sopenharmony_ci int index = aspects == VK_IMAGE_ASPECT_DEPTH_BIT ? DEPTH_RESOLVE : STENCIL_RESOLVE; 759bf215546Sopenharmony_ci VkResult ret; 760bf215546Sopenharmony_ci 761bf215546Sopenharmony_ci ret = create_depth_stencil_resolve_pipeline(device, samples_log2, index, resolve_mode); 762bf215546Sopenharmony_ci if (ret != VK_SUCCESS) { 763bf215546Sopenharmony_ci cmd_buffer->record_result = ret; 764bf215546Sopenharmony_ci return; 765bf215546Sopenharmony_ci } 766bf215546Sopenharmony_ci } 767bf215546Sopenharmony_ci 768bf215546Sopenharmony_ci radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS, 769bf215546Sopenharmony_ci *pipeline); 770bf215546Sopenharmony_ci 771bf215546Sopenharmony_ci radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, 772bf215546Sopenharmony_ci &(VkViewport){.x = 0, 773bf215546Sopenharmony_ci .y = 0, 774bf215546Sopenharmony_ci .width = resolve_extent->width, 775bf215546Sopenharmony_ci .height = resolve_extent->height, 776bf215546Sopenharmony_ci .minDepth = 0.0f, 777bf215546Sopenharmony_ci .maxDepth = 1.0f}); 778bf215546Sopenharmony_ci 779bf215546Sopenharmony_ci radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, 780bf215546Sopenharmony_ci &(VkRect2D){ 781bf215546Sopenharmony_ci .offset = (VkOffset2D){0, 0}, 782bf215546Sopenharmony_ci .extent = *resolve_extent, 783bf215546Sopenharmony_ci }); 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ci radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0); 786bf215546Sopenharmony_ci} 787bf215546Sopenharmony_ci 788bf215546Sopenharmony_civoid 789bf215546Sopenharmony_ciradv_meta_resolve_fragment_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image, 790bf215546Sopenharmony_ci VkImageLayout src_image_layout, struct radv_image *dest_image, 791bf215546Sopenharmony_ci VkImageLayout dest_image_layout, const VkImageResolve2 *region) 792bf215546Sopenharmony_ci{ 793bf215546Sopenharmony_ci struct radv_meta_saved_state saved_state; 794bf215546Sopenharmony_ci unsigned dst_layout = radv_meta_dst_layout_from_layout(dest_image_layout); 795bf215546Sopenharmony_ci VkImageLayout layout = radv_meta_dst_layout_to_layout(dst_layout); 796bf215546Sopenharmony_ci 797bf215546Sopenharmony_ci radv_decompress_resolve_src(cmd_buffer, src_image, src_image_layout, region); 798bf215546Sopenharmony_ci 799bf215546Sopenharmony_ci radv_meta_save( 800bf215546Sopenharmony_ci &saved_state, cmd_buffer, 801bf215546Sopenharmony_ci RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS); 802bf215546Sopenharmony_ci 803bf215546Sopenharmony_ci assert(region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT); 804bf215546Sopenharmony_ci assert(region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT); 805bf215546Sopenharmony_ci assert(region->srcSubresource.layerCount == region->dstSubresource.layerCount); 806bf215546Sopenharmony_ci 807bf215546Sopenharmony_ci const uint32_t src_base_layer = 808bf215546Sopenharmony_ci radv_meta_get_iview_layer(src_image, ®ion->srcSubresource, ®ion->srcOffset); 809bf215546Sopenharmony_ci 810bf215546Sopenharmony_ci const uint32_t dest_base_layer = 811bf215546Sopenharmony_ci radv_meta_get_iview_layer(dest_image, ®ion->dstSubresource, ®ion->dstOffset); 812bf215546Sopenharmony_ci 813bf215546Sopenharmony_ci const struct VkExtent3D extent = vk_image_sanitize_extent(&src_image->vk, region->extent); 814bf215546Sopenharmony_ci const struct VkOffset3D srcOffset = vk_image_sanitize_offset(&src_image->vk, region->srcOffset); 815bf215546Sopenharmony_ci const struct VkOffset3D dstOffset = vk_image_sanitize_offset(&dest_image->vk, region->dstOffset); 816bf215546Sopenharmony_ci 817bf215546Sopenharmony_ci for (uint32_t layer = 0; layer < region->srcSubresource.layerCount; ++layer) { 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_ci struct radv_image_view src_iview; 820bf215546Sopenharmony_ci radv_image_view_init(&src_iview, cmd_buffer->device, 821bf215546Sopenharmony_ci &(VkImageViewCreateInfo){ 822bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 823bf215546Sopenharmony_ci .image = radv_image_to_handle(src_image), 824bf215546Sopenharmony_ci .viewType = radv_meta_get_view_type(src_image), 825bf215546Sopenharmony_ci .format = src_image->vk.format, 826bf215546Sopenharmony_ci .subresourceRange = 827bf215546Sopenharmony_ci { 828bf215546Sopenharmony_ci .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 829bf215546Sopenharmony_ci .baseMipLevel = region->srcSubresource.mipLevel, 830bf215546Sopenharmony_ci .levelCount = 1, 831bf215546Sopenharmony_ci .baseArrayLayer = src_base_layer + layer, 832bf215546Sopenharmony_ci .layerCount = 1, 833bf215546Sopenharmony_ci }, 834bf215546Sopenharmony_ci }, 835bf215546Sopenharmony_ci 0, NULL); 836bf215546Sopenharmony_ci 837bf215546Sopenharmony_ci struct radv_image_view dest_iview; 838bf215546Sopenharmony_ci radv_image_view_init(&dest_iview, cmd_buffer->device, 839bf215546Sopenharmony_ci &(VkImageViewCreateInfo){ 840bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 841bf215546Sopenharmony_ci .image = radv_image_to_handle(dest_image), 842bf215546Sopenharmony_ci .viewType = radv_meta_get_view_type(dest_image), 843bf215546Sopenharmony_ci .format = dest_image->vk.format, 844bf215546Sopenharmony_ci .subresourceRange = 845bf215546Sopenharmony_ci { 846bf215546Sopenharmony_ci .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 847bf215546Sopenharmony_ci .baseMipLevel = region->dstSubresource.mipLevel, 848bf215546Sopenharmony_ci .levelCount = 1, 849bf215546Sopenharmony_ci .baseArrayLayer = dest_base_layer + layer, 850bf215546Sopenharmony_ci .layerCount = 1, 851bf215546Sopenharmony_ci }, 852bf215546Sopenharmony_ci }, 853bf215546Sopenharmony_ci 0, NULL); 854bf215546Sopenharmony_ci 855bf215546Sopenharmony_ci const VkRenderingAttachmentInfo color_att = { 856bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, 857bf215546Sopenharmony_ci .imageView = radv_image_view_to_handle(&dest_iview), 858bf215546Sopenharmony_ci .imageLayout = layout, 859bf215546Sopenharmony_ci .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 860bf215546Sopenharmony_ci .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 861bf215546Sopenharmony_ci }; 862bf215546Sopenharmony_ci 863bf215546Sopenharmony_ci const VkRenderingInfo rendering_info = { 864bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, 865bf215546Sopenharmony_ci .renderArea = { 866bf215546Sopenharmony_ci .offset = { dstOffset.x, dstOffset.y }, 867bf215546Sopenharmony_ci .extent = { extent.width, extent.height } 868bf215546Sopenharmony_ci }, 869bf215546Sopenharmony_ci .layerCount = 1, 870bf215546Sopenharmony_ci .colorAttachmentCount = 1, 871bf215546Sopenharmony_ci .pColorAttachments = &color_att, 872bf215546Sopenharmony_ci }; 873bf215546Sopenharmony_ci 874bf215546Sopenharmony_ci radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info); 875bf215546Sopenharmony_ci 876bf215546Sopenharmony_ci emit_resolve(cmd_buffer, &src_iview, &dest_iview, &(VkOffset2D){srcOffset.x, srcOffset.y}, 877bf215546Sopenharmony_ci &(VkOffset2D){dstOffset.x, dstOffset.y}, 878bf215546Sopenharmony_ci &(VkExtent2D){extent.width, extent.height}); 879bf215546Sopenharmony_ci 880bf215546Sopenharmony_ci radv_CmdEndRendering(radv_cmd_buffer_to_handle(cmd_buffer)); 881bf215546Sopenharmony_ci 882bf215546Sopenharmony_ci radv_image_view_finish(&src_iview); 883bf215546Sopenharmony_ci radv_image_view_finish(&dest_iview); 884bf215546Sopenharmony_ci } 885bf215546Sopenharmony_ci 886bf215546Sopenharmony_ci radv_meta_restore(&saved_state, cmd_buffer); 887bf215546Sopenharmony_ci} 888bf215546Sopenharmony_ci 889bf215546Sopenharmony_ci/** 890bf215546Sopenharmony_ci * Emit any needed resolves for the current subpass. 891bf215546Sopenharmony_ci */ 892bf215546Sopenharmony_civoid 893bf215546Sopenharmony_ciradv_cmd_buffer_resolve_subpass_fs(struct radv_cmd_buffer *cmd_buffer) 894bf215546Sopenharmony_ci{ 895bf215546Sopenharmony_ci struct vk_framebuffer *fb = cmd_buffer->state.framebuffer; 896bf215546Sopenharmony_ci const struct radv_subpass *subpass = cmd_buffer->state.subpass; 897bf215546Sopenharmony_ci struct radv_meta_saved_state saved_state; 898bf215546Sopenharmony_ci struct radv_subpass_barrier barrier; 899bf215546Sopenharmony_ci 900bf215546Sopenharmony_ci /* Resolves happen before the end-of-subpass barriers get executed, 901bf215546Sopenharmony_ci * so we have to make the attachment shader-readable */ 902bf215546Sopenharmony_ci barrier.src_stage_mask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; 903bf215546Sopenharmony_ci barrier.src_access_mask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; 904bf215546Sopenharmony_ci barrier.dst_access_mask = VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT; 905bf215546Sopenharmony_ci radv_emit_subpass_barrier(cmd_buffer, &barrier); 906bf215546Sopenharmony_ci 907bf215546Sopenharmony_ci radv_decompress_resolve_subpass_src(cmd_buffer); 908bf215546Sopenharmony_ci 909bf215546Sopenharmony_ci radv_meta_save( 910bf215546Sopenharmony_ci &saved_state, cmd_buffer, 911bf215546Sopenharmony_ci RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS); 912bf215546Sopenharmony_ci 913bf215546Sopenharmony_ci for (uint32_t i = 0; i < subpass->color_count; ++i) { 914bf215546Sopenharmony_ci struct radv_subpass_attachment src_att = subpass->color_attachments[i]; 915bf215546Sopenharmony_ci struct radv_subpass_attachment dest_att = subpass->resolve_attachments[i]; 916bf215546Sopenharmony_ci 917bf215546Sopenharmony_ci if (dest_att.attachment == VK_ATTACHMENT_UNUSED) 918bf215546Sopenharmony_ci continue; 919bf215546Sopenharmony_ci 920bf215546Sopenharmony_ci struct radv_image_view *dest_iview = cmd_buffer->state.attachments[dest_att.attachment].iview; 921bf215546Sopenharmony_ci struct radv_image_view *src_iview = cmd_buffer->state.attachments[src_att.attachment].iview; 922bf215546Sopenharmony_ci 923bf215546Sopenharmony_ci struct radv_subpass resolve_subpass = { 924bf215546Sopenharmony_ci .color_count = 1, 925bf215546Sopenharmony_ci .color_attachments = (struct radv_subpass_attachment[]){dest_att}, 926bf215546Sopenharmony_ci .depth_stencil_attachment = NULL, 927bf215546Sopenharmony_ci }; 928bf215546Sopenharmony_ci 929bf215546Sopenharmony_ci radv_cmd_buffer_set_subpass(cmd_buffer, &resolve_subpass); 930bf215546Sopenharmony_ci 931bf215546Sopenharmony_ci emit_resolve(cmd_buffer, src_iview, dest_iview, &(VkOffset2D){0, 0}, &(VkOffset2D){0, 0}, 932bf215546Sopenharmony_ci &(VkExtent2D){fb->width, fb->height}); 933bf215546Sopenharmony_ci 934bf215546Sopenharmony_ci radv_cmd_buffer_restore_subpass(cmd_buffer, subpass); 935bf215546Sopenharmony_ci } 936bf215546Sopenharmony_ci 937bf215546Sopenharmony_ci radv_meta_restore(&saved_state, cmd_buffer); 938bf215546Sopenharmony_ci} 939bf215546Sopenharmony_ci 940bf215546Sopenharmony_ci/** 941bf215546Sopenharmony_ci * Depth/stencil resolves for the current subpass. 942bf215546Sopenharmony_ci */ 943bf215546Sopenharmony_civoid 944bf215546Sopenharmony_ciradv_depth_stencil_resolve_subpass_fs(struct radv_cmd_buffer *cmd_buffer, 945bf215546Sopenharmony_ci VkImageAspectFlags aspects, 946bf215546Sopenharmony_ci VkResolveModeFlagBits resolve_mode) 947bf215546Sopenharmony_ci{ 948bf215546Sopenharmony_ci struct vk_framebuffer *fb = cmd_buffer->state.framebuffer; 949bf215546Sopenharmony_ci const struct radv_subpass *subpass = cmd_buffer->state.subpass; 950bf215546Sopenharmony_ci struct radv_meta_saved_state saved_state; 951bf215546Sopenharmony_ci struct radv_subpass_barrier barrier; 952bf215546Sopenharmony_ci 953bf215546Sopenharmony_ci /* Resolves happen before the end-of-subpass barriers get executed, 954bf215546Sopenharmony_ci * so we have to make the attachment shader-readable */ 955bf215546Sopenharmony_ci barrier.src_stage_mask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; 956bf215546Sopenharmony_ci barrier.src_access_mask = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 957bf215546Sopenharmony_ci barrier.dst_access_mask = VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT; 958bf215546Sopenharmony_ci radv_emit_subpass_barrier(cmd_buffer, &barrier); 959bf215546Sopenharmony_ci 960bf215546Sopenharmony_ci struct radv_subpass_attachment src_att = *subpass->depth_stencil_attachment; 961bf215546Sopenharmony_ci struct radv_image_view *src_iview = cmd_buffer->state.attachments[src_att.attachment].iview; 962bf215546Sopenharmony_ci struct radv_image *src_image = src_iview->image; 963bf215546Sopenharmony_ci 964bf215546Sopenharmony_ci VkImageResolve2 region = {0}; 965bf215546Sopenharmony_ci region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2; 966bf215546Sopenharmony_ci region.srcSubresource.aspectMask = aspects; 967bf215546Sopenharmony_ci region.srcSubresource.mipLevel = 0; 968bf215546Sopenharmony_ci region.srcSubresource.baseArrayLayer = 0; 969bf215546Sopenharmony_ci region.srcSubresource.layerCount = 1; 970bf215546Sopenharmony_ci 971bf215546Sopenharmony_ci radv_decompress_resolve_src(cmd_buffer, src_image, src_att.layout, ®ion); 972bf215546Sopenharmony_ci 973bf215546Sopenharmony_ci radv_meta_save(&saved_state, cmd_buffer, 974bf215546Sopenharmony_ci RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_DESCRIPTORS); 975bf215546Sopenharmony_ci 976bf215546Sopenharmony_ci struct radv_subpass_attachment dst_att = *subpass->ds_resolve_attachment; 977bf215546Sopenharmony_ci struct radv_image_view *dst_iview = cmd_buffer->state.attachments[dst_att.attachment].iview; 978bf215546Sopenharmony_ci 979bf215546Sopenharmony_ci struct radv_subpass resolve_subpass = { 980bf215546Sopenharmony_ci .color_count = 0, 981bf215546Sopenharmony_ci .color_attachments = NULL, 982bf215546Sopenharmony_ci .depth_stencil_attachment = (struct radv_subpass_attachment *){&dst_att}, 983bf215546Sopenharmony_ci }; 984bf215546Sopenharmony_ci 985bf215546Sopenharmony_ci radv_cmd_buffer_set_subpass(cmd_buffer, &resolve_subpass); 986bf215546Sopenharmony_ci 987bf215546Sopenharmony_ci struct radv_image_view tsrc_iview; 988bf215546Sopenharmony_ci radv_image_view_init(&tsrc_iview, cmd_buffer->device, 989bf215546Sopenharmony_ci &(VkImageViewCreateInfo){ 990bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 991bf215546Sopenharmony_ci .image = radv_image_to_handle(src_image), 992bf215546Sopenharmony_ci .viewType = radv_meta_get_view_type(src_image), 993bf215546Sopenharmony_ci .format = src_iview->vk.format, 994bf215546Sopenharmony_ci .subresourceRange = 995bf215546Sopenharmony_ci { 996bf215546Sopenharmony_ci .aspectMask = aspects, 997bf215546Sopenharmony_ci .baseMipLevel = 0, 998bf215546Sopenharmony_ci .levelCount = 1, 999bf215546Sopenharmony_ci .baseArrayLayer = 0, 1000bf215546Sopenharmony_ci .layerCount = 1, 1001bf215546Sopenharmony_ci }, 1002bf215546Sopenharmony_ci }, 1003bf215546Sopenharmony_ci 0, NULL); 1004bf215546Sopenharmony_ci 1005bf215546Sopenharmony_ci emit_depth_stencil_resolve(cmd_buffer, &tsrc_iview, dst_iview, 1006bf215546Sopenharmony_ci &(VkExtent2D){fb->width, fb->height}, aspects, resolve_mode); 1007bf215546Sopenharmony_ci 1008bf215546Sopenharmony_ci radv_cmd_buffer_restore_subpass(cmd_buffer, subpass); 1009bf215546Sopenharmony_ci 1010bf215546Sopenharmony_ci radv_image_view_finish(&tsrc_iview); 1011bf215546Sopenharmony_ci 1012bf215546Sopenharmony_ci radv_meta_restore(&saved_state, cmd_buffer); 1013bf215546Sopenharmony_ci} 1014