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, &region->srcSubresource, &region->srcOffset);
809bf215546Sopenharmony_ci
810bf215546Sopenharmony_ci   const uint32_t dest_base_layer =
811bf215546Sopenharmony_ci      radv_meta_get_iview_layer(dest_image, &region->dstSubresource, &region->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, &region);
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