Path: blob/21.2-virgl/src/amd/vulkan/radv_meta_resolve_fs.c
7237 views
/*1* Copyright © 2016 Dave Airlie2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include <assert.h>24#include <stdbool.h>2526#include "nir/nir_builder.h"27#include "radv_meta.h"28#include "radv_private.h"29#include "sid.h"30#include "vk_format.h"3132static nir_shader *33build_nir_vertex_shader(void)34{35const struct glsl_type *vec4 = glsl_vec4_type();36nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_VERTEX, NULL, "meta_resolve_vs");3738nir_variable *pos_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "gl_Position");39pos_out->data.location = VARYING_SLOT_POS;4041nir_ssa_def *outvec = radv_meta_gen_rect_vertices(&b);4243nir_store_var(&b, pos_out, outvec, 0xf);44return b.shader;45}4647static nir_shader *48build_resolve_fragment_shader(struct radv_device *dev, bool is_integer, int samples)49{50const struct glsl_type *vec4 = glsl_vec4_type();51const struct glsl_type *sampler_type =52glsl_sampler_type(GLSL_SAMPLER_DIM_MS, false, false, GLSL_TYPE_FLOAT);5354nir_builder b = nir_builder_init_simple_shader(55MESA_SHADER_FRAGMENT, NULL, "meta_resolve_fs-%d-%s", samples, is_integer ? "int" : "float");5657nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex");58input_img->data.descriptor_set = 0;59input_img->data.binding = 0;6061nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");62color_out->data.location = FRAG_RESULT_DATA0;6364nir_ssa_def *pos_in = nir_channels(&b, nir_load_frag_coord(&b), 0x3);65nir_ssa_def *src_offset = nir_load_push_constant(&b, 2, 32, nir_imm_int(&b, 0), 0, 8);6667nir_ssa_def *pos_int = nir_f2i32(&b, pos_in);6869nir_ssa_def *img_coord = nir_channels(&b, nir_iadd(&b, pos_int, src_offset), 0x3);70nir_variable *color = nir_local_variable_create(b.impl, glsl_vec4_type(), "color");7172radv_meta_build_resolve_shader_core(&b, is_integer, samples, input_img, color, img_coord);7374nir_ssa_def *outval = nir_load_var(&b, color);75nir_store_var(&b, color_out, outval, 0xf);76return b.shader;77}7879static VkResult80create_layout(struct radv_device *device)81{82VkResult result;83/*84* one descriptors for the image being sampled85*/86VkDescriptorSetLayoutCreateInfo ds_create_info = {87.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,88.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,89.bindingCount = 1,90.pBindings = (VkDescriptorSetLayoutBinding[]){91{.binding = 0,92.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,93.descriptorCount = 1,94.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,95.pImmutableSamplers = NULL},96}};9798result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &ds_create_info,99&device->meta_state.alloc,100&device->meta_state.resolve_fragment.ds_layout);101if (result != VK_SUCCESS)102goto fail;103104VkPipelineLayoutCreateInfo pl_create_info = {105.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,106.setLayoutCount = 1,107.pSetLayouts = &device->meta_state.resolve_fragment.ds_layout,108.pushConstantRangeCount = 1,109.pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_FRAGMENT_BIT, 0, 8},110};111112result = radv_CreatePipelineLayout(radv_device_to_handle(device), &pl_create_info,113&device->meta_state.alloc,114&device->meta_state.resolve_fragment.p_layout);115if (result != VK_SUCCESS)116goto fail;117return VK_SUCCESS;118fail:119return result;120}121122static const VkPipelineVertexInputStateCreateInfo normal_vi_create_info = {123.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,124.vertexBindingDescriptionCount = 0,125.vertexAttributeDescriptionCount = 0,126};127128static VkResult129create_resolve_pipeline(struct radv_device *device, int samples_log2, VkFormat format)130{131mtx_lock(&device->meta_state.mtx);132133unsigned fs_key = radv_format_meta_fs_key(device, format);134VkPipeline *pipeline = &device->meta_state.resolve_fragment.rc[samples_log2].pipeline[fs_key];135if (*pipeline) {136mtx_unlock(&device->meta_state.mtx);137return VK_SUCCESS;138}139140VkResult result;141bool is_integer = false;142uint32_t samples = 1 << samples_log2;143const VkPipelineVertexInputStateCreateInfo *vi_create_info;144vi_create_info = &normal_vi_create_info;145if (vk_format_is_int(format))146is_integer = true;147148nir_shader *fs = build_resolve_fragment_shader(device, is_integer, samples);149nir_shader *vs = build_nir_vertex_shader();150151VkRenderPass *rp = &device->meta_state.resolve_fragment.rc[samples_log2].render_pass[fs_key][0];152153assert(!*rp);154155VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {156{.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,157.stage = VK_SHADER_STAGE_VERTEX_BIT,158.module = vk_shader_module_handle_from_nir(vs),159.pName = "main",160.pSpecializationInfo = NULL},161{.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,162.stage = VK_SHADER_STAGE_FRAGMENT_BIT,163.module = vk_shader_module_handle_from_nir(fs),164.pName = "main",165.pSpecializationInfo = NULL},166};167168for (unsigned dst_layout = 0; dst_layout < RADV_META_DST_LAYOUT_COUNT; ++dst_layout) {169VkImageLayout layout = radv_meta_dst_layout_to_layout(dst_layout);170result = radv_CreateRenderPass2(171radv_device_to_handle(device),172&(VkRenderPassCreateInfo2){173.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,174.attachmentCount = 1,175.pAttachments =176&(VkAttachmentDescription2){177.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,178.format = format,179.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,180.storeOp = VK_ATTACHMENT_STORE_OP_STORE,181.initialLayout = layout,182.finalLayout = layout,183},184.subpassCount = 1,185.pSubpasses =186&(VkSubpassDescription2){187.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,188.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,189.inputAttachmentCount = 0,190.colorAttachmentCount = 1,191.pColorAttachments =192&(VkAttachmentReference2){193.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,194.attachment = 0,195.layout = layout,196},197.pResolveAttachments = NULL,198.pDepthStencilAttachment =199&(VkAttachmentReference2){200.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,201.attachment = VK_ATTACHMENT_UNUSED,202.layout = VK_IMAGE_LAYOUT_GENERAL,203},204.preserveAttachmentCount = 0,205.pPreserveAttachments = NULL,206},207.dependencyCount = 2,208.pDependencies =209(VkSubpassDependency2[]){{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,210.srcSubpass = VK_SUBPASS_EXTERNAL,211.dstSubpass = 0,212.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,213.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,214.srcAccessMask = 0,215.dstAccessMask = 0,216.dependencyFlags = 0},217{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,218.srcSubpass = 0,219.dstSubpass = VK_SUBPASS_EXTERNAL,220.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,221.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,222.srcAccessMask = 0,223.dstAccessMask = 0,224.dependencyFlags = 0}},225},226&device->meta_state.alloc, rp + dst_layout);227}228229const VkGraphicsPipelineCreateInfo vk_pipeline_info = {230.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,231.stageCount = ARRAY_SIZE(pipeline_shader_stages),232.pStages = pipeline_shader_stages,233.pVertexInputState = vi_create_info,234.pInputAssemblyState =235&(VkPipelineInputAssemblyStateCreateInfo){236.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,237.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,238.primitiveRestartEnable = false,239},240.pViewportState =241&(VkPipelineViewportStateCreateInfo){242.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,243.viewportCount = 1,244.scissorCount = 1,245},246.pRasterizationState =247&(VkPipelineRasterizationStateCreateInfo){248.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,249.rasterizerDiscardEnable = false,250.polygonMode = VK_POLYGON_MODE_FILL,251.cullMode = VK_CULL_MODE_NONE,252.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE},253.pMultisampleState =254&(VkPipelineMultisampleStateCreateInfo){255.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,256.rasterizationSamples = 1,257.sampleShadingEnable = false,258.pSampleMask = (VkSampleMask[]){UINT32_MAX},259},260.pColorBlendState =261&(VkPipelineColorBlendStateCreateInfo){262.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,263.attachmentCount = 1,264.pAttachments =265(VkPipelineColorBlendAttachmentState[]){266{.colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_R_BIT |267VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT},268}},269.pDynamicState =270&(VkPipelineDynamicStateCreateInfo){271.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,272.dynamicStateCount = 9,273.pDynamicStates =274(VkDynamicState[]){275VK_DYNAMIC_STATE_VIEWPORT,276VK_DYNAMIC_STATE_SCISSOR,277VK_DYNAMIC_STATE_LINE_WIDTH,278VK_DYNAMIC_STATE_DEPTH_BIAS,279VK_DYNAMIC_STATE_BLEND_CONSTANTS,280VK_DYNAMIC_STATE_DEPTH_BOUNDS,281VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,282VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,283VK_DYNAMIC_STATE_STENCIL_REFERENCE,284},285},286.flags = 0,287.layout = device->meta_state.resolve_fragment.p_layout,288.renderPass = *rp,289.subpass = 0,290};291292const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};293294result = radv_graphics_pipeline_create(295radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache),296&vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc, pipeline);297ralloc_free(vs);298ralloc_free(fs);299300mtx_unlock(&device->meta_state.mtx);301return result;302}303304enum { DEPTH_RESOLVE, STENCIL_RESOLVE };305306static const char *307get_resolve_mode_str(VkResolveModeFlagBits resolve_mode)308{309switch (resolve_mode) {310case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR:311return "zero";312case VK_RESOLVE_MODE_AVERAGE_BIT_KHR:313return "average";314case VK_RESOLVE_MODE_MIN_BIT_KHR:315return "min";316case VK_RESOLVE_MODE_MAX_BIT_KHR:317return "max";318default:319unreachable("invalid resolve mode");320}321}322323static nir_shader *324build_depth_stencil_resolve_fragment_shader(struct radv_device *dev, int samples, int index,325VkResolveModeFlagBits resolve_mode)326{327const struct glsl_type *vec4 = glsl_vec4_type();328const struct glsl_type *sampler_type =329glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false, GLSL_TYPE_FLOAT);330331nir_builder b = nir_builder_init_simple_shader(332MESA_SHADER_FRAGMENT, NULL, "meta_resolve_fs_%s-%s-%d",333index == DEPTH_RESOLVE ? "depth" : "stencil", get_resolve_mode_str(resolve_mode), samples);334335nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex");336input_img->data.descriptor_set = 0;337input_img->data.binding = 0;338339nir_variable *fs_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_out");340fs_out->data.location = index == DEPTH_RESOLVE ? FRAG_RESULT_DEPTH : FRAG_RESULT_STENCIL;341342nir_ssa_def *pos_in = nir_channels(&b, nir_load_frag_coord(&b), 0x3);343344nir_ssa_def *pos_int = nir_f2i32(&b, pos_in);345346nir_ssa_def *img_coord = nir_channels(&b, pos_int, 0x3);347348nir_ssa_def *input_img_deref = &nir_build_deref_var(&b, input_img)->dest.ssa;349350nir_alu_type type = index == DEPTH_RESOLVE ? nir_type_float32 : nir_type_uint32;351352nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3);353tex->sampler_dim = GLSL_SAMPLER_DIM_MS;354tex->op = nir_texop_txf_ms;355tex->src[0].src_type = nir_tex_src_coord;356tex->src[0].src = nir_src_for_ssa(img_coord);357tex->src[1].src_type = nir_tex_src_ms_index;358tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0));359tex->src[2].src_type = nir_tex_src_texture_deref;360tex->src[2].src = nir_src_for_ssa(input_img_deref);361tex->dest_type = type;362tex->is_array = false;363tex->coord_components = 2;364365nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");366nir_builder_instr_insert(&b, &tex->instr);367368nir_ssa_def *outval = &tex->dest.ssa;369370if (resolve_mode != VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR) {371for (int i = 1; i < samples; i++) {372nir_tex_instr *tex_add = nir_tex_instr_create(b.shader, 3);373tex_add->sampler_dim = GLSL_SAMPLER_DIM_MS;374tex_add->op = nir_texop_txf_ms;375tex_add->src[0].src_type = nir_tex_src_coord;376tex_add->src[0].src = nir_src_for_ssa(img_coord);377tex_add->src[1].src_type = nir_tex_src_ms_index;378tex_add->src[1].src = nir_src_for_ssa(nir_imm_int(&b, i));379tex_add->src[2].src_type = nir_tex_src_texture_deref;380tex_add->src[2].src = nir_src_for_ssa(input_img_deref);381tex_add->dest_type = type;382tex_add->is_array = false;383tex_add->coord_components = 2;384385nir_ssa_dest_init(&tex_add->instr, &tex_add->dest, 4, 32, "tex");386nir_builder_instr_insert(&b, &tex_add->instr);387388switch (resolve_mode) {389case VK_RESOLVE_MODE_AVERAGE_BIT_KHR:390assert(index == DEPTH_RESOLVE);391outval = nir_fadd(&b, outval, &tex_add->dest.ssa);392break;393case VK_RESOLVE_MODE_MIN_BIT_KHR:394if (index == DEPTH_RESOLVE)395outval = nir_fmin(&b, outval, &tex_add->dest.ssa);396else397outval = nir_umin(&b, outval, &tex_add->dest.ssa);398break;399case VK_RESOLVE_MODE_MAX_BIT_KHR:400if (index == DEPTH_RESOLVE)401outval = nir_fmax(&b, outval, &tex_add->dest.ssa);402else403outval = nir_umax(&b, outval, &tex_add->dest.ssa);404break;405default:406unreachable("invalid resolve mode");407}408}409410if (resolve_mode == VK_RESOLVE_MODE_AVERAGE_BIT_KHR)411outval = nir_fdiv(&b, outval, nir_imm_float(&b, samples));412}413414nir_store_var(&b, fs_out, outval, 0x1);415416return b.shader;417}418419static VkResult420create_depth_stencil_resolve_pipeline(struct radv_device *device, int samples_log2, int index,421VkResolveModeFlagBits resolve_mode)422{423VkRenderPass *render_pass;424VkPipeline *pipeline;425VkFormat src_format;426VkResult result;427428mtx_lock(&device->meta_state.mtx);429430switch (resolve_mode) {431case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR:432if (index == DEPTH_RESOLVE)433pipeline = &device->meta_state.resolve_fragment.depth_zero_pipeline;434else435pipeline = &device->meta_state.resolve_fragment.stencil_zero_pipeline;436break;437case VK_RESOLVE_MODE_AVERAGE_BIT_KHR:438assert(index == DEPTH_RESOLVE);439pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].average_pipeline;440break;441case VK_RESOLVE_MODE_MIN_BIT_KHR:442if (index == DEPTH_RESOLVE)443pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].min_pipeline;444else445pipeline = &device->meta_state.resolve_fragment.stencil[samples_log2].min_pipeline;446break;447case VK_RESOLVE_MODE_MAX_BIT_KHR:448if (index == DEPTH_RESOLVE)449pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].max_pipeline;450else451pipeline = &device->meta_state.resolve_fragment.stencil[samples_log2].max_pipeline;452break;453default:454unreachable("invalid resolve mode");455}456457if (*pipeline) {458mtx_unlock(&device->meta_state.mtx);459return VK_SUCCESS;460}461462uint32_t samples = 1 << samples_log2;463nir_shader *fs =464build_depth_stencil_resolve_fragment_shader(device, samples, index, resolve_mode);465nir_shader *vs = build_nir_vertex_shader();466467VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {468{.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,469.stage = VK_SHADER_STAGE_VERTEX_BIT,470.module = vk_shader_module_handle_from_nir(vs),471.pName = "main",472.pSpecializationInfo = NULL},473{.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,474.stage = VK_SHADER_STAGE_FRAGMENT_BIT,475.module = vk_shader_module_handle_from_nir(fs),476.pName = "main",477.pSpecializationInfo = NULL},478};479480if (index == DEPTH_RESOLVE) {481src_format = VK_FORMAT_D32_SFLOAT;482render_pass = &device->meta_state.resolve_fragment.depth_render_pass;483} else {484render_pass = &device->meta_state.resolve_fragment.stencil_render_pass;485src_format = VK_FORMAT_S8_UINT;486}487488if (!*render_pass) {489result = radv_CreateRenderPass2(490radv_device_to_handle(device),491&(VkRenderPassCreateInfo2){492.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,493.attachmentCount = 1,494.pAttachments =495&(VkAttachmentDescription2){496.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,497.format = src_format,498.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,499.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,500.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD,501.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,502.initialLayout = VK_IMAGE_LAYOUT_GENERAL,503.finalLayout = VK_IMAGE_LAYOUT_GENERAL,504},505.subpassCount = 1,506.pSubpasses =507&(VkSubpassDescription2){508.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,509.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,510.inputAttachmentCount = 0,511.colorAttachmentCount = 0,512.pColorAttachments = NULL,513.pResolveAttachments = NULL,514.pDepthStencilAttachment =515&(VkAttachmentReference2){516.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,517.attachment = 0,518.layout = VK_IMAGE_LAYOUT_GENERAL,519},520.preserveAttachmentCount = 0,521.pPreserveAttachments = NULL,522},523.dependencyCount = 2,524.pDependencies =525(VkSubpassDependency2[]){{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,526.srcSubpass = VK_SUBPASS_EXTERNAL,527.dstSubpass = 0,528.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,529.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,530.srcAccessMask = 0,531.dstAccessMask = 0,532.dependencyFlags = 0},533{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,534.srcSubpass = 0,535.dstSubpass = VK_SUBPASS_EXTERNAL,536.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,537.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,538.srcAccessMask = 0,539.dstAccessMask = 0,540.dependencyFlags = 0}},541},542&device->meta_state.alloc, render_pass);543}544545VkStencilOp stencil_op = index == DEPTH_RESOLVE ? VK_STENCIL_OP_KEEP : VK_STENCIL_OP_REPLACE;546547VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {548.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,549.depthTestEnable = true,550.depthWriteEnable = index == DEPTH_RESOLVE,551.stencilTestEnable = index == STENCIL_RESOLVE,552.depthCompareOp = VK_COMPARE_OP_ALWAYS,553.front =554{555.failOp = stencil_op,556.passOp = stencil_op,557.depthFailOp = stencil_op,558.compareOp = VK_COMPARE_OP_ALWAYS,559},560.back = {561.failOp = stencil_op,562.passOp = stencil_op,563.depthFailOp = stencil_op,564.compareOp = VK_COMPARE_OP_ALWAYS,565}};566567const VkPipelineVertexInputStateCreateInfo *vi_create_info;568vi_create_info = &normal_vi_create_info;569570const VkGraphicsPipelineCreateInfo vk_pipeline_info = {571.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,572.stageCount = ARRAY_SIZE(pipeline_shader_stages),573.pStages = pipeline_shader_stages,574.pVertexInputState = vi_create_info,575.pInputAssemblyState =576&(VkPipelineInputAssemblyStateCreateInfo){577.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,578.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,579.primitiveRestartEnable = false,580},581.pViewportState =582&(VkPipelineViewportStateCreateInfo){583.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,584.viewportCount = 1,585.scissorCount = 1,586},587.pDepthStencilState = &depth_stencil_state,588.pRasterizationState =589&(VkPipelineRasterizationStateCreateInfo){590.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,591.rasterizerDiscardEnable = false,592.polygonMode = VK_POLYGON_MODE_FILL,593.cullMode = VK_CULL_MODE_NONE,594.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE},595.pMultisampleState =596&(VkPipelineMultisampleStateCreateInfo){597.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,598.rasterizationSamples = 1,599.sampleShadingEnable = false,600.pSampleMask = (VkSampleMask[]){UINT32_MAX},601},602.pColorBlendState =603&(VkPipelineColorBlendStateCreateInfo){604.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,605.attachmentCount = 0,606.pAttachments =607(VkPipelineColorBlendAttachmentState[]){608{.colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_R_BIT |609VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT},610}},611.pDynamicState =612&(VkPipelineDynamicStateCreateInfo){613.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,614.dynamicStateCount = 9,615.pDynamicStates =616(VkDynamicState[]){617VK_DYNAMIC_STATE_VIEWPORT,618VK_DYNAMIC_STATE_SCISSOR,619VK_DYNAMIC_STATE_LINE_WIDTH,620VK_DYNAMIC_STATE_DEPTH_BIAS,621VK_DYNAMIC_STATE_BLEND_CONSTANTS,622VK_DYNAMIC_STATE_DEPTH_BOUNDS,623VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,624VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,625VK_DYNAMIC_STATE_STENCIL_REFERENCE,626},627},628.flags = 0,629.layout = device->meta_state.resolve_fragment.p_layout,630.renderPass = *render_pass,631.subpass = 0,632};633634const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};635636result = radv_graphics_pipeline_create(637radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache),638&vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc, pipeline);639640ralloc_free(vs);641ralloc_free(fs);642643mtx_unlock(&device->meta_state.mtx);644return result;645}646647VkResult648radv_device_init_meta_resolve_fragment_state(struct radv_device *device, bool on_demand)649{650VkResult res;651652res = create_layout(device);653if (res != VK_SUCCESS)654goto fail;655656if (on_demand)657return VK_SUCCESS;658659for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; ++i) {660for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {661res = create_resolve_pipeline(device, i, radv_fs_key_format_exemplars[j]);662if (res != VK_SUCCESS)663goto fail;664}665666res = create_depth_stencil_resolve_pipeline(device, i, DEPTH_RESOLVE,667VK_RESOLVE_MODE_AVERAGE_BIT_KHR);668if (res != VK_SUCCESS)669goto fail;670671res = create_depth_stencil_resolve_pipeline(device, i, DEPTH_RESOLVE,672VK_RESOLVE_MODE_MIN_BIT_KHR);673if (res != VK_SUCCESS)674goto fail;675676res = create_depth_stencil_resolve_pipeline(device, i, DEPTH_RESOLVE,677VK_RESOLVE_MODE_MAX_BIT_KHR);678if (res != VK_SUCCESS)679goto fail;680681res = create_depth_stencil_resolve_pipeline(device, i, STENCIL_RESOLVE,682VK_RESOLVE_MODE_MIN_BIT_KHR);683if (res != VK_SUCCESS)684goto fail;685686res = create_depth_stencil_resolve_pipeline(device, i, STENCIL_RESOLVE,687VK_RESOLVE_MODE_MAX_BIT_KHR);688if (res != VK_SUCCESS)689goto fail;690}691692res = create_depth_stencil_resolve_pipeline(device, 0, DEPTH_RESOLVE,693VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR);694if (res != VK_SUCCESS)695goto fail;696697res = create_depth_stencil_resolve_pipeline(device, 0, STENCIL_RESOLVE,698VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR);699if (res != VK_SUCCESS)700goto fail;701702return VK_SUCCESS;703fail:704radv_device_finish_meta_resolve_fragment_state(device);705return res;706}707708void709radv_device_finish_meta_resolve_fragment_state(struct radv_device *device)710{711struct radv_meta_state *state = &device->meta_state;712for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; ++i) {713for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {714for (unsigned k = 0; k < RADV_META_DST_LAYOUT_COUNT; ++k) {715radv_DestroyRenderPass(radv_device_to_handle(device),716state->resolve_fragment.rc[i].render_pass[j][k], &state->alloc);717}718radv_DestroyPipeline(radv_device_to_handle(device),719state->resolve_fragment.rc[i].pipeline[j], &state->alloc);720}721722radv_DestroyPipeline(radv_device_to_handle(device),723state->resolve_fragment.depth[i].average_pipeline, &state->alloc);724725radv_DestroyPipeline(radv_device_to_handle(device),726state->resolve_fragment.depth[i].max_pipeline, &state->alloc);727728radv_DestroyPipeline(radv_device_to_handle(device),729state->resolve_fragment.depth[i].min_pipeline, &state->alloc);730731radv_DestroyPipeline(radv_device_to_handle(device),732state->resolve_fragment.stencil[i].max_pipeline, &state->alloc);733734radv_DestroyPipeline(radv_device_to_handle(device),735state->resolve_fragment.stencil[i].min_pipeline, &state->alloc);736}737738radv_DestroyRenderPass(radv_device_to_handle(device), state->resolve_fragment.depth_render_pass,739&state->alloc);740radv_DestroyRenderPass(radv_device_to_handle(device),741state->resolve_fragment.stencil_render_pass, &state->alloc);742743radv_DestroyPipeline(radv_device_to_handle(device), state->resolve_fragment.depth_zero_pipeline,744&state->alloc);745radv_DestroyPipeline(radv_device_to_handle(device),746state->resolve_fragment.stencil_zero_pipeline, &state->alloc);747748radv_DestroyDescriptorSetLayout(radv_device_to_handle(device), state->resolve_fragment.ds_layout,749&state->alloc);750radv_DestroyPipelineLayout(radv_device_to_handle(device), state->resolve_fragment.p_layout,751&state->alloc);752}753754static VkPipeline *755radv_get_resolve_pipeline(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview,756struct radv_image_view *dst_iview)757{758struct radv_device *device = cmd_buffer->device;759unsigned fs_key = radv_format_meta_fs_key(cmd_buffer->device, dst_iview->vk_format);760const uint32_t samples = src_iview->image->info.samples;761const uint32_t samples_log2 = ffs(samples) - 1;762VkPipeline *pipeline;763764pipeline = &device->meta_state.resolve_fragment.rc[samples_log2].pipeline[fs_key];765if (!*pipeline) {766VkResult ret;767768ret = create_resolve_pipeline(device, samples_log2, radv_fs_key_format_exemplars[fs_key]);769if (ret != VK_SUCCESS) {770cmd_buffer->record_result = ret;771return NULL;772}773}774775return pipeline;776}777778static void779emit_resolve(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview,780struct radv_image_view *dest_iview, const VkOffset2D *src_offset,781const VkOffset2D *dest_offset, const VkExtent2D *resolve_extent)782{783struct radv_device *device = cmd_buffer->device;784VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);785VkPipeline *pipeline;786787radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,788cmd_buffer->device->meta_state.resolve_fragment.p_layout,7890, /* set */7901, /* descriptorWriteCount */791(VkWriteDescriptorSet[]){792{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,793.dstBinding = 0,794.dstArrayElement = 0,795.descriptorCount = 1,796.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,797.pImageInfo =798(VkDescriptorImageInfo[]){799{800.sampler = VK_NULL_HANDLE,801.imageView = radv_image_view_to_handle(src_iview),802.imageLayout = VK_IMAGE_LAYOUT_GENERAL,803},804}},805});806807cmd_buffer->state.flush_bits |=808radv_dst_access_flush(cmd_buffer, VK_ACCESS_SHADER_READ_BIT, src_iview->image) |809radv_dst_access_flush(cmd_buffer, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, dest_iview->image);810811unsigned push_constants[2] = {812src_offset->x - dest_offset->x,813src_offset->y - dest_offset->y,814};815radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),816device->meta_state.resolve_fragment.p_layout, VK_SHADER_STAGE_FRAGMENT_BIT,8170, 8, push_constants);818819pipeline = radv_get_resolve_pipeline(cmd_buffer, src_iview, dest_iview);820821radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);822823radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,824&(VkViewport){.x = dest_offset->x,825.y = dest_offset->y,826.width = resolve_extent->width,827.height = resolve_extent->height,828.minDepth = 0.0f,829.maxDepth = 1.0f});830831radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,832&(VkRect2D){833.offset = *dest_offset,834.extent = *resolve_extent,835});836837radv_CmdDraw(cmd_buffer_h, 3, 1, 0, 0);838cmd_buffer->state.flush_bits |=839radv_src_access_flush(cmd_buffer, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, dest_iview->image);840}841842static void843emit_depth_stencil_resolve(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview,844struct radv_image_view *dst_iview, const VkExtent2D *resolve_extent,845VkImageAspectFlags aspects, VkResolveModeFlagBits resolve_mode)846{847struct radv_device *device = cmd_buffer->device;848const uint32_t samples = src_iview->image->info.samples;849const uint32_t samples_log2 = ffs(samples) - 1;850VkPipeline *pipeline;851852radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,853cmd_buffer->device->meta_state.resolve_fragment.p_layout,8540, /* set */8551, /* descriptorWriteCount */856(VkWriteDescriptorSet[]){857{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,858.dstBinding = 0,859.dstArrayElement = 0,860.descriptorCount = 1,861.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,862.pImageInfo =863(VkDescriptorImageInfo[]){864{865.sampler = VK_NULL_HANDLE,866.imageView = radv_image_view_to_handle(src_iview),867.imageLayout = VK_IMAGE_LAYOUT_GENERAL,868},869}},870});871872switch (resolve_mode) {873case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR:874if (aspects == VK_IMAGE_ASPECT_DEPTH_BIT)875pipeline = &device->meta_state.resolve_fragment.depth_zero_pipeline;876else877pipeline = &device->meta_state.resolve_fragment.stencil_zero_pipeline;878break;879case VK_RESOLVE_MODE_AVERAGE_BIT_KHR:880assert(aspects == VK_IMAGE_ASPECT_DEPTH_BIT);881pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].average_pipeline;882break;883case VK_RESOLVE_MODE_MIN_BIT_KHR:884if (aspects == VK_IMAGE_ASPECT_DEPTH_BIT)885pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].min_pipeline;886else887pipeline = &device->meta_state.resolve_fragment.stencil[samples_log2].min_pipeline;888break;889case VK_RESOLVE_MODE_MAX_BIT_KHR:890if (aspects == VK_IMAGE_ASPECT_DEPTH_BIT)891pipeline = &device->meta_state.resolve_fragment.depth[samples_log2].max_pipeline;892else893pipeline = &device->meta_state.resolve_fragment.stencil[samples_log2].max_pipeline;894break;895default:896unreachable("invalid resolve mode");897}898899if (!*pipeline) {900int index = aspects == VK_IMAGE_ASPECT_DEPTH_BIT ? DEPTH_RESOLVE : STENCIL_RESOLVE;901VkResult ret;902903ret = create_depth_stencil_resolve_pipeline(device, samples_log2, index, resolve_mode);904if (ret != VK_SUCCESS) {905cmd_buffer->record_result = ret;906return;907}908}909910radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,911*pipeline);912913radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,914&(VkViewport){.x = 0,915.y = 0,916.width = resolve_extent->width,917.height = resolve_extent->height,918.minDepth = 0.0f,919.maxDepth = 1.0f});920921radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,922&(VkRect2D){923.offset = (VkOffset2D){0, 0},924.extent = *resolve_extent,925});926927radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);928}929930void931radv_meta_resolve_fragment_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image,932VkImageLayout src_image_layout, struct radv_image *dest_image,933VkImageLayout dest_image_layout, const VkImageResolve2KHR *region)934{935struct radv_device *device = cmd_buffer->device;936struct radv_meta_saved_state saved_state;937const uint32_t samples = src_image->info.samples;938const uint32_t samples_log2 = ffs(samples) - 1;939unsigned fs_key = radv_format_meta_fs_key(cmd_buffer->device, dest_image->vk_format);940unsigned dst_layout = radv_meta_dst_layout_from_layout(dest_image_layout);941VkRenderPass rp;942943radv_decompress_resolve_src(cmd_buffer, src_image, src_image_layout, region);944945if (!device->meta_state.resolve_fragment.rc[samples_log2].render_pass[fs_key][dst_layout]) {946VkResult ret =947create_resolve_pipeline(device, samples_log2, radv_fs_key_format_exemplars[fs_key]);948if (ret != VK_SUCCESS) {949cmd_buffer->record_result = ret;950return;951}952}953954rp = device->meta_state.resolve_fragment.rc[samples_log2].render_pass[fs_key][dst_layout];955956radv_meta_save(957&saved_state, cmd_buffer,958RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS);959960assert(region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);961assert(region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);962assert(region->srcSubresource.layerCount == region->dstSubresource.layerCount);963964const uint32_t src_base_layer =965radv_meta_get_iview_layer(src_image, ®ion->srcSubresource, ®ion->srcOffset);966967const uint32_t dest_base_layer =968radv_meta_get_iview_layer(dest_image, ®ion->dstSubresource, ®ion->dstOffset);969970const struct VkExtent3D extent = radv_sanitize_image_extent(src_image->type, region->extent);971const struct VkOffset3D srcOffset =972radv_sanitize_image_offset(src_image->type, region->srcOffset);973const struct VkOffset3D dstOffset =974radv_sanitize_image_offset(dest_image->type, region->dstOffset);975976for (uint32_t layer = 0; layer < region->srcSubresource.layerCount; ++layer) {977978struct radv_image_view src_iview;979radv_image_view_init(&src_iview, cmd_buffer->device,980&(VkImageViewCreateInfo){981.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,982.image = radv_image_to_handle(src_image),983.viewType = radv_meta_get_view_type(src_image),984.format = src_image->vk_format,985.subresourceRange =986{987.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,988.baseMipLevel = region->srcSubresource.mipLevel,989.levelCount = 1,990.baseArrayLayer = src_base_layer + layer,991.layerCount = 1,992},993},994NULL);995996struct radv_image_view dest_iview;997radv_image_view_init(&dest_iview, cmd_buffer->device,998&(VkImageViewCreateInfo){999.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,1000.image = radv_image_to_handle(dest_image),1001.viewType = radv_meta_get_view_type(dest_image),1002.format = dest_image->vk_format,1003.subresourceRange =1004{1005.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,1006.baseMipLevel = region->dstSubresource.mipLevel,1007.levelCount = 1,1008.baseArrayLayer = dest_base_layer + layer,1009.layerCount = 1,1010},1011},1012NULL);10131014VkFramebuffer fb;1015radv_CreateFramebuffer(1016radv_device_to_handle(cmd_buffer->device),1017&(VkFramebufferCreateInfo){.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,1018.attachmentCount = 1,1019.pAttachments =1020(VkImageView[]){1021radv_image_view_to_handle(&dest_iview),1022},1023.width = extent.width + dstOffset.x,1024.height = extent.height + dstOffset.y,1025.layers = 1},1026&cmd_buffer->pool->alloc, &fb);10271028radv_cmd_buffer_begin_render_pass(cmd_buffer,1029&(VkRenderPassBeginInfo){1030.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,1031.renderPass = rp,1032.framebuffer = fb,1033.renderArea =1034{1035.offset =1036{1037dstOffset.x,1038dstOffset.y,1039},1040.extent = {extent.width, extent.height},1041},1042.clearValueCount = 0,1043.pClearValues = NULL,1044},1045NULL);10461047radv_cmd_buffer_set_subpass(cmd_buffer, &cmd_buffer->state.pass->subpasses[0]);10481049emit_resolve(cmd_buffer, &src_iview, &dest_iview, &(VkOffset2D){srcOffset.x, srcOffset.y},1050&(VkOffset2D){dstOffset.x, dstOffset.y},1051&(VkExtent2D){extent.width, extent.height});10521053radv_cmd_buffer_end_render_pass(cmd_buffer);10541055radv_DestroyFramebuffer(radv_device_to_handle(cmd_buffer->device), fb,1056&cmd_buffer->pool->alloc);1057}10581059radv_meta_restore(&saved_state, cmd_buffer);1060}10611062/**1063* Emit any needed resolves for the current subpass.1064*/1065void1066radv_cmd_buffer_resolve_subpass_fs(struct radv_cmd_buffer *cmd_buffer)1067{1068struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;1069const struct radv_subpass *subpass = cmd_buffer->state.subpass;1070struct radv_meta_saved_state saved_state;1071struct radv_subpass_barrier barrier;10721073/* Resolves happen before the end-of-subpass barriers get executed,1074* so we have to make the attachment shader-readable */1075barrier.src_stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;1076barrier.src_access_mask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;1077barrier.dst_access_mask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;1078radv_subpass_barrier(cmd_buffer, &barrier);10791080radv_decompress_resolve_subpass_src(cmd_buffer);10811082radv_meta_save(1083&saved_state, cmd_buffer,1084RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS);10851086for (uint32_t i = 0; i < subpass->color_count; ++i) {1087struct radv_subpass_attachment src_att = subpass->color_attachments[i];1088struct radv_subpass_attachment dest_att = subpass->resolve_attachments[i];10891090if (dest_att.attachment == VK_ATTACHMENT_UNUSED)1091continue;10921093struct radv_image_view *dest_iview = cmd_buffer->state.attachments[dest_att.attachment].iview;1094struct radv_image_view *src_iview = cmd_buffer->state.attachments[src_att.attachment].iview;10951096struct radv_subpass resolve_subpass = {1097.color_count = 1,1098.color_attachments = (struct radv_subpass_attachment[]){dest_att},1099.depth_stencil_attachment = NULL,1100};11011102radv_cmd_buffer_set_subpass(cmd_buffer, &resolve_subpass);11031104emit_resolve(cmd_buffer, src_iview, dest_iview, &(VkOffset2D){0, 0}, &(VkOffset2D){0, 0},1105&(VkExtent2D){fb->width, fb->height});1106}11071108radv_cmd_buffer_set_subpass(cmd_buffer, subpass);11091110radv_meta_restore(&saved_state, cmd_buffer);1111}11121113/**1114* Depth/stencil resolves for the current subpass.1115*/1116void1117radv_depth_stencil_resolve_subpass_fs(struct radv_cmd_buffer *cmd_buffer,1118VkImageAspectFlags aspects,1119VkResolveModeFlagBits resolve_mode)1120{1121struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;1122const struct radv_subpass *subpass = cmd_buffer->state.subpass;1123struct radv_meta_saved_state saved_state;1124struct radv_subpass_barrier barrier;11251126/* Resolves happen before the end-of-subpass barriers get executed,1127* so we have to make the attachment shader-readable */1128barrier.src_stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;1129barrier.src_access_mask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;1130barrier.dst_access_mask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;1131radv_subpass_barrier(cmd_buffer, &barrier);11321133struct radv_subpass_attachment src_att = *subpass->depth_stencil_attachment;1134struct radv_image_view *src_iview = cmd_buffer->state.attachments[src_att.attachment].iview;1135struct radv_image *src_image = src_iview->image;11361137VkImageResolve2KHR region = {0};1138region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR;1139region.srcSubresource.aspectMask = aspects;1140region.srcSubresource.mipLevel = 0;1141region.srcSubresource.baseArrayLayer = 0;1142region.srcSubresource.layerCount = 1;11431144radv_decompress_resolve_src(cmd_buffer, src_image, src_att.layout, ®ion);11451146radv_meta_save(&saved_state, cmd_buffer,1147RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_DESCRIPTORS);11481149struct radv_subpass_attachment dst_att = *subpass->ds_resolve_attachment;1150struct radv_image_view *dst_iview = cmd_buffer->state.attachments[dst_att.attachment].iview;11511152struct radv_subpass resolve_subpass = {1153.color_count = 0,1154.color_attachments = NULL,1155.depth_stencil_attachment = (struct radv_subpass_attachment *){&dst_att},1156};11571158radv_cmd_buffer_set_subpass(cmd_buffer, &resolve_subpass);11591160struct radv_image_view tsrc_iview;1161radv_image_view_init(&tsrc_iview, cmd_buffer->device,1162&(VkImageViewCreateInfo){1163.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,1164.image = radv_image_to_handle(src_image),1165.viewType = radv_meta_get_view_type(src_image),1166.format = src_iview->vk_format,1167.subresourceRange =1168{1169.aspectMask = aspects,1170.baseMipLevel = 0,1171.levelCount = 1,1172.baseArrayLayer = 0,1173.layerCount = 1,1174},1175},1176NULL);11771178emit_depth_stencil_resolve(cmd_buffer, &tsrc_iview, dst_iview,1179&(VkExtent2D){fb->width, fb->height}, aspects, resolve_mode);11801181radv_cmd_buffer_set_subpass(cmd_buffer, subpass);11821183radv_meta_restore(&saved_state, cmd_buffer);1184}118511861187