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_ssa_def *
34bf215546Sopenharmony_ciradv_meta_build_resolve_srgb_conversion(nir_builder *b, nir_ssa_def *input)
35bf215546Sopenharmony_ci{
36bf215546Sopenharmony_ci   unsigned i;
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci   nir_ssa_def *cmp[3];
39bf215546Sopenharmony_ci   for (i = 0; i < 3; i++)
40bf215546Sopenharmony_ci      cmp[i] = nir_flt(b, nir_channel(b, input, i), nir_imm_int(b, 0x3b4d2e1c));
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci   nir_ssa_def *ltvals[3];
43bf215546Sopenharmony_ci   for (i = 0; i < 3; i++)
44bf215546Sopenharmony_ci      ltvals[i] = nir_fmul(b, nir_channel(b, input, i), nir_imm_float(b, 12.92));
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_ci   nir_ssa_def *gtvals[3];
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_ci   for (i = 0; i < 3; i++) {
49bf215546Sopenharmony_ci      gtvals[i] = nir_fpow(b, nir_channel(b, input, i), nir_imm_float(b, 1.0 / 2.4));
50bf215546Sopenharmony_ci      gtvals[i] = nir_fmul(b, gtvals[i], nir_imm_float(b, 1.055));
51bf215546Sopenharmony_ci      gtvals[i] = nir_fsub(b, gtvals[i], nir_imm_float(b, 0.055));
52bf215546Sopenharmony_ci   }
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ci   nir_ssa_def *comp[4];
55bf215546Sopenharmony_ci   for (i = 0; i < 3; i++)
56bf215546Sopenharmony_ci      comp[i] = nir_bcsel(b, cmp[i], ltvals[i], gtvals[i]);
57bf215546Sopenharmony_ci   comp[3] = nir_channels(b, input, 1 << 3);
58bf215546Sopenharmony_ci   return nir_vec(b, comp, 4);
59bf215546Sopenharmony_ci}
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_cistatic nir_shader *
62bf215546Sopenharmony_cibuild_resolve_compute_shader(struct radv_device *dev, bool is_integer, bool is_srgb, int samples)
63bf215546Sopenharmony_ci{
64bf215546Sopenharmony_ci   enum glsl_base_type img_base_type = is_integer ? GLSL_TYPE_UINT : GLSL_TYPE_FLOAT;
65bf215546Sopenharmony_ci   const struct glsl_type *sampler_type =
66bf215546Sopenharmony_ci      glsl_sampler_type(GLSL_SAMPLER_DIM_MS, false, false, img_base_type);
67bf215546Sopenharmony_ci   const struct glsl_type *img_type = glsl_image_type(GLSL_SAMPLER_DIM_2D, false, img_base_type);
68bf215546Sopenharmony_ci   nir_builder b = radv_meta_init_shader(dev, MESA_SHADER_COMPUTE, "meta_resolve_cs-%d-%s", samples,
69bf215546Sopenharmony_ci                                         is_integer ? "int" : (is_srgb ? "srgb" : "float"));
70bf215546Sopenharmony_ci   b.shader->info.workgroup_size[0] = 8;
71bf215546Sopenharmony_ci   b.shader->info.workgroup_size[1] = 8;
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ci   nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex");
74bf215546Sopenharmony_ci   input_img->data.descriptor_set = 0;
75bf215546Sopenharmony_ci   input_img->data.binding = 0;
76bf215546Sopenharmony_ci
77bf215546Sopenharmony_ci   nir_variable *output_img = nir_variable_create(b.shader, nir_var_image, img_type, "out_img");
78bf215546Sopenharmony_ci   output_img->data.descriptor_set = 0;
79bf215546Sopenharmony_ci   output_img->data.binding = 1;
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_ci   nir_ssa_def *global_id = get_global_ids(&b, 2);
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ci   nir_ssa_def *src_offset = nir_load_push_constant(&b, 2, 32, nir_imm_int(&b, 0), .range = 8);
84bf215546Sopenharmony_ci   nir_ssa_def *dst_offset = nir_load_push_constant(&b, 2, 32, nir_imm_int(&b, 8), .range = 16);
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci   nir_ssa_def *src_coord = nir_iadd(&b, global_id, src_offset);
87bf215546Sopenharmony_ci   nir_ssa_def *dst_coord = nir_iadd(&b, global_id, dst_offset);
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ci   nir_variable *color = nir_local_variable_create(b.impl, glsl_vec4_type(), "color");
90bf215546Sopenharmony_ci
91bf215546Sopenharmony_ci   radv_meta_build_resolve_shader_core(&b, is_integer, samples, input_img, color, src_coord);
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci   nir_ssa_def *outval = nir_load_var(&b, color);
94bf215546Sopenharmony_ci   if (is_srgb)
95bf215546Sopenharmony_ci      outval = radv_meta_build_resolve_srgb_conversion(&b, outval);
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci   nir_ssa_def *img_coord = nir_vec4(&b, nir_channel(&b, dst_coord, 0),
98bf215546Sopenharmony_ci                                         nir_channel(&b, dst_coord, 1),
99bf215546Sopenharmony_ci                                         nir_ssa_undef(&b, 1, 32),
100bf215546Sopenharmony_ci                                         nir_ssa_undef(&b, 1, 32));
101bf215546Sopenharmony_ci
102bf215546Sopenharmony_ci   nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img)->dest.ssa, img_coord,
103bf215546Sopenharmony_ci                         nir_ssa_undef(&b, 1, 32), outval, nir_imm_int(&b, 0),
104bf215546Sopenharmony_ci                         .image_dim = GLSL_SAMPLER_DIM_2D);
105bf215546Sopenharmony_ci   return b.shader;
106bf215546Sopenharmony_ci}
107bf215546Sopenharmony_ci
108bf215546Sopenharmony_cienum {
109bf215546Sopenharmony_ci   DEPTH_RESOLVE,
110bf215546Sopenharmony_ci   STENCIL_RESOLVE,
111bf215546Sopenharmony_ci};
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_cistatic const char *
114bf215546Sopenharmony_ciget_resolve_mode_str(VkResolveModeFlagBits resolve_mode)
115bf215546Sopenharmony_ci{
116bf215546Sopenharmony_ci   switch (resolve_mode) {
117bf215546Sopenharmony_ci   case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT:
118bf215546Sopenharmony_ci      return "zero";
119bf215546Sopenharmony_ci   case VK_RESOLVE_MODE_AVERAGE_BIT:
120bf215546Sopenharmony_ci      return "average";
121bf215546Sopenharmony_ci   case VK_RESOLVE_MODE_MIN_BIT:
122bf215546Sopenharmony_ci      return "min";
123bf215546Sopenharmony_ci   case VK_RESOLVE_MODE_MAX_BIT:
124bf215546Sopenharmony_ci      return "max";
125bf215546Sopenharmony_ci   default:
126bf215546Sopenharmony_ci      unreachable("invalid resolve mode");
127bf215546Sopenharmony_ci   }
128bf215546Sopenharmony_ci}
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_cistatic nir_shader *
131bf215546Sopenharmony_cibuild_depth_stencil_resolve_compute_shader(struct radv_device *dev, int samples, int index,
132bf215546Sopenharmony_ci                                           VkResolveModeFlagBits resolve_mode)
133bf215546Sopenharmony_ci{
134bf215546Sopenharmony_ci   enum glsl_base_type img_base_type = index == DEPTH_RESOLVE ? GLSL_TYPE_FLOAT : GLSL_TYPE_UINT;
135bf215546Sopenharmony_ci   const struct glsl_type *sampler_type =
136bf215546Sopenharmony_ci      glsl_sampler_type(GLSL_SAMPLER_DIM_MS, false, true, img_base_type);
137bf215546Sopenharmony_ci   const struct glsl_type *img_type = glsl_image_type(GLSL_SAMPLER_DIM_2D, true, img_base_type);
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci   nir_builder b = radv_meta_init_shader(dev, MESA_SHADER_COMPUTE, "meta_resolve_cs_%s-%s-%d",
140bf215546Sopenharmony_ci                                         index == DEPTH_RESOLVE ? "depth" : "stencil",
141bf215546Sopenharmony_ci                                         get_resolve_mode_str(resolve_mode), samples);
142bf215546Sopenharmony_ci   b.shader->info.workgroup_size[0] = 8;
143bf215546Sopenharmony_ci   b.shader->info.workgroup_size[1] = 8;
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_ci   nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex");
146bf215546Sopenharmony_ci   input_img->data.descriptor_set = 0;
147bf215546Sopenharmony_ci   input_img->data.binding = 0;
148bf215546Sopenharmony_ci
149bf215546Sopenharmony_ci   nir_variable *output_img = nir_variable_create(b.shader, nir_var_image, img_type, "out_img");
150bf215546Sopenharmony_ci   output_img->data.descriptor_set = 0;
151bf215546Sopenharmony_ci   output_img->data.binding = 1;
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ci   nir_ssa_def *img_coord = get_global_ids(&b, 3);
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ci   nir_ssa_def *input_img_deref = &nir_build_deref_var(&b, input_img)->dest.ssa;
156bf215546Sopenharmony_ci
157bf215546Sopenharmony_ci   nir_alu_type type = index == DEPTH_RESOLVE ? nir_type_float32 : nir_type_uint32;
158bf215546Sopenharmony_ci
159bf215546Sopenharmony_ci   nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3);
160bf215546Sopenharmony_ci   tex->sampler_dim = GLSL_SAMPLER_DIM_MS;
161bf215546Sopenharmony_ci   tex->op = nir_texop_txf_ms;
162bf215546Sopenharmony_ci   tex->src[0].src_type = nir_tex_src_coord;
163bf215546Sopenharmony_ci   tex->src[0].src = nir_src_for_ssa(img_coord);
164bf215546Sopenharmony_ci   tex->src[1].src_type = nir_tex_src_ms_index;
165bf215546Sopenharmony_ci   tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0));
166bf215546Sopenharmony_ci   tex->src[2].src_type = nir_tex_src_texture_deref;
167bf215546Sopenharmony_ci   tex->src[2].src = nir_src_for_ssa(input_img_deref);
168bf215546Sopenharmony_ci   tex->dest_type = type;
169bf215546Sopenharmony_ci   tex->is_array = true;
170bf215546Sopenharmony_ci   tex->coord_components = 3;
171bf215546Sopenharmony_ci
172bf215546Sopenharmony_ci   nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
173bf215546Sopenharmony_ci   nir_builder_instr_insert(&b, &tex->instr);
174bf215546Sopenharmony_ci
175bf215546Sopenharmony_ci   nir_ssa_def *outval = &tex->dest.ssa;
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_ci   if (resolve_mode != VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) {
178bf215546Sopenharmony_ci      for (int i = 1; i < samples; i++) {
179bf215546Sopenharmony_ci         nir_tex_instr *tex_add = nir_tex_instr_create(b.shader, 3);
180bf215546Sopenharmony_ci         tex_add->sampler_dim = GLSL_SAMPLER_DIM_MS;
181bf215546Sopenharmony_ci         tex_add->op = nir_texop_txf_ms;
182bf215546Sopenharmony_ci         tex_add->src[0].src_type = nir_tex_src_coord;
183bf215546Sopenharmony_ci         tex_add->src[0].src = nir_src_for_ssa(img_coord);
184bf215546Sopenharmony_ci         tex_add->src[1].src_type = nir_tex_src_ms_index;
185bf215546Sopenharmony_ci         tex_add->src[1].src = nir_src_for_ssa(nir_imm_int(&b, i));
186bf215546Sopenharmony_ci         tex_add->src[2].src_type = nir_tex_src_texture_deref;
187bf215546Sopenharmony_ci         tex_add->src[2].src = nir_src_for_ssa(input_img_deref);
188bf215546Sopenharmony_ci         tex_add->dest_type = type;
189bf215546Sopenharmony_ci         tex_add->is_array = true;
190bf215546Sopenharmony_ci         tex_add->coord_components = 3;
191bf215546Sopenharmony_ci
192bf215546Sopenharmony_ci         nir_ssa_dest_init(&tex_add->instr, &tex_add->dest, 4, 32, "tex");
193bf215546Sopenharmony_ci         nir_builder_instr_insert(&b, &tex_add->instr);
194bf215546Sopenharmony_ci
195bf215546Sopenharmony_ci         switch (resolve_mode) {
196bf215546Sopenharmony_ci         case VK_RESOLVE_MODE_AVERAGE_BIT:
197bf215546Sopenharmony_ci            assert(index == DEPTH_RESOLVE);
198bf215546Sopenharmony_ci            outval = nir_fadd(&b, outval, &tex_add->dest.ssa);
199bf215546Sopenharmony_ci            break;
200bf215546Sopenharmony_ci         case VK_RESOLVE_MODE_MIN_BIT:
201bf215546Sopenharmony_ci            if (index == DEPTH_RESOLVE)
202bf215546Sopenharmony_ci               outval = nir_fmin(&b, outval, &tex_add->dest.ssa);
203bf215546Sopenharmony_ci            else
204bf215546Sopenharmony_ci               outval = nir_umin(&b, outval, &tex_add->dest.ssa);
205bf215546Sopenharmony_ci            break;
206bf215546Sopenharmony_ci         case VK_RESOLVE_MODE_MAX_BIT:
207bf215546Sopenharmony_ci            if (index == DEPTH_RESOLVE)
208bf215546Sopenharmony_ci               outval = nir_fmax(&b, outval, &tex_add->dest.ssa);
209bf215546Sopenharmony_ci            else
210bf215546Sopenharmony_ci               outval = nir_umax(&b, outval, &tex_add->dest.ssa);
211bf215546Sopenharmony_ci            break;
212bf215546Sopenharmony_ci         default:
213bf215546Sopenharmony_ci            unreachable("invalid resolve mode");
214bf215546Sopenharmony_ci         }
215bf215546Sopenharmony_ci      }
216bf215546Sopenharmony_ci
217bf215546Sopenharmony_ci      if (resolve_mode == VK_RESOLVE_MODE_AVERAGE_BIT)
218bf215546Sopenharmony_ci         outval = nir_fdiv(&b, outval, nir_imm_float(&b, samples));
219bf215546Sopenharmony_ci   }
220bf215546Sopenharmony_ci
221bf215546Sopenharmony_ci   nir_ssa_def *coord = nir_vec4(&b, nir_channel(&b, img_coord, 0), nir_channel(&b, img_coord, 1),
222bf215546Sopenharmony_ci                                 nir_channel(&b, img_coord, 2), nir_ssa_undef(&b, 1, 32));
223bf215546Sopenharmony_ci   nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img)->dest.ssa, coord,
224bf215546Sopenharmony_ci                         nir_ssa_undef(&b, 1, 32), outval, nir_imm_int(&b, 0),
225bf215546Sopenharmony_ci                         .image_dim = GLSL_SAMPLER_DIM_2D, .image_array = true);
226bf215546Sopenharmony_ci   return b.shader;
227bf215546Sopenharmony_ci}
228bf215546Sopenharmony_ci
229bf215546Sopenharmony_cistatic VkResult
230bf215546Sopenharmony_cicreate_layout(struct radv_device *device)
231bf215546Sopenharmony_ci{
232bf215546Sopenharmony_ci   VkResult result;
233bf215546Sopenharmony_ci   /*
234bf215546Sopenharmony_ci    * two descriptors one for the image being sampled
235bf215546Sopenharmony_ci    * one for the buffer being written.
236bf215546Sopenharmony_ci    */
237bf215546Sopenharmony_ci   VkDescriptorSetLayoutCreateInfo ds_create_info = {
238bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
239bf215546Sopenharmony_ci      .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
240bf215546Sopenharmony_ci      .bindingCount = 2,
241bf215546Sopenharmony_ci      .pBindings = (VkDescriptorSetLayoutBinding[]){
242bf215546Sopenharmony_ci         {.binding = 0,
243bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
244bf215546Sopenharmony_ci          .descriptorCount = 1,
245bf215546Sopenharmony_ci          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
246bf215546Sopenharmony_ci          .pImmutableSamplers = NULL},
247bf215546Sopenharmony_ci         {.binding = 1,
248bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
249bf215546Sopenharmony_ci          .descriptorCount = 1,
250bf215546Sopenharmony_ci          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
251bf215546Sopenharmony_ci          .pImmutableSamplers = NULL},
252bf215546Sopenharmony_ci      }};
253bf215546Sopenharmony_ci
254bf215546Sopenharmony_ci   result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &ds_create_info,
255bf215546Sopenharmony_ci                                           &device->meta_state.alloc,
256bf215546Sopenharmony_ci                                           &device->meta_state.resolve_compute.ds_layout);
257bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
258bf215546Sopenharmony_ci      goto fail;
259bf215546Sopenharmony_ci
260bf215546Sopenharmony_ci   VkPipelineLayoutCreateInfo pl_create_info = {
261bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
262bf215546Sopenharmony_ci      .setLayoutCount = 1,
263bf215546Sopenharmony_ci      .pSetLayouts = &device->meta_state.resolve_compute.ds_layout,
264bf215546Sopenharmony_ci      .pushConstantRangeCount = 1,
265bf215546Sopenharmony_ci      .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_COMPUTE_BIT, 0, 16},
266bf215546Sopenharmony_ci   };
267bf215546Sopenharmony_ci
268bf215546Sopenharmony_ci   result = radv_CreatePipelineLayout(radv_device_to_handle(device), &pl_create_info,
269bf215546Sopenharmony_ci                                      &device->meta_state.alloc,
270bf215546Sopenharmony_ci                                      &device->meta_state.resolve_compute.p_layout);
271bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
272bf215546Sopenharmony_ci      goto fail;
273bf215546Sopenharmony_ci   return VK_SUCCESS;
274bf215546Sopenharmony_cifail:
275bf215546Sopenharmony_ci   return result;
276bf215546Sopenharmony_ci}
277bf215546Sopenharmony_ci
278bf215546Sopenharmony_cistatic VkResult
279bf215546Sopenharmony_cicreate_resolve_pipeline(struct radv_device *device, int samples, bool is_integer, bool is_srgb,
280bf215546Sopenharmony_ci                        VkPipeline *pipeline)
281bf215546Sopenharmony_ci{
282bf215546Sopenharmony_ci   VkResult result;
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_ci   mtx_lock(&device->meta_state.mtx);
285bf215546Sopenharmony_ci   if (*pipeline) {
286bf215546Sopenharmony_ci      mtx_unlock(&device->meta_state.mtx);
287bf215546Sopenharmony_ci      return VK_SUCCESS;
288bf215546Sopenharmony_ci   }
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_ci   nir_shader *cs = build_resolve_compute_shader(device, is_integer, is_srgb, samples);
291bf215546Sopenharmony_ci
292bf215546Sopenharmony_ci   /* compute shader */
293bf215546Sopenharmony_ci
294bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
295bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
296bf215546Sopenharmony_ci      .stage = VK_SHADER_STAGE_COMPUTE_BIT,
297bf215546Sopenharmony_ci      .module = vk_shader_module_handle_from_nir(cs),
298bf215546Sopenharmony_ci      .pName = "main",
299bf215546Sopenharmony_ci      .pSpecializationInfo = NULL,
300bf215546Sopenharmony_ci   };
301bf215546Sopenharmony_ci
302bf215546Sopenharmony_ci   VkComputePipelineCreateInfo vk_pipeline_info = {
303bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
304bf215546Sopenharmony_ci      .stage = pipeline_shader_stage,
305bf215546Sopenharmony_ci      .flags = 0,
306bf215546Sopenharmony_ci      .layout = device->meta_state.resolve_compute.p_layout,
307bf215546Sopenharmony_ci   };
308bf215546Sopenharmony_ci
309bf215546Sopenharmony_ci   result = radv_CreateComputePipelines(radv_device_to_handle(device),
310bf215546Sopenharmony_ci                                        radv_pipeline_cache_to_handle(&device->meta_state.cache), 1,
311bf215546Sopenharmony_ci                                        &vk_pipeline_info, NULL, pipeline);
312bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
313bf215546Sopenharmony_ci      goto fail;
314bf215546Sopenharmony_ci
315bf215546Sopenharmony_ci   ralloc_free(cs);
316bf215546Sopenharmony_ci   mtx_unlock(&device->meta_state.mtx);
317bf215546Sopenharmony_ci   return VK_SUCCESS;
318bf215546Sopenharmony_cifail:
319bf215546Sopenharmony_ci   ralloc_free(cs);
320bf215546Sopenharmony_ci   mtx_unlock(&device->meta_state.mtx);
321bf215546Sopenharmony_ci   return result;
322bf215546Sopenharmony_ci}
323bf215546Sopenharmony_ci
324bf215546Sopenharmony_cistatic VkResult
325bf215546Sopenharmony_cicreate_depth_stencil_resolve_pipeline(struct radv_device *device, int samples, int index,
326bf215546Sopenharmony_ci                                      VkResolveModeFlagBits resolve_mode, VkPipeline *pipeline)
327bf215546Sopenharmony_ci{
328bf215546Sopenharmony_ci   VkResult result;
329bf215546Sopenharmony_ci
330bf215546Sopenharmony_ci   mtx_lock(&device->meta_state.mtx);
331bf215546Sopenharmony_ci   if (*pipeline) {
332bf215546Sopenharmony_ci      mtx_unlock(&device->meta_state.mtx);
333bf215546Sopenharmony_ci      return VK_SUCCESS;
334bf215546Sopenharmony_ci   }
335bf215546Sopenharmony_ci
336bf215546Sopenharmony_ci   nir_shader *cs =
337bf215546Sopenharmony_ci      build_depth_stencil_resolve_compute_shader(device, samples, index, resolve_mode);
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_ci   /* compute shader */
340bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
341bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
342bf215546Sopenharmony_ci      .stage = VK_SHADER_STAGE_COMPUTE_BIT,
343bf215546Sopenharmony_ci      .module = vk_shader_module_handle_from_nir(cs),
344bf215546Sopenharmony_ci      .pName = "main",
345bf215546Sopenharmony_ci      .pSpecializationInfo = NULL,
346bf215546Sopenharmony_ci   };
347bf215546Sopenharmony_ci
348bf215546Sopenharmony_ci   VkComputePipelineCreateInfo vk_pipeline_info = {
349bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
350bf215546Sopenharmony_ci      .stage = pipeline_shader_stage,
351bf215546Sopenharmony_ci      .flags = 0,
352bf215546Sopenharmony_ci      .layout = device->meta_state.resolve_compute.p_layout,
353bf215546Sopenharmony_ci   };
354bf215546Sopenharmony_ci
355bf215546Sopenharmony_ci   result = radv_CreateComputePipelines(radv_device_to_handle(device),
356bf215546Sopenharmony_ci                                        radv_pipeline_cache_to_handle(&device->meta_state.cache), 1,
357bf215546Sopenharmony_ci                                        &vk_pipeline_info, NULL, pipeline);
358bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
359bf215546Sopenharmony_ci      goto fail;
360bf215546Sopenharmony_ci
361bf215546Sopenharmony_ci   ralloc_free(cs);
362bf215546Sopenharmony_ci   mtx_unlock(&device->meta_state.mtx);
363bf215546Sopenharmony_ci   return VK_SUCCESS;
364bf215546Sopenharmony_cifail:
365bf215546Sopenharmony_ci   ralloc_free(cs);
366bf215546Sopenharmony_ci   mtx_unlock(&device->meta_state.mtx);
367bf215546Sopenharmony_ci   return result;
368bf215546Sopenharmony_ci}
369bf215546Sopenharmony_ci
370bf215546Sopenharmony_ciVkResult
371bf215546Sopenharmony_ciradv_device_init_meta_resolve_compute_state(struct radv_device *device, bool on_demand)
372bf215546Sopenharmony_ci{
373bf215546Sopenharmony_ci   struct radv_meta_state *state = &device->meta_state;
374bf215546Sopenharmony_ci   VkResult res;
375bf215546Sopenharmony_ci
376bf215546Sopenharmony_ci   res = create_layout(device);
377bf215546Sopenharmony_ci   if (res != VK_SUCCESS)
378bf215546Sopenharmony_ci      return res;
379bf215546Sopenharmony_ci
380bf215546Sopenharmony_ci   if (on_demand)
381bf215546Sopenharmony_ci      return VK_SUCCESS;
382bf215546Sopenharmony_ci
383bf215546Sopenharmony_ci   for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; ++i) {
384bf215546Sopenharmony_ci      uint32_t samples = 1 << i;
385bf215546Sopenharmony_ci
386bf215546Sopenharmony_ci      res = create_resolve_pipeline(device, samples, false, false,
387bf215546Sopenharmony_ci                                    &state->resolve_compute.rc[i].pipeline);
388bf215546Sopenharmony_ci      if (res != VK_SUCCESS)
389bf215546Sopenharmony_ci         return res;
390bf215546Sopenharmony_ci
391bf215546Sopenharmony_ci      res = create_resolve_pipeline(device, samples, true, false,
392bf215546Sopenharmony_ci                                    &state->resolve_compute.rc[i].i_pipeline);
393bf215546Sopenharmony_ci      if (res != VK_SUCCESS)
394bf215546Sopenharmony_ci         return res;
395bf215546Sopenharmony_ci
396bf215546Sopenharmony_ci      res = create_resolve_pipeline(device, samples, false, true,
397bf215546Sopenharmony_ci                                    &state->resolve_compute.rc[i].srgb_pipeline);
398bf215546Sopenharmony_ci      if (res != VK_SUCCESS)
399bf215546Sopenharmony_ci         return res;
400bf215546Sopenharmony_ci
401bf215546Sopenharmony_ci      res = create_depth_stencil_resolve_pipeline(
402bf215546Sopenharmony_ci         device, samples, DEPTH_RESOLVE, VK_RESOLVE_MODE_AVERAGE_BIT,
403bf215546Sopenharmony_ci         &state->resolve_compute.depth[i].average_pipeline);
404bf215546Sopenharmony_ci      if (res != VK_SUCCESS)
405bf215546Sopenharmony_ci         return res;
406bf215546Sopenharmony_ci
407bf215546Sopenharmony_ci      res = create_depth_stencil_resolve_pipeline(device, samples, DEPTH_RESOLVE,
408bf215546Sopenharmony_ci                                                  VK_RESOLVE_MODE_MAX_BIT,
409bf215546Sopenharmony_ci                                                  &state->resolve_compute.depth[i].max_pipeline);
410bf215546Sopenharmony_ci      if (res != VK_SUCCESS)
411bf215546Sopenharmony_ci         return res;
412bf215546Sopenharmony_ci
413bf215546Sopenharmony_ci      res = create_depth_stencil_resolve_pipeline(device, samples, DEPTH_RESOLVE,
414bf215546Sopenharmony_ci                                                  VK_RESOLVE_MODE_MIN_BIT,
415bf215546Sopenharmony_ci                                                  &state->resolve_compute.depth[i].min_pipeline);
416bf215546Sopenharmony_ci      if (res != VK_SUCCESS)
417bf215546Sopenharmony_ci         return res;
418bf215546Sopenharmony_ci
419bf215546Sopenharmony_ci      res = create_depth_stencil_resolve_pipeline(device, samples, STENCIL_RESOLVE,
420bf215546Sopenharmony_ci                                                  VK_RESOLVE_MODE_MAX_BIT,
421bf215546Sopenharmony_ci                                                  &state->resolve_compute.stencil[i].max_pipeline);
422bf215546Sopenharmony_ci      if (res != VK_SUCCESS)
423bf215546Sopenharmony_ci         return res;
424bf215546Sopenharmony_ci
425bf215546Sopenharmony_ci      res = create_depth_stencil_resolve_pipeline(device, samples, STENCIL_RESOLVE,
426bf215546Sopenharmony_ci                                                  VK_RESOLVE_MODE_MIN_BIT,
427bf215546Sopenharmony_ci                                                  &state->resolve_compute.stencil[i].min_pipeline);
428bf215546Sopenharmony_ci      if (res != VK_SUCCESS)
429bf215546Sopenharmony_ci         return res;
430bf215546Sopenharmony_ci   }
431bf215546Sopenharmony_ci
432bf215546Sopenharmony_ci   res = create_depth_stencil_resolve_pipeline(device, 0, DEPTH_RESOLVE,
433bf215546Sopenharmony_ci                                               VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
434bf215546Sopenharmony_ci                                               &state->resolve_compute.depth_zero_pipeline);
435bf215546Sopenharmony_ci   if (res != VK_SUCCESS)
436bf215546Sopenharmony_ci      return res;
437bf215546Sopenharmony_ci
438bf215546Sopenharmony_ci   return create_depth_stencil_resolve_pipeline(device, 0, STENCIL_RESOLVE,
439bf215546Sopenharmony_ci                                                VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
440bf215546Sopenharmony_ci                                                &state->resolve_compute.stencil_zero_pipeline);
441bf215546Sopenharmony_ci}
442bf215546Sopenharmony_ci
443bf215546Sopenharmony_civoid
444bf215546Sopenharmony_ciradv_device_finish_meta_resolve_compute_state(struct radv_device *device)
445bf215546Sopenharmony_ci{
446bf215546Sopenharmony_ci   struct radv_meta_state *state = &device->meta_state;
447bf215546Sopenharmony_ci   for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; ++i) {
448bf215546Sopenharmony_ci      radv_DestroyPipeline(radv_device_to_handle(device), state->resolve_compute.rc[i].pipeline,
449bf215546Sopenharmony_ci                           &state->alloc);
450bf215546Sopenharmony_ci
451bf215546Sopenharmony_ci      radv_DestroyPipeline(radv_device_to_handle(device), state->resolve_compute.rc[i].i_pipeline,
452bf215546Sopenharmony_ci                           &state->alloc);
453bf215546Sopenharmony_ci
454bf215546Sopenharmony_ci      radv_DestroyPipeline(radv_device_to_handle(device),
455bf215546Sopenharmony_ci                           state->resolve_compute.rc[i].srgb_pipeline, &state->alloc);
456bf215546Sopenharmony_ci
457bf215546Sopenharmony_ci      radv_DestroyPipeline(radv_device_to_handle(device),
458bf215546Sopenharmony_ci                           state->resolve_compute.depth[i].average_pipeline, &state->alloc);
459bf215546Sopenharmony_ci
460bf215546Sopenharmony_ci      radv_DestroyPipeline(radv_device_to_handle(device),
461bf215546Sopenharmony_ci                           state->resolve_compute.depth[i].max_pipeline, &state->alloc);
462bf215546Sopenharmony_ci
463bf215546Sopenharmony_ci      radv_DestroyPipeline(radv_device_to_handle(device),
464bf215546Sopenharmony_ci                           state->resolve_compute.depth[i].min_pipeline, &state->alloc);
465bf215546Sopenharmony_ci
466bf215546Sopenharmony_ci      radv_DestroyPipeline(radv_device_to_handle(device),
467bf215546Sopenharmony_ci                           state->resolve_compute.stencil[i].max_pipeline, &state->alloc);
468bf215546Sopenharmony_ci
469bf215546Sopenharmony_ci      radv_DestroyPipeline(radv_device_to_handle(device),
470bf215546Sopenharmony_ci                           state->resolve_compute.stencil[i].min_pipeline, &state->alloc);
471bf215546Sopenharmony_ci   }
472bf215546Sopenharmony_ci
473bf215546Sopenharmony_ci   radv_DestroyPipeline(radv_device_to_handle(device), state->resolve_compute.depth_zero_pipeline,
474bf215546Sopenharmony_ci                        &state->alloc);
475bf215546Sopenharmony_ci
476bf215546Sopenharmony_ci   radv_DestroyPipeline(radv_device_to_handle(device), state->resolve_compute.stencil_zero_pipeline,
477bf215546Sopenharmony_ci                        &state->alloc);
478bf215546Sopenharmony_ci
479bf215546Sopenharmony_ci   device->vk.dispatch_table.DestroyDescriptorSetLayout(
480bf215546Sopenharmony_ci      radv_device_to_handle(device), state->resolve_compute.ds_layout, &state->alloc);
481bf215546Sopenharmony_ci   radv_DestroyPipelineLayout(radv_device_to_handle(device), state->resolve_compute.p_layout,
482bf215546Sopenharmony_ci                              &state->alloc);
483bf215546Sopenharmony_ci}
484bf215546Sopenharmony_ci
485bf215546Sopenharmony_cistatic VkPipeline *
486bf215546Sopenharmony_ciradv_get_resolve_pipeline(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview)
487bf215546Sopenharmony_ci{
488bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
489bf215546Sopenharmony_ci   struct radv_meta_state *state = &device->meta_state;
490bf215546Sopenharmony_ci   uint32_t samples = src_iview->image->info.samples;
491bf215546Sopenharmony_ci   uint32_t samples_log2 = ffs(samples) - 1;
492bf215546Sopenharmony_ci   VkPipeline *pipeline;
493bf215546Sopenharmony_ci
494bf215546Sopenharmony_ci   if (vk_format_is_int(src_iview->vk.format))
495bf215546Sopenharmony_ci      pipeline = &state->resolve_compute.rc[samples_log2].i_pipeline;
496bf215546Sopenharmony_ci   else if (vk_format_is_srgb(src_iview->vk.format))
497bf215546Sopenharmony_ci      pipeline = &state->resolve_compute.rc[samples_log2].srgb_pipeline;
498bf215546Sopenharmony_ci   else
499bf215546Sopenharmony_ci      pipeline = &state->resolve_compute.rc[samples_log2].pipeline;
500bf215546Sopenharmony_ci
501bf215546Sopenharmony_ci   if (!*pipeline) {
502bf215546Sopenharmony_ci      VkResult ret;
503bf215546Sopenharmony_ci
504bf215546Sopenharmony_ci      ret = create_resolve_pipeline(device, samples, vk_format_is_int(src_iview->vk.format),
505bf215546Sopenharmony_ci                                    vk_format_is_srgb(src_iview->vk.format), pipeline);
506bf215546Sopenharmony_ci      if (ret != VK_SUCCESS) {
507bf215546Sopenharmony_ci         cmd_buffer->record_result = ret;
508bf215546Sopenharmony_ci         return NULL;
509bf215546Sopenharmony_ci      }
510bf215546Sopenharmony_ci   }
511bf215546Sopenharmony_ci
512bf215546Sopenharmony_ci   return pipeline;
513bf215546Sopenharmony_ci}
514bf215546Sopenharmony_ci
515bf215546Sopenharmony_cistatic void
516bf215546Sopenharmony_ciemit_resolve(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview,
517bf215546Sopenharmony_ci             struct radv_image_view *dest_iview, const VkOffset2D *src_offset,
518bf215546Sopenharmony_ci             const VkOffset2D *dest_offset, const VkExtent2D *resolve_extent)
519bf215546Sopenharmony_ci{
520bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
521bf215546Sopenharmony_ci   VkPipeline *pipeline;
522bf215546Sopenharmony_ci
523bf215546Sopenharmony_ci   radv_meta_push_descriptor_set(
524bf215546Sopenharmony_ci      cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, device->meta_state.resolve_compute.p_layout,
525bf215546Sopenharmony_ci      0, /* set */
526bf215546Sopenharmony_ci      2, /* descriptorWriteCount */
527bf215546Sopenharmony_ci      (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
528bf215546Sopenharmony_ci                                .dstBinding = 0,
529bf215546Sopenharmony_ci                                .dstArrayElement = 0,
530bf215546Sopenharmony_ci                                .descriptorCount = 1,
531bf215546Sopenharmony_ci                                .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
532bf215546Sopenharmony_ci                                .pImageInfo =
533bf215546Sopenharmony_ci                                   (VkDescriptorImageInfo[]){
534bf215546Sopenharmony_ci                                      {.sampler = VK_NULL_HANDLE,
535bf215546Sopenharmony_ci                                       .imageView = radv_image_view_to_handle(src_iview),
536bf215546Sopenharmony_ci                                       .imageLayout = VK_IMAGE_LAYOUT_GENERAL},
537bf215546Sopenharmony_ci                                   }},
538bf215546Sopenharmony_ci                               {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
539bf215546Sopenharmony_ci                                .dstBinding = 1,
540bf215546Sopenharmony_ci                                .dstArrayElement = 0,
541bf215546Sopenharmony_ci                                .descriptorCount = 1,
542bf215546Sopenharmony_ci                                .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
543bf215546Sopenharmony_ci                                .pImageInfo = (VkDescriptorImageInfo[]){
544bf215546Sopenharmony_ci                                   {
545bf215546Sopenharmony_ci                                      .sampler = VK_NULL_HANDLE,
546bf215546Sopenharmony_ci                                      .imageView = radv_image_view_to_handle(dest_iview),
547bf215546Sopenharmony_ci                                      .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
548bf215546Sopenharmony_ci                                   },
549bf215546Sopenharmony_ci                                }}});
550bf215546Sopenharmony_ci
551bf215546Sopenharmony_ci   pipeline = radv_get_resolve_pipeline(cmd_buffer, src_iview);
552bf215546Sopenharmony_ci
553bf215546Sopenharmony_ci   radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE,
554bf215546Sopenharmony_ci                        *pipeline);
555bf215546Sopenharmony_ci
556bf215546Sopenharmony_ci   unsigned push_constants[4] = {
557bf215546Sopenharmony_ci      src_offset->x,
558bf215546Sopenharmony_ci      src_offset->y,
559bf215546Sopenharmony_ci      dest_offset->x,
560bf215546Sopenharmony_ci      dest_offset->y,
561bf215546Sopenharmony_ci   };
562bf215546Sopenharmony_ci   radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
563bf215546Sopenharmony_ci                         device->meta_state.resolve_compute.p_layout, VK_SHADER_STAGE_COMPUTE_BIT,
564bf215546Sopenharmony_ci                         0, 16, push_constants);
565bf215546Sopenharmony_ci   radv_unaligned_dispatch(cmd_buffer, resolve_extent->width, resolve_extent->height, 1);
566bf215546Sopenharmony_ci}
567bf215546Sopenharmony_ci
568bf215546Sopenharmony_cistatic void
569bf215546Sopenharmony_ciemit_depth_stencil_resolve(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview,
570bf215546Sopenharmony_ci                           struct radv_image_view *dest_iview, const VkExtent3D *resolve_extent,
571bf215546Sopenharmony_ci                           VkImageAspectFlags aspects, VkResolveModeFlagBits resolve_mode)
572bf215546Sopenharmony_ci{
573bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
574bf215546Sopenharmony_ci   const uint32_t samples = src_iview->image->info.samples;
575bf215546Sopenharmony_ci   const uint32_t samples_log2 = ffs(samples) - 1;
576bf215546Sopenharmony_ci   VkPipeline *pipeline;
577bf215546Sopenharmony_ci
578bf215546Sopenharmony_ci   radv_meta_push_descriptor_set(
579bf215546Sopenharmony_ci      cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, device->meta_state.resolve_compute.p_layout,
580bf215546Sopenharmony_ci      0, /* set */
581bf215546Sopenharmony_ci      2, /* descriptorWriteCount */
582bf215546Sopenharmony_ci      (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
583bf215546Sopenharmony_ci                                .dstBinding = 0,
584bf215546Sopenharmony_ci                                .dstArrayElement = 0,
585bf215546Sopenharmony_ci                                .descriptorCount = 1,
586bf215546Sopenharmony_ci                                .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
587bf215546Sopenharmony_ci                                .pImageInfo =
588bf215546Sopenharmony_ci                                   (VkDescriptorImageInfo[]){
589bf215546Sopenharmony_ci                                      {.sampler = VK_NULL_HANDLE,
590bf215546Sopenharmony_ci                                       .imageView = radv_image_view_to_handle(src_iview),
591bf215546Sopenharmony_ci                                       .imageLayout = VK_IMAGE_LAYOUT_GENERAL},
592bf215546Sopenharmony_ci                                   }},
593bf215546Sopenharmony_ci                               {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
594bf215546Sopenharmony_ci                                .dstBinding = 1,
595bf215546Sopenharmony_ci                                .dstArrayElement = 0,
596bf215546Sopenharmony_ci                                .descriptorCount = 1,
597bf215546Sopenharmony_ci                                .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
598bf215546Sopenharmony_ci                                .pImageInfo = (VkDescriptorImageInfo[]){
599bf215546Sopenharmony_ci                                   {
600bf215546Sopenharmony_ci                                      .sampler = VK_NULL_HANDLE,
601bf215546Sopenharmony_ci                                      .imageView = radv_image_view_to_handle(dest_iview),
602bf215546Sopenharmony_ci                                      .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
603bf215546Sopenharmony_ci                                   },
604bf215546Sopenharmony_ci                                }}});
605bf215546Sopenharmony_ci
606bf215546Sopenharmony_ci   switch (resolve_mode) {
607bf215546Sopenharmony_ci   case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT:
608bf215546Sopenharmony_ci      if (aspects == VK_IMAGE_ASPECT_DEPTH_BIT)
609bf215546Sopenharmony_ci         pipeline = &device->meta_state.resolve_compute.depth_zero_pipeline;
610bf215546Sopenharmony_ci      else
611bf215546Sopenharmony_ci         pipeline = &device->meta_state.resolve_compute.stencil_zero_pipeline;
612bf215546Sopenharmony_ci      break;
613bf215546Sopenharmony_ci   case VK_RESOLVE_MODE_AVERAGE_BIT:
614bf215546Sopenharmony_ci      assert(aspects == VK_IMAGE_ASPECT_DEPTH_BIT);
615bf215546Sopenharmony_ci      pipeline = &device->meta_state.resolve_compute.depth[samples_log2].average_pipeline;
616bf215546Sopenharmony_ci      break;
617bf215546Sopenharmony_ci   case VK_RESOLVE_MODE_MIN_BIT:
618bf215546Sopenharmony_ci      if (aspects == VK_IMAGE_ASPECT_DEPTH_BIT)
619bf215546Sopenharmony_ci         pipeline = &device->meta_state.resolve_compute.depth[samples_log2].min_pipeline;
620bf215546Sopenharmony_ci      else
621bf215546Sopenharmony_ci         pipeline = &device->meta_state.resolve_compute.stencil[samples_log2].min_pipeline;
622bf215546Sopenharmony_ci      break;
623bf215546Sopenharmony_ci   case VK_RESOLVE_MODE_MAX_BIT:
624bf215546Sopenharmony_ci      if (aspects == VK_IMAGE_ASPECT_DEPTH_BIT)
625bf215546Sopenharmony_ci         pipeline = &device->meta_state.resolve_compute.depth[samples_log2].max_pipeline;
626bf215546Sopenharmony_ci      else
627bf215546Sopenharmony_ci         pipeline = &device->meta_state.resolve_compute.stencil[samples_log2].max_pipeline;
628bf215546Sopenharmony_ci      break;
629bf215546Sopenharmony_ci   default:
630bf215546Sopenharmony_ci      unreachable("invalid resolve mode");
631bf215546Sopenharmony_ci   }
632bf215546Sopenharmony_ci
633bf215546Sopenharmony_ci   if (!*pipeline) {
634bf215546Sopenharmony_ci      int index = aspects == VK_IMAGE_ASPECT_DEPTH_BIT ? DEPTH_RESOLVE : STENCIL_RESOLVE;
635bf215546Sopenharmony_ci      VkResult ret;
636bf215546Sopenharmony_ci
637bf215546Sopenharmony_ci      ret = create_depth_stencil_resolve_pipeline(device, samples, index, resolve_mode, pipeline);
638bf215546Sopenharmony_ci      if (ret != VK_SUCCESS) {
639bf215546Sopenharmony_ci         cmd_buffer->record_result = ret;
640bf215546Sopenharmony_ci         return;
641bf215546Sopenharmony_ci      }
642bf215546Sopenharmony_ci   }
643bf215546Sopenharmony_ci
644bf215546Sopenharmony_ci   radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE,
645bf215546Sopenharmony_ci                        *pipeline);
646bf215546Sopenharmony_ci
647bf215546Sopenharmony_ci   radv_unaligned_dispatch(cmd_buffer, resolve_extent->width, resolve_extent->height,
648bf215546Sopenharmony_ci                           resolve_extent->depth);
649bf215546Sopenharmony_ci}
650bf215546Sopenharmony_ci
651bf215546Sopenharmony_civoid
652bf215546Sopenharmony_ciradv_meta_resolve_compute_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image,
653bf215546Sopenharmony_ci                                VkFormat src_format, VkImageLayout src_image_layout,
654bf215546Sopenharmony_ci                                struct radv_image *dest_image, VkFormat dest_format,
655bf215546Sopenharmony_ci                                VkImageLayout dest_image_layout, const VkImageResolve2 *region)
656bf215546Sopenharmony_ci{
657bf215546Sopenharmony_ci   struct radv_meta_saved_state saved_state;
658bf215546Sopenharmony_ci
659bf215546Sopenharmony_ci   radv_decompress_resolve_src(cmd_buffer, src_image, src_image_layout, region);
660bf215546Sopenharmony_ci
661bf215546Sopenharmony_ci   /* For partial resolves, DCC should be decompressed before resolving
662bf215546Sopenharmony_ci    * because the metadata is re-initialized to the uncompressed after.
663bf215546Sopenharmony_ci    */
664bf215546Sopenharmony_ci   uint32_t queue_mask = radv_image_queue_family_mask(dest_image, cmd_buffer->qf,
665bf215546Sopenharmony_ci                                                      cmd_buffer->qf);
666bf215546Sopenharmony_ci
667bf215546Sopenharmony_ci   if (!radv_image_use_dcc_image_stores(cmd_buffer->device, dest_image) &&
668bf215546Sopenharmony_ci       radv_layout_dcc_compressed(cmd_buffer->device, dest_image, region->dstSubresource.mipLevel,
669bf215546Sopenharmony_ci                                  dest_image_layout, false, queue_mask) &&
670bf215546Sopenharmony_ci       (region->dstOffset.x || region->dstOffset.y || region->dstOffset.z ||
671bf215546Sopenharmony_ci        region->extent.width != dest_image->info.width ||
672bf215546Sopenharmony_ci        region->extent.height != dest_image->info.height ||
673bf215546Sopenharmony_ci        region->extent.depth != dest_image->info.depth)) {
674bf215546Sopenharmony_ci      radv_decompress_dcc(cmd_buffer, dest_image,
675bf215546Sopenharmony_ci                          &(VkImageSubresourceRange){
676bf215546Sopenharmony_ci                             .aspectMask = region->dstSubresource.aspectMask,
677bf215546Sopenharmony_ci                             .baseMipLevel = region->dstSubresource.mipLevel,
678bf215546Sopenharmony_ci                             .levelCount = 1,
679bf215546Sopenharmony_ci                             .baseArrayLayer = region->dstSubresource.baseArrayLayer,
680bf215546Sopenharmony_ci                             .layerCount = region->dstSubresource.layerCount,
681bf215546Sopenharmony_ci                          });
682bf215546Sopenharmony_ci   }
683bf215546Sopenharmony_ci
684bf215546Sopenharmony_ci   radv_meta_save(
685bf215546Sopenharmony_ci      &saved_state, cmd_buffer,
686bf215546Sopenharmony_ci      RADV_META_SAVE_COMPUTE_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS);
687bf215546Sopenharmony_ci
688bf215546Sopenharmony_ci   assert(region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
689bf215546Sopenharmony_ci   assert(region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
690bf215546Sopenharmony_ci   assert(region->srcSubresource.layerCount == region->dstSubresource.layerCount);
691bf215546Sopenharmony_ci
692bf215546Sopenharmony_ci   const uint32_t src_base_layer =
693bf215546Sopenharmony_ci      radv_meta_get_iview_layer(src_image, &region->srcSubresource, &region->srcOffset);
694bf215546Sopenharmony_ci
695bf215546Sopenharmony_ci   const uint32_t dest_base_layer =
696bf215546Sopenharmony_ci      radv_meta_get_iview_layer(dest_image, &region->dstSubresource, &region->dstOffset);
697bf215546Sopenharmony_ci
698bf215546Sopenharmony_ci   const struct VkExtent3D extent = vk_image_sanitize_extent(&src_image->vk, region->extent);
699bf215546Sopenharmony_ci   const struct VkOffset3D srcOffset = vk_image_sanitize_offset(&src_image->vk, region->srcOffset);
700bf215546Sopenharmony_ci   const struct VkOffset3D dstOffset = vk_image_sanitize_offset(&dest_image->vk, region->dstOffset);
701bf215546Sopenharmony_ci
702bf215546Sopenharmony_ci   for (uint32_t layer = 0; layer < region->srcSubresource.layerCount; ++layer) {
703bf215546Sopenharmony_ci
704bf215546Sopenharmony_ci      struct radv_image_view src_iview;
705bf215546Sopenharmony_ci      radv_image_view_init(&src_iview, cmd_buffer->device,
706bf215546Sopenharmony_ci                           &(VkImageViewCreateInfo){
707bf215546Sopenharmony_ci                              .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
708bf215546Sopenharmony_ci                              .image = radv_image_to_handle(src_image),
709bf215546Sopenharmony_ci                              .viewType = radv_meta_get_view_type(src_image),
710bf215546Sopenharmony_ci                              .format = src_format,
711bf215546Sopenharmony_ci                              .subresourceRange =
712bf215546Sopenharmony_ci                                 {
713bf215546Sopenharmony_ci                                    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
714bf215546Sopenharmony_ci                                    .baseMipLevel = region->srcSubresource.mipLevel,
715bf215546Sopenharmony_ci                                    .levelCount = 1,
716bf215546Sopenharmony_ci                                    .baseArrayLayer = src_base_layer + layer,
717bf215546Sopenharmony_ci                                    .layerCount = 1,
718bf215546Sopenharmony_ci                                 },
719bf215546Sopenharmony_ci                           },
720bf215546Sopenharmony_ci                           0, NULL);
721bf215546Sopenharmony_ci
722bf215546Sopenharmony_ci      struct radv_image_view dest_iview;
723bf215546Sopenharmony_ci      radv_image_view_init(&dest_iview, cmd_buffer->device,
724bf215546Sopenharmony_ci                           &(VkImageViewCreateInfo){
725bf215546Sopenharmony_ci                              .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
726bf215546Sopenharmony_ci                              .image = radv_image_to_handle(dest_image),
727bf215546Sopenharmony_ci                              .viewType = radv_meta_get_view_type(dest_image),
728bf215546Sopenharmony_ci                              .format = vk_to_non_srgb_format(dest_format),
729bf215546Sopenharmony_ci                              .subresourceRange =
730bf215546Sopenharmony_ci                                 {
731bf215546Sopenharmony_ci                                    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
732bf215546Sopenharmony_ci                                    .baseMipLevel = region->dstSubresource.mipLevel,
733bf215546Sopenharmony_ci                                    .levelCount = 1,
734bf215546Sopenharmony_ci                                    .baseArrayLayer = dest_base_layer + layer,
735bf215546Sopenharmony_ci                                    .layerCount = 1,
736bf215546Sopenharmony_ci                                 },
737bf215546Sopenharmony_ci                           },
738bf215546Sopenharmony_ci                           0, NULL);
739bf215546Sopenharmony_ci
740bf215546Sopenharmony_ci      emit_resolve(cmd_buffer, &src_iview, &dest_iview, &(VkOffset2D){srcOffset.x, srcOffset.y},
741bf215546Sopenharmony_ci                   &(VkOffset2D){dstOffset.x, dstOffset.y},
742bf215546Sopenharmony_ci                   &(VkExtent2D){extent.width, extent.height});
743bf215546Sopenharmony_ci
744bf215546Sopenharmony_ci      radv_image_view_finish(&src_iview);
745bf215546Sopenharmony_ci      radv_image_view_finish(&dest_iview);
746bf215546Sopenharmony_ci   }
747bf215546Sopenharmony_ci
748bf215546Sopenharmony_ci   radv_meta_restore(&saved_state, cmd_buffer);
749bf215546Sopenharmony_ci
750bf215546Sopenharmony_ci   if (!radv_image_use_dcc_image_stores(cmd_buffer->device, dest_image) &&
751bf215546Sopenharmony_ci       radv_layout_dcc_compressed(cmd_buffer->device, dest_image, region->dstSubresource.mipLevel,
752bf215546Sopenharmony_ci                                  dest_image_layout, false, queue_mask)) {
753bf215546Sopenharmony_ci
754bf215546Sopenharmony_ci      cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH | RADV_CMD_FLAG_INV_VCACHE;
755bf215546Sopenharmony_ci
756bf215546Sopenharmony_ci      VkImageSubresourceRange range = {
757bf215546Sopenharmony_ci         .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
758bf215546Sopenharmony_ci         .baseMipLevel = region->dstSubresource.mipLevel,
759bf215546Sopenharmony_ci         .levelCount = 1,
760bf215546Sopenharmony_ci         .baseArrayLayer = dest_base_layer,
761bf215546Sopenharmony_ci         .layerCount = region->dstSubresource.layerCount,
762bf215546Sopenharmony_ci      };
763bf215546Sopenharmony_ci
764bf215546Sopenharmony_ci      cmd_buffer->state.flush_bits |= radv_init_dcc(cmd_buffer, dest_image, &range, 0xffffffff);
765bf215546Sopenharmony_ci   }
766bf215546Sopenharmony_ci}
767bf215546Sopenharmony_ci
768bf215546Sopenharmony_ci/**
769bf215546Sopenharmony_ci * Emit any needed resolves for the current subpass.
770bf215546Sopenharmony_ci */
771bf215546Sopenharmony_civoid
772bf215546Sopenharmony_ciradv_cmd_buffer_resolve_subpass_cs(struct radv_cmd_buffer *cmd_buffer)
773bf215546Sopenharmony_ci{
774bf215546Sopenharmony_ci   struct vk_framebuffer *fb = cmd_buffer->state.framebuffer;
775bf215546Sopenharmony_ci   const struct radv_subpass *subpass = cmd_buffer->state.subpass;
776bf215546Sopenharmony_ci   struct radv_subpass_barrier barrier;
777bf215546Sopenharmony_ci   uint32_t layer_count = fb->layers;
778bf215546Sopenharmony_ci
779bf215546Sopenharmony_ci   if (subpass->view_mask)
780bf215546Sopenharmony_ci      layer_count = util_last_bit(subpass->view_mask);
781bf215546Sopenharmony_ci
782bf215546Sopenharmony_ci   /* Resolves happen before the end-of-subpass barriers get executed, so
783bf215546Sopenharmony_ci    * we have to make the attachment shader-readable.
784bf215546Sopenharmony_ci    */
785bf215546Sopenharmony_ci   barrier.src_stage_mask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
786bf215546Sopenharmony_ci   barrier.src_access_mask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
787bf215546Sopenharmony_ci   barrier.dst_access_mask = VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT;
788bf215546Sopenharmony_ci   radv_emit_subpass_barrier(cmd_buffer, &barrier);
789bf215546Sopenharmony_ci
790bf215546Sopenharmony_ci   for (uint32_t i = 0; i < subpass->color_count; ++i) {
791bf215546Sopenharmony_ci      struct radv_subpass_attachment src_att = subpass->color_attachments[i];
792bf215546Sopenharmony_ci      struct radv_subpass_attachment dst_att = subpass->resolve_attachments[i];
793bf215546Sopenharmony_ci
794bf215546Sopenharmony_ci      if (dst_att.attachment == VK_ATTACHMENT_UNUSED)
795bf215546Sopenharmony_ci         continue;
796bf215546Sopenharmony_ci
797bf215546Sopenharmony_ci      struct radv_image_view *src_iview = cmd_buffer->state.attachments[src_att.attachment].iview;
798bf215546Sopenharmony_ci      struct radv_image_view *dst_iview = cmd_buffer->state.attachments[dst_att.attachment].iview;
799bf215546Sopenharmony_ci
800bf215546Sopenharmony_ci      VkImageResolve2 region = {
801bf215546Sopenharmony_ci         .sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2,
802bf215546Sopenharmony_ci         .extent = (VkExtent3D){fb->width, fb->height, 1},
803bf215546Sopenharmony_ci         .srcSubresource =
804bf215546Sopenharmony_ci            (VkImageSubresourceLayers){
805bf215546Sopenharmony_ci               .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
806bf215546Sopenharmony_ci               .mipLevel = src_iview->vk.base_mip_level,
807bf215546Sopenharmony_ci               .baseArrayLayer = src_iview->vk.base_array_layer,
808bf215546Sopenharmony_ci               .layerCount = layer_count,
809bf215546Sopenharmony_ci            },
810bf215546Sopenharmony_ci         .dstSubresource =
811bf215546Sopenharmony_ci            (VkImageSubresourceLayers){
812bf215546Sopenharmony_ci               .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
813bf215546Sopenharmony_ci               .mipLevel = dst_iview->vk.base_mip_level,
814bf215546Sopenharmony_ci               .baseArrayLayer = dst_iview->vk.base_array_layer,
815bf215546Sopenharmony_ci               .layerCount = layer_count,
816bf215546Sopenharmony_ci            },
817bf215546Sopenharmony_ci         .srcOffset = (VkOffset3D){0, 0, 0},
818bf215546Sopenharmony_ci         .dstOffset = (VkOffset3D){0, 0, 0},
819bf215546Sopenharmony_ci      };
820bf215546Sopenharmony_ci
821bf215546Sopenharmony_ci      radv_meta_resolve_compute_image(cmd_buffer, src_iview->image, src_iview->vk.format,
822bf215546Sopenharmony_ci                                      src_att.layout, dst_iview->image, dst_iview->vk.format,
823bf215546Sopenharmony_ci                                      dst_att.layout, &region);
824bf215546Sopenharmony_ci   }
825bf215546Sopenharmony_ci
826bf215546Sopenharmony_ci   cmd_buffer->state.flush_bits |=
827bf215546Sopenharmony_ci      RADV_CMD_FLAG_CS_PARTIAL_FLUSH | RADV_CMD_FLAG_INV_VCACHE |
828bf215546Sopenharmony_ci      radv_src_access_flush(cmd_buffer, VK_ACCESS_2_SHADER_WRITE_BIT, NULL);
829bf215546Sopenharmony_ci}
830bf215546Sopenharmony_ci
831bf215546Sopenharmony_civoid
832bf215546Sopenharmony_ciradv_depth_stencil_resolve_subpass_cs(struct radv_cmd_buffer *cmd_buffer,
833bf215546Sopenharmony_ci                                      VkImageAspectFlags aspects,
834bf215546Sopenharmony_ci                                      VkResolveModeFlagBits resolve_mode)
835bf215546Sopenharmony_ci{
836bf215546Sopenharmony_ci   struct vk_framebuffer *fb = cmd_buffer->state.framebuffer;
837bf215546Sopenharmony_ci   const struct radv_subpass *subpass = cmd_buffer->state.subpass;
838bf215546Sopenharmony_ci   struct radv_meta_saved_state saved_state;
839bf215546Sopenharmony_ci   uint32_t layer_count = fb->layers;
840bf215546Sopenharmony_ci
841bf215546Sopenharmony_ci   if (subpass->view_mask)
842bf215546Sopenharmony_ci      layer_count = util_last_bit(subpass->view_mask);
843bf215546Sopenharmony_ci
844bf215546Sopenharmony_ci   /* Resolves happen before the end-of-subpass barriers get executed, so
845bf215546Sopenharmony_ci    * we have to make the attachment shader-readable.
846bf215546Sopenharmony_ci    */
847bf215546Sopenharmony_ci   cmd_buffer->state.flush_bits |=
848bf215546Sopenharmony_ci      radv_src_access_flush(cmd_buffer, VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, NULL) |
849bf215546Sopenharmony_ci      radv_dst_access_flush(cmd_buffer, VK_ACCESS_2_SHADER_READ_BIT, NULL) |
850bf215546Sopenharmony_ci      radv_dst_access_flush(cmd_buffer, VK_ACCESS_2_SHADER_WRITE_BIT, NULL);
851bf215546Sopenharmony_ci
852bf215546Sopenharmony_ci   struct radv_subpass_attachment src_att = *subpass->depth_stencil_attachment;
853bf215546Sopenharmony_ci   struct radv_image_view *src_iview = cmd_buffer->state.attachments[src_att.attachment].iview;
854bf215546Sopenharmony_ci   struct radv_image *src_image = src_iview->image;
855bf215546Sopenharmony_ci
856bf215546Sopenharmony_ci   VkImageResolve2 region = {0};
857bf215546Sopenharmony_ci   region.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2;
858bf215546Sopenharmony_ci   region.srcSubresource.aspectMask = aspects;
859bf215546Sopenharmony_ci   region.srcSubresource.mipLevel = 0;
860bf215546Sopenharmony_ci   region.srcSubresource.baseArrayLayer = src_iview->vk.base_array_layer;
861bf215546Sopenharmony_ci   region.srcSubresource.layerCount = layer_count;
862bf215546Sopenharmony_ci
863bf215546Sopenharmony_ci   radv_decompress_resolve_src(cmd_buffer, src_image, src_att.layout, &region);
864bf215546Sopenharmony_ci
865bf215546Sopenharmony_ci   radv_meta_save(&saved_state, cmd_buffer,
866bf215546Sopenharmony_ci                  RADV_META_SAVE_COMPUTE_PIPELINE | RADV_META_SAVE_DESCRIPTORS);
867bf215546Sopenharmony_ci
868bf215546Sopenharmony_ci   struct radv_subpass_attachment dest_att = *subpass->ds_resolve_attachment;
869bf215546Sopenharmony_ci   struct radv_image_view *dst_iview = cmd_buffer->state.attachments[dest_att.attachment].iview;
870bf215546Sopenharmony_ci   struct radv_image *dst_image = dst_iview->image;
871bf215546Sopenharmony_ci
872bf215546Sopenharmony_ci   struct radv_image_view tsrc_iview;
873bf215546Sopenharmony_ci   radv_image_view_init(&tsrc_iview, cmd_buffer->device,
874bf215546Sopenharmony_ci                        &(VkImageViewCreateInfo){
875bf215546Sopenharmony_ci                           .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
876bf215546Sopenharmony_ci                           .image = radv_image_to_handle(src_image),
877bf215546Sopenharmony_ci                           .viewType = radv_meta_get_view_type(src_image),
878bf215546Sopenharmony_ci                           .format = src_iview->vk.format,
879bf215546Sopenharmony_ci                           .subresourceRange =
880bf215546Sopenharmony_ci                              {
881bf215546Sopenharmony_ci                                 .aspectMask = aspects,
882bf215546Sopenharmony_ci                                 .baseMipLevel = src_iview->vk.base_mip_level,
883bf215546Sopenharmony_ci                                 .levelCount = 1,
884bf215546Sopenharmony_ci                                 .baseArrayLayer = src_iview->vk.base_array_layer,
885bf215546Sopenharmony_ci                                 .layerCount = layer_count,
886bf215546Sopenharmony_ci                              },
887bf215546Sopenharmony_ci                        },
888bf215546Sopenharmony_ci                        0, NULL);
889bf215546Sopenharmony_ci
890bf215546Sopenharmony_ci   struct radv_image_view tdst_iview;
891bf215546Sopenharmony_ci   radv_image_view_init(&tdst_iview, cmd_buffer->device,
892bf215546Sopenharmony_ci                        &(VkImageViewCreateInfo){
893bf215546Sopenharmony_ci                           .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
894bf215546Sopenharmony_ci                           .image = radv_image_to_handle(dst_image),
895bf215546Sopenharmony_ci                           .viewType = radv_meta_get_view_type(dst_image),
896bf215546Sopenharmony_ci                           .format = dst_iview->vk.format,
897bf215546Sopenharmony_ci                           .subresourceRange =
898bf215546Sopenharmony_ci                              {
899bf215546Sopenharmony_ci                                 .aspectMask = aspects,
900bf215546Sopenharmony_ci                                 .baseMipLevel = dst_iview->vk.base_mip_level,
901bf215546Sopenharmony_ci                                 .levelCount = 1,
902bf215546Sopenharmony_ci                                 .baseArrayLayer = dst_iview->vk.base_array_layer,
903bf215546Sopenharmony_ci                                 .layerCount = layer_count,
904bf215546Sopenharmony_ci                              },
905bf215546Sopenharmony_ci                        },
906bf215546Sopenharmony_ci                        0, NULL);
907bf215546Sopenharmony_ci
908bf215546Sopenharmony_ci   emit_depth_stencil_resolve(cmd_buffer, &tsrc_iview, &tdst_iview,
909bf215546Sopenharmony_ci                              &(VkExtent3D){fb->width, fb->height, layer_count}, aspects,
910bf215546Sopenharmony_ci                              resolve_mode);
911bf215546Sopenharmony_ci
912bf215546Sopenharmony_ci   cmd_buffer->state.flush_bits |=
913bf215546Sopenharmony_ci      RADV_CMD_FLAG_CS_PARTIAL_FLUSH | RADV_CMD_FLAG_INV_VCACHE |
914bf215546Sopenharmony_ci      radv_src_access_flush(cmd_buffer, VK_ACCESS_2_SHADER_WRITE_BIT, NULL);
915bf215546Sopenharmony_ci
916bf215546Sopenharmony_ci   VkImageLayout layout = cmd_buffer->state.attachments[dest_att.attachment].current_layout;
917bf215546Sopenharmony_ci   uint32_t queue_mask = radv_image_queue_family_mask(dst_image, cmd_buffer->qf,
918bf215546Sopenharmony_ci                                                      cmd_buffer->qf);
919bf215546Sopenharmony_ci
920bf215546Sopenharmony_ci   if (radv_layout_is_htile_compressed(cmd_buffer->device, dst_image, layout, false, queue_mask)) {
921bf215546Sopenharmony_ci      VkImageSubresourceRange range = {0};
922bf215546Sopenharmony_ci      range.aspectMask = aspects;
923bf215546Sopenharmony_ci      range.baseMipLevel = dst_iview->vk.base_mip_level;
924bf215546Sopenharmony_ci      range.levelCount = 1;
925bf215546Sopenharmony_ci      range.baseArrayLayer = dst_iview->vk.base_array_layer;
926bf215546Sopenharmony_ci      range.layerCount = layer_count;
927bf215546Sopenharmony_ci
928bf215546Sopenharmony_ci      uint32_t htile_value = radv_get_htile_initial_value(cmd_buffer->device, dst_image);
929bf215546Sopenharmony_ci
930bf215546Sopenharmony_ci      cmd_buffer->state.flush_bits |= radv_clear_htile(cmd_buffer, dst_image, &range, htile_value);
931bf215546Sopenharmony_ci   }
932bf215546Sopenharmony_ci
933bf215546Sopenharmony_ci   radv_image_view_finish(&tsrc_iview);
934bf215546Sopenharmony_ci   radv_image_view_finish(&tdst_iview);
935bf215546Sopenharmony_ci
936bf215546Sopenharmony_ci   radv_meta_restore(&saved_state, cmd_buffer);
937bf215546Sopenharmony_ci}
938