1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2016 Red Hat.
3bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen
4bf215546Sopenharmony_ci *
5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
11bf215546Sopenharmony_ci *
12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
14bf215546Sopenharmony_ci * Software.
15bf215546Sopenharmony_ci *
16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22bf215546Sopenharmony_ci * IN THE SOFTWARE.
23bf215546Sopenharmony_ci */
24bf215546Sopenharmony_ci#include "nir/nir_builder.h"
25bf215546Sopenharmony_ci#include "radv_meta.h"
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci/*
28bf215546Sopenharmony_ci * GFX queue: Compute shader implementation of image->buffer copy
29bf215546Sopenharmony_ci * Compute queue: implementation also of buffer->image, image->image, and image clear.
30bf215546Sopenharmony_ci */
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_cistatic nir_shader *
33bf215546Sopenharmony_cibuild_nir_itob_compute_shader(struct radv_device *dev, bool is_3d)
34bf215546Sopenharmony_ci{
35bf215546Sopenharmony_ci   enum glsl_sampler_dim dim = is_3d ? GLSL_SAMPLER_DIM_3D : GLSL_SAMPLER_DIM_2D;
36bf215546Sopenharmony_ci   const struct glsl_type *sampler_type = glsl_sampler_type(dim, false, false, GLSL_TYPE_FLOAT);
37bf215546Sopenharmony_ci   const struct glsl_type *img_type = glsl_image_type(GLSL_SAMPLER_DIM_BUF, false, GLSL_TYPE_FLOAT);
38bf215546Sopenharmony_ci   nir_builder b =
39bf215546Sopenharmony_ci      radv_meta_init_shader(dev, MESA_SHADER_COMPUTE, is_3d ? "meta_itob_cs_3d" : "meta_itob_cs");
40bf215546Sopenharmony_ci   b.shader->info.workgroup_size[0] = 8;
41bf215546Sopenharmony_ci   b.shader->info.workgroup_size[1] = 8;
42bf215546Sopenharmony_ci   nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex");
43bf215546Sopenharmony_ci   input_img->data.descriptor_set = 0;
44bf215546Sopenharmony_ci   input_img->data.binding = 0;
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_ci   nir_variable *output_img = nir_variable_create(b.shader, nir_var_image, img_type, "out_img");
47bf215546Sopenharmony_ci   output_img->data.descriptor_set = 0;
48bf215546Sopenharmony_ci   output_img->data.binding = 1;
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_ci   nir_ssa_def *global_id = get_global_ids(&b, is_3d ? 3 : 2);
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_ci   nir_ssa_def *offset =
53bf215546Sopenharmony_ci      nir_load_push_constant(&b, is_3d ? 3 : 2, 32, nir_imm_int(&b, 0), .range = is_3d ? 12 : 8);
54bf215546Sopenharmony_ci   nir_ssa_def *stride = nir_load_push_constant(&b, 1, 32, nir_imm_int(&b, 12), .range = 16);
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_ci   nir_ssa_def *img_coord = nir_iadd(&b, global_id, offset);
57bf215546Sopenharmony_ci   nir_ssa_def *input_img_deref = &nir_build_deref_var(&b, input_img)->dest.ssa;
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_ci   nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3);
60bf215546Sopenharmony_ci   tex->sampler_dim = dim;
61bf215546Sopenharmony_ci   tex->op = nir_texop_txf;
62bf215546Sopenharmony_ci   tex->src[0].src_type = nir_tex_src_coord;
63bf215546Sopenharmony_ci   tex->src[0].src = nir_src_for_ssa(nir_trim_vector(&b, img_coord, 2 + is_3d));
64bf215546Sopenharmony_ci   tex->src[1].src_type = nir_tex_src_lod;
65bf215546Sopenharmony_ci   tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0));
66bf215546Sopenharmony_ci   tex->src[2].src_type = nir_tex_src_texture_deref;
67bf215546Sopenharmony_ci   tex->src[2].src = nir_src_for_ssa(input_img_deref);
68bf215546Sopenharmony_ci   tex->dest_type = nir_type_float32;
69bf215546Sopenharmony_ci   tex->is_array = false;
70bf215546Sopenharmony_ci   tex->coord_components = is_3d ? 3 : 2;
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_ci   nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
73bf215546Sopenharmony_ci   nir_builder_instr_insert(&b, &tex->instr);
74bf215546Sopenharmony_ci
75bf215546Sopenharmony_ci   nir_ssa_def *pos_x = nir_channel(&b, global_id, 0);
76bf215546Sopenharmony_ci   nir_ssa_def *pos_y = nir_channel(&b, global_id, 1);
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_ci   nir_ssa_def *tmp = nir_imul(&b, pos_y, stride);
79bf215546Sopenharmony_ci   tmp = nir_iadd(&b, tmp, pos_x);
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_ci   nir_ssa_def *coord = nir_vec4(&b, tmp, tmp, tmp, tmp);
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ci   nir_ssa_def *outval = &tex->dest.ssa;
84bf215546Sopenharmony_ci   nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img)->dest.ssa, coord,
85bf215546Sopenharmony_ci                         nir_ssa_undef(&b, 1, 32), outval, nir_imm_int(&b, 0),
86bf215546Sopenharmony_ci                         .image_dim = GLSL_SAMPLER_DIM_BUF);
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_ci   return b.shader;
89bf215546Sopenharmony_ci}
90bf215546Sopenharmony_ci
91bf215546Sopenharmony_ci/* Image to buffer - don't write use image accessors */
92bf215546Sopenharmony_cistatic VkResult
93bf215546Sopenharmony_ciradv_device_init_meta_itob_state(struct radv_device *device)
94bf215546Sopenharmony_ci{
95bf215546Sopenharmony_ci   VkResult result;
96bf215546Sopenharmony_ci   nir_shader *cs = build_nir_itob_compute_shader(device, false);
97bf215546Sopenharmony_ci   nir_shader *cs_3d = build_nir_itob_compute_shader(device, true);
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci   /*
100bf215546Sopenharmony_ci    * two descriptors one for the image being sampled
101bf215546Sopenharmony_ci    * one for the buffer being written.
102bf215546Sopenharmony_ci    */
103bf215546Sopenharmony_ci   VkDescriptorSetLayoutCreateInfo ds_create_info = {
104bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
105bf215546Sopenharmony_ci      .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
106bf215546Sopenharmony_ci      .bindingCount = 2,
107bf215546Sopenharmony_ci      .pBindings = (VkDescriptorSetLayoutBinding[]){
108bf215546Sopenharmony_ci         {.binding = 0,
109bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
110bf215546Sopenharmony_ci          .descriptorCount = 1,
111bf215546Sopenharmony_ci          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
112bf215546Sopenharmony_ci          .pImmutableSamplers = NULL},
113bf215546Sopenharmony_ci         {.binding = 1,
114bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
115bf215546Sopenharmony_ci          .descriptorCount = 1,
116bf215546Sopenharmony_ci          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
117bf215546Sopenharmony_ci          .pImmutableSamplers = NULL},
118bf215546Sopenharmony_ci      }};
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_ci   result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &ds_create_info,
121bf215546Sopenharmony_ci                                           &device->meta_state.alloc,
122bf215546Sopenharmony_ci                                           &device->meta_state.itob.img_ds_layout);
123bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
124bf215546Sopenharmony_ci      goto fail;
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_ci   VkPipelineLayoutCreateInfo pl_create_info = {
127bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
128bf215546Sopenharmony_ci      .setLayoutCount = 1,
129bf215546Sopenharmony_ci      .pSetLayouts = &device->meta_state.itob.img_ds_layout,
130bf215546Sopenharmony_ci      .pushConstantRangeCount = 1,
131bf215546Sopenharmony_ci      .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_COMPUTE_BIT, 0, 16},
132bf215546Sopenharmony_ci   };
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_ci   result =
135bf215546Sopenharmony_ci      radv_CreatePipelineLayout(radv_device_to_handle(device), &pl_create_info,
136bf215546Sopenharmony_ci                                &device->meta_state.alloc, &device->meta_state.itob.img_p_layout);
137bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
138bf215546Sopenharmony_ci      goto fail;
139bf215546Sopenharmony_ci
140bf215546Sopenharmony_ci   /* compute shader */
141bf215546Sopenharmony_ci
142bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
143bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
144bf215546Sopenharmony_ci      .stage = VK_SHADER_STAGE_COMPUTE_BIT,
145bf215546Sopenharmony_ci      .module = vk_shader_module_handle_from_nir(cs),
146bf215546Sopenharmony_ci      .pName = "main",
147bf215546Sopenharmony_ci      .pSpecializationInfo = NULL,
148bf215546Sopenharmony_ci   };
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ci   VkComputePipelineCreateInfo vk_pipeline_info = {
151bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
152bf215546Sopenharmony_ci      .stage = pipeline_shader_stage,
153bf215546Sopenharmony_ci      .flags = 0,
154bf215546Sopenharmony_ci      .layout = device->meta_state.itob.img_p_layout,
155bf215546Sopenharmony_ci   };
156bf215546Sopenharmony_ci
157bf215546Sopenharmony_ci   result = radv_CreateComputePipelines(radv_device_to_handle(device),
158bf215546Sopenharmony_ci                                        radv_pipeline_cache_to_handle(&device->meta_state.cache), 1,
159bf215546Sopenharmony_ci                                        &vk_pipeline_info, NULL, &device->meta_state.itob.pipeline);
160bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
161bf215546Sopenharmony_ci      goto fail;
162bf215546Sopenharmony_ci
163bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stage_3d = {
164bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
165bf215546Sopenharmony_ci      .stage = VK_SHADER_STAGE_COMPUTE_BIT,
166bf215546Sopenharmony_ci      .module = vk_shader_module_handle_from_nir(cs_3d),
167bf215546Sopenharmony_ci      .pName = "main",
168bf215546Sopenharmony_ci      .pSpecializationInfo = NULL,
169bf215546Sopenharmony_ci   };
170bf215546Sopenharmony_ci
171bf215546Sopenharmony_ci   VkComputePipelineCreateInfo vk_pipeline_info_3d = {
172bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
173bf215546Sopenharmony_ci      .stage = pipeline_shader_stage_3d,
174bf215546Sopenharmony_ci      .flags = 0,
175bf215546Sopenharmony_ci      .layout = device->meta_state.itob.img_p_layout,
176bf215546Sopenharmony_ci   };
177bf215546Sopenharmony_ci
178bf215546Sopenharmony_ci   result = radv_CreateComputePipelines(
179bf215546Sopenharmony_ci      radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache), 1,
180bf215546Sopenharmony_ci      &vk_pipeline_info_3d, NULL, &device->meta_state.itob.pipeline_3d);
181bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
182bf215546Sopenharmony_ci      goto fail;
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_ci   ralloc_free(cs_3d);
185bf215546Sopenharmony_ci   ralloc_free(cs);
186bf215546Sopenharmony_ci
187bf215546Sopenharmony_ci   return VK_SUCCESS;
188bf215546Sopenharmony_cifail:
189bf215546Sopenharmony_ci   ralloc_free(cs);
190bf215546Sopenharmony_ci   ralloc_free(cs_3d);
191bf215546Sopenharmony_ci   return result;
192bf215546Sopenharmony_ci}
193bf215546Sopenharmony_ci
194bf215546Sopenharmony_cistatic void
195bf215546Sopenharmony_ciradv_device_finish_meta_itob_state(struct radv_device *device)
196bf215546Sopenharmony_ci{
197bf215546Sopenharmony_ci   struct radv_meta_state *state = &device->meta_state;
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_ci   radv_DestroyPipelineLayout(radv_device_to_handle(device), state->itob.img_p_layout,
200bf215546Sopenharmony_ci                              &state->alloc);
201bf215546Sopenharmony_ci   device->vk.dispatch_table.DestroyDescriptorSetLayout(radv_device_to_handle(device),
202bf215546Sopenharmony_ci                                                        state->itob.img_ds_layout, &state->alloc);
203bf215546Sopenharmony_ci   radv_DestroyPipeline(radv_device_to_handle(device), state->itob.pipeline, &state->alloc);
204bf215546Sopenharmony_ci   radv_DestroyPipeline(radv_device_to_handle(device), state->itob.pipeline_3d, &state->alloc);
205bf215546Sopenharmony_ci}
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_cistatic nir_shader *
208bf215546Sopenharmony_cibuild_nir_btoi_compute_shader(struct radv_device *dev, bool is_3d)
209bf215546Sopenharmony_ci{
210bf215546Sopenharmony_ci   enum glsl_sampler_dim dim = is_3d ? GLSL_SAMPLER_DIM_3D : GLSL_SAMPLER_DIM_2D;
211bf215546Sopenharmony_ci   const struct glsl_type *buf_type =
212bf215546Sopenharmony_ci      glsl_sampler_type(GLSL_SAMPLER_DIM_BUF, false, false, GLSL_TYPE_FLOAT);
213bf215546Sopenharmony_ci   const struct glsl_type *img_type = glsl_image_type(dim, false, GLSL_TYPE_FLOAT);
214bf215546Sopenharmony_ci   nir_builder b =
215bf215546Sopenharmony_ci      radv_meta_init_shader(dev, MESA_SHADER_COMPUTE, is_3d ? "meta_btoi_cs_3d" : "meta_btoi_cs");
216bf215546Sopenharmony_ci   b.shader->info.workgroup_size[0] = 8;
217bf215546Sopenharmony_ci   b.shader->info.workgroup_size[1] = 8;
218bf215546Sopenharmony_ci   nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, buf_type, "s_tex");
219bf215546Sopenharmony_ci   input_img->data.descriptor_set = 0;
220bf215546Sopenharmony_ci   input_img->data.binding = 0;
221bf215546Sopenharmony_ci
222bf215546Sopenharmony_ci   nir_variable *output_img = nir_variable_create(b.shader, nir_var_image, img_type, "out_img");
223bf215546Sopenharmony_ci   output_img->data.descriptor_set = 0;
224bf215546Sopenharmony_ci   output_img->data.binding = 1;
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci   nir_ssa_def *global_id = get_global_ids(&b, is_3d ? 3 : 2);
227bf215546Sopenharmony_ci
228bf215546Sopenharmony_ci   nir_ssa_def *offset =
229bf215546Sopenharmony_ci      nir_load_push_constant(&b, is_3d ? 3 : 2, 32, nir_imm_int(&b, 0), .range = is_3d ? 12 : 8);
230bf215546Sopenharmony_ci   nir_ssa_def *stride = nir_load_push_constant(&b, 1, 32, nir_imm_int(&b, 12), .range = 16);
231bf215546Sopenharmony_ci
232bf215546Sopenharmony_ci   nir_ssa_def *pos_x = nir_channel(&b, global_id, 0);
233bf215546Sopenharmony_ci   nir_ssa_def *pos_y = nir_channel(&b, global_id, 1);
234bf215546Sopenharmony_ci
235bf215546Sopenharmony_ci   nir_ssa_def *buf_coord = nir_imul(&b, pos_y, stride);
236bf215546Sopenharmony_ci   buf_coord = nir_iadd(&b, buf_coord, pos_x);
237bf215546Sopenharmony_ci
238bf215546Sopenharmony_ci   nir_ssa_def *coord = nir_iadd(&b, global_id, offset);
239bf215546Sopenharmony_ci   nir_ssa_def *input_img_deref = &nir_build_deref_var(&b, input_img)->dest.ssa;
240bf215546Sopenharmony_ci
241bf215546Sopenharmony_ci   nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3);
242bf215546Sopenharmony_ci   tex->sampler_dim = GLSL_SAMPLER_DIM_BUF;
243bf215546Sopenharmony_ci   tex->op = nir_texop_txf;
244bf215546Sopenharmony_ci   tex->src[0].src_type = nir_tex_src_coord;
245bf215546Sopenharmony_ci   tex->src[0].src = nir_src_for_ssa(buf_coord);
246bf215546Sopenharmony_ci   tex->src[1].src_type = nir_tex_src_lod;
247bf215546Sopenharmony_ci   tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0));
248bf215546Sopenharmony_ci   tex->src[2].src_type = nir_tex_src_texture_deref;
249bf215546Sopenharmony_ci   tex->src[2].src = nir_src_for_ssa(input_img_deref);
250bf215546Sopenharmony_ci   tex->dest_type = nir_type_float32;
251bf215546Sopenharmony_ci   tex->is_array = false;
252bf215546Sopenharmony_ci   tex->coord_components = 1;
253bf215546Sopenharmony_ci
254bf215546Sopenharmony_ci   nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
255bf215546Sopenharmony_ci   nir_builder_instr_insert(&b, &tex->instr);
256bf215546Sopenharmony_ci
257bf215546Sopenharmony_ci   nir_ssa_def *outval = &tex->dest.ssa;
258bf215546Sopenharmony_ci
259bf215546Sopenharmony_ci   nir_ssa_def *img_coord = nir_vec4(&b, nir_channel(&b, coord, 0),
260bf215546Sopenharmony_ci                                         nir_channel(&b, coord, 1),
261bf215546Sopenharmony_ci                                         is_3d ? nir_channel(&b, coord, 2) : nir_ssa_undef(&b, 1, 32),
262bf215546Sopenharmony_ci                                         nir_ssa_undef(&b, 1, 32));
263bf215546Sopenharmony_ci
264bf215546Sopenharmony_ci   nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img)->dest.ssa, img_coord,
265bf215546Sopenharmony_ci                         nir_ssa_undef(&b, 1, 32), outval, nir_imm_int(&b, 0), .image_dim = dim);
266bf215546Sopenharmony_ci
267bf215546Sopenharmony_ci   return b.shader;
268bf215546Sopenharmony_ci}
269bf215546Sopenharmony_ci
270bf215546Sopenharmony_ci/* Buffer to image - don't write use image accessors */
271bf215546Sopenharmony_cistatic VkResult
272bf215546Sopenharmony_ciradv_device_init_meta_btoi_state(struct radv_device *device)
273bf215546Sopenharmony_ci{
274bf215546Sopenharmony_ci   VkResult result;
275bf215546Sopenharmony_ci   nir_shader *cs = build_nir_btoi_compute_shader(device, false);
276bf215546Sopenharmony_ci   nir_shader *cs_3d = build_nir_btoi_compute_shader(device, true);
277bf215546Sopenharmony_ci   /*
278bf215546Sopenharmony_ci    * two descriptors one for the image being sampled
279bf215546Sopenharmony_ci    * one for the buffer being written.
280bf215546Sopenharmony_ci    */
281bf215546Sopenharmony_ci   VkDescriptorSetLayoutCreateInfo ds_create_info = {
282bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
283bf215546Sopenharmony_ci      .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
284bf215546Sopenharmony_ci      .bindingCount = 2,
285bf215546Sopenharmony_ci      .pBindings = (VkDescriptorSetLayoutBinding[]){
286bf215546Sopenharmony_ci         {.binding = 0,
287bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
288bf215546Sopenharmony_ci          .descriptorCount = 1,
289bf215546Sopenharmony_ci          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
290bf215546Sopenharmony_ci          .pImmutableSamplers = NULL},
291bf215546Sopenharmony_ci         {.binding = 1,
292bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
293bf215546Sopenharmony_ci          .descriptorCount = 1,
294bf215546Sopenharmony_ci          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
295bf215546Sopenharmony_ci          .pImmutableSamplers = NULL},
296bf215546Sopenharmony_ci      }};
297bf215546Sopenharmony_ci
298bf215546Sopenharmony_ci   result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &ds_create_info,
299bf215546Sopenharmony_ci                                           &device->meta_state.alloc,
300bf215546Sopenharmony_ci                                           &device->meta_state.btoi.img_ds_layout);
301bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
302bf215546Sopenharmony_ci      goto fail;
303bf215546Sopenharmony_ci
304bf215546Sopenharmony_ci   VkPipelineLayoutCreateInfo pl_create_info = {
305bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
306bf215546Sopenharmony_ci      .setLayoutCount = 1,
307bf215546Sopenharmony_ci      .pSetLayouts = &device->meta_state.btoi.img_ds_layout,
308bf215546Sopenharmony_ci      .pushConstantRangeCount = 1,
309bf215546Sopenharmony_ci      .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_COMPUTE_BIT, 0, 16},
310bf215546Sopenharmony_ci   };
311bf215546Sopenharmony_ci
312bf215546Sopenharmony_ci   result =
313bf215546Sopenharmony_ci      radv_CreatePipelineLayout(radv_device_to_handle(device), &pl_create_info,
314bf215546Sopenharmony_ci                                &device->meta_state.alloc, &device->meta_state.btoi.img_p_layout);
315bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
316bf215546Sopenharmony_ci      goto fail;
317bf215546Sopenharmony_ci
318bf215546Sopenharmony_ci   /* compute shader */
319bf215546Sopenharmony_ci
320bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
321bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
322bf215546Sopenharmony_ci      .stage = VK_SHADER_STAGE_COMPUTE_BIT,
323bf215546Sopenharmony_ci      .module = vk_shader_module_handle_from_nir(cs),
324bf215546Sopenharmony_ci      .pName = "main",
325bf215546Sopenharmony_ci      .pSpecializationInfo = NULL,
326bf215546Sopenharmony_ci   };
327bf215546Sopenharmony_ci
328bf215546Sopenharmony_ci   VkComputePipelineCreateInfo vk_pipeline_info = {
329bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
330bf215546Sopenharmony_ci      .stage = pipeline_shader_stage,
331bf215546Sopenharmony_ci      .flags = 0,
332bf215546Sopenharmony_ci      .layout = device->meta_state.btoi.img_p_layout,
333bf215546Sopenharmony_ci   };
334bf215546Sopenharmony_ci
335bf215546Sopenharmony_ci   result = radv_CreateComputePipelines(radv_device_to_handle(device),
336bf215546Sopenharmony_ci                                        radv_pipeline_cache_to_handle(&device->meta_state.cache), 1,
337bf215546Sopenharmony_ci                                        &vk_pipeline_info, NULL, &device->meta_state.btoi.pipeline);
338bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
339bf215546Sopenharmony_ci      goto fail;
340bf215546Sopenharmony_ci
341bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stage_3d = {
342bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
343bf215546Sopenharmony_ci      .stage = VK_SHADER_STAGE_COMPUTE_BIT,
344bf215546Sopenharmony_ci      .module = vk_shader_module_handle_from_nir(cs_3d),
345bf215546Sopenharmony_ci      .pName = "main",
346bf215546Sopenharmony_ci      .pSpecializationInfo = NULL,
347bf215546Sopenharmony_ci   };
348bf215546Sopenharmony_ci
349bf215546Sopenharmony_ci   VkComputePipelineCreateInfo vk_pipeline_info_3d = {
350bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
351bf215546Sopenharmony_ci      .stage = pipeline_shader_stage_3d,
352bf215546Sopenharmony_ci      .flags = 0,
353bf215546Sopenharmony_ci      .layout = device->meta_state.btoi.img_p_layout,
354bf215546Sopenharmony_ci   };
355bf215546Sopenharmony_ci
356bf215546Sopenharmony_ci   result = radv_CreateComputePipelines(
357bf215546Sopenharmony_ci      radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache), 1,
358bf215546Sopenharmony_ci      &vk_pipeline_info_3d, NULL, &device->meta_state.btoi.pipeline_3d);
359bf215546Sopenharmony_ci
360bf215546Sopenharmony_ci   ralloc_free(cs_3d);
361bf215546Sopenharmony_ci   ralloc_free(cs);
362bf215546Sopenharmony_ci
363bf215546Sopenharmony_ci   return VK_SUCCESS;
364bf215546Sopenharmony_cifail:
365bf215546Sopenharmony_ci   ralloc_free(cs_3d);
366bf215546Sopenharmony_ci   ralloc_free(cs);
367bf215546Sopenharmony_ci   return result;
368bf215546Sopenharmony_ci}
369bf215546Sopenharmony_ci
370bf215546Sopenharmony_cistatic void
371bf215546Sopenharmony_ciradv_device_finish_meta_btoi_state(struct radv_device *device)
372bf215546Sopenharmony_ci{
373bf215546Sopenharmony_ci   struct radv_meta_state *state = &device->meta_state;
374bf215546Sopenharmony_ci
375bf215546Sopenharmony_ci   radv_DestroyPipelineLayout(radv_device_to_handle(device), state->btoi.img_p_layout,
376bf215546Sopenharmony_ci                              &state->alloc);
377bf215546Sopenharmony_ci   device->vk.dispatch_table.DestroyDescriptorSetLayout(radv_device_to_handle(device),
378bf215546Sopenharmony_ci                                                        state->btoi.img_ds_layout, &state->alloc);
379bf215546Sopenharmony_ci   radv_DestroyPipeline(radv_device_to_handle(device), state->btoi.pipeline, &state->alloc);
380bf215546Sopenharmony_ci   radv_DestroyPipeline(radv_device_to_handle(device), state->btoi.pipeline_3d, &state->alloc);
381bf215546Sopenharmony_ci}
382bf215546Sopenharmony_ci
383bf215546Sopenharmony_ci/* Buffer to image - special path for R32G32B32 */
384bf215546Sopenharmony_cistatic nir_shader *
385bf215546Sopenharmony_cibuild_nir_btoi_r32g32b32_compute_shader(struct radv_device *dev)
386bf215546Sopenharmony_ci{
387bf215546Sopenharmony_ci   const struct glsl_type *buf_type =
388bf215546Sopenharmony_ci      glsl_sampler_type(GLSL_SAMPLER_DIM_BUF, false, false, GLSL_TYPE_FLOAT);
389bf215546Sopenharmony_ci   const struct glsl_type *img_type = glsl_image_type(GLSL_SAMPLER_DIM_BUF, false, GLSL_TYPE_FLOAT);
390bf215546Sopenharmony_ci   nir_builder b = radv_meta_init_shader(dev, MESA_SHADER_COMPUTE, "meta_btoi_r32g32b32_cs");
391bf215546Sopenharmony_ci   b.shader->info.workgroup_size[0] = 8;
392bf215546Sopenharmony_ci   b.shader->info.workgroup_size[1] = 8;
393bf215546Sopenharmony_ci   nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, buf_type, "s_tex");
394bf215546Sopenharmony_ci   input_img->data.descriptor_set = 0;
395bf215546Sopenharmony_ci   input_img->data.binding = 0;
396bf215546Sopenharmony_ci
397bf215546Sopenharmony_ci   nir_variable *output_img = nir_variable_create(b.shader, nir_var_image, img_type, "out_img");
398bf215546Sopenharmony_ci   output_img->data.descriptor_set = 0;
399bf215546Sopenharmony_ci   output_img->data.binding = 1;
400bf215546Sopenharmony_ci
401bf215546Sopenharmony_ci   nir_ssa_def *global_id = get_global_ids(&b, 2);
402bf215546Sopenharmony_ci
403bf215546Sopenharmony_ci   nir_ssa_def *offset = nir_load_push_constant(&b, 2, 32, nir_imm_int(&b, 0), .range = 8);
404bf215546Sopenharmony_ci   nir_ssa_def *pitch = nir_load_push_constant(&b, 1, 32, nir_imm_int(&b, 8), .range = 12);
405bf215546Sopenharmony_ci   nir_ssa_def *stride = nir_load_push_constant(&b, 1, 32, nir_imm_int(&b, 12), .range = 16);
406bf215546Sopenharmony_ci
407bf215546Sopenharmony_ci   nir_ssa_def *pos_x = nir_channel(&b, global_id, 0);
408bf215546Sopenharmony_ci   nir_ssa_def *pos_y = nir_channel(&b, global_id, 1);
409bf215546Sopenharmony_ci
410bf215546Sopenharmony_ci   nir_ssa_def *buf_coord = nir_imul(&b, pos_y, stride);
411bf215546Sopenharmony_ci   buf_coord = nir_iadd(&b, buf_coord, pos_x);
412bf215546Sopenharmony_ci
413bf215546Sopenharmony_ci   nir_ssa_def *img_coord = nir_iadd(&b, global_id, offset);
414bf215546Sopenharmony_ci
415bf215546Sopenharmony_ci   nir_ssa_def *global_pos = nir_iadd(&b, nir_imul(&b, nir_channel(&b, img_coord, 1), pitch),
416bf215546Sopenharmony_ci                                      nir_imul_imm(&b, nir_channel(&b, img_coord, 0), 3));
417bf215546Sopenharmony_ci
418bf215546Sopenharmony_ci   nir_ssa_def *input_img_deref = &nir_build_deref_var(&b, input_img)->dest.ssa;
419bf215546Sopenharmony_ci
420bf215546Sopenharmony_ci   nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3);
421bf215546Sopenharmony_ci   tex->sampler_dim = GLSL_SAMPLER_DIM_BUF;
422bf215546Sopenharmony_ci   tex->op = nir_texop_txf;
423bf215546Sopenharmony_ci   tex->src[0].src_type = nir_tex_src_coord;
424bf215546Sopenharmony_ci   tex->src[0].src = nir_src_for_ssa(buf_coord);
425bf215546Sopenharmony_ci   tex->src[1].src_type = nir_tex_src_lod;
426bf215546Sopenharmony_ci   tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0));
427bf215546Sopenharmony_ci   tex->src[2].src_type = nir_tex_src_texture_deref;
428bf215546Sopenharmony_ci   tex->src[2].src = nir_src_for_ssa(input_img_deref);
429bf215546Sopenharmony_ci   tex->dest_type = nir_type_float32;
430bf215546Sopenharmony_ci   tex->is_array = false;
431bf215546Sopenharmony_ci   tex->coord_components = 1;
432bf215546Sopenharmony_ci   nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
433bf215546Sopenharmony_ci   nir_builder_instr_insert(&b, &tex->instr);
434bf215546Sopenharmony_ci
435bf215546Sopenharmony_ci   nir_ssa_def *outval = &tex->dest.ssa;
436bf215546Sopenharmony_ci
437bf215546Sopenharmony_ci   for (int chan = 0; chan < 3; chan++) {
438bf215546Sopenharmony_ci      nir_ssa_def *local_pos = nir_iadd_imm(&b, global_pos, chan);
439bf215546Sopenharmony_ci
440bf215546Sopenharmony_ci      nir_ssa_def *coord = nir_vec4(&b, local_pos, local_pos, local_pos, local_pos);
441bf215546Sopenharmony_ci
442bf215546Sopenharmony_ci      nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img)->dest.ssa, coord,
443bf215546Sopenharmony_ci                            nir_ssa_undef(&b, 1, 32), nir_channel(&b, outval, chan),
444bf215546Sopenharmony_ci                            nir_imm_int(&b, 0), .image_dim = GLSL_SAMPLER_DIM_BUF);
445bf215546Sopenharmony_ci   }
446bf215546Sopenharmony_ci
447bf215546Sopenharmony_ci   return b.shader;
448bf215546Sopenharmony_ci}
449bf215546Sopenharmony_ci
450bf215546Sopenharmony_cistatic VkResult
451bf215546Sopenharmony_ciradv_device_init_meta_btoi_r32g32b32_state(struct radv_device *device)
452bf215546Sopenharmony_ci{
453bf215546Sopenharmony_ci   VkResult result;
454bf215546Sopenharmony_ci   nir_shader *cs = build_nir_btoi_r32g32b32_compute_shader(device);
455bf215546Sopenharmony_ci
456bf215546Sopenharmony_ci   VkDescriptorSetLayoutCreateInfo ds_create_info = {
457bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
458bf215546Sopenharmony_ci      .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
459bf215546Sopenharmony_ci      .bindingCount = 2,
460bf215546Sopenharmony_ci      .pBindings = (VkDescriptorSetLayoutBinding[]){
461bf215546Sopenharmony_ci         {.binding = 0,
462bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
463bf215546Sopenharmony_ci          .descriptorCount = 1,
464bf215546Sopenharmony_ci          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
465bf215546Sopenharmony_ci          .pImmutableSamplers = NULL},
466bf215546Sopenharmony_ci         {.binding = 1,
467bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
468bf215546Sopenharmony_ci          .descriptorCount = 1,
469bf215546Sopenharmony_ci          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
470bf215546Sopenharmony_ci          .pImmutableSamplers = NULL},
471bf215546Sopenharmony_ci      }};
472bf215546Sopenharmony_ci
473bf215546Sopenharmony_ci   result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &ds_create_info,
474bf215546Sopenharmony_ci                                           &device->meta_state.alloc,
475bf215546Sopenharmony_ci                                           &device->meta_state.btoi_r32g32b32.img_ds_layout);
476bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
477bf215546Sopenharmony_ci      goto fail;
478bf215546Sopenharmony_ci
479bf215546Sopenharmony_ci   VkPipelineLayoutCreateInfo pl_create_info = {
480bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
481bf215546Sopenharmony_ci      .setLayoutCount = 1,
482bf215546Sopenharmony_ci      .pSetLayouts = &device->meta_state.btoi_r32g32b32.img_ds_layout,
483bf215546Sopenharmony_ci      .pushConstantRangeCount = 1,
484bf215546Sopenharmony_ci      .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_COMPUTE_BIT, 0, 16},
485bf215546Sopenharmony_ci   };
486bf215546Sopenharmony_ci
487bf215546Sopenharmony_ci   result = radv_CreatePipelineLayout(radv_device_to_handle(device), &pl_create_info,
488bf215546Sopenharmony_ci                                      &device->meta_state.alloc,
489bf215546Sopenharmony_ci                                      &device->meta_state.btoi_r32g32b32.img_p_layout);
490bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
491bf215546Sopenharmony_ci      goto fail;
492bf215546Sopenharmony_ci
493bf215546Sopenharmony_ci   /* compute shader */
494bf215546Sopenharmony_ci
495bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
496bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
497bf215546Sopenharmony_ci      .stage = VK_SHADER_STAGE_COMPUTE_BIT,
498bf215546Sopenharmony_ci      .module = vk_shader_module_handle_from_nir(cs),
499bf215546Sopenharmony_ci      .pName = "main",
500bf215546Sopenharmony_ci      .pSpecializationInfo = NULL,
501bf215546Sopenharmony_ci   };
502bf215546Sopenharmony_ci
503bf215546Sopenharmony_ci   VkComputePipelineCreateInfo vk_pipeline_info = {
504bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
505bf215546Sopenharmony_ci      .stage = pipeline_shader_stage,
506bf215546Sopenharmony_ci      .flags = 0,
507bf215546Sopenharmony_ci      .layout = device->meta_state.btoi_r32g32b32.img_p_layout,
508bf215546Sopenharmony_ci   };
509bf215546Sopenharmony_ci
510bf215546Sopenharmony_ci   result = radv_CreateComputePipelines(
511bf215546Sopenharmony_ci      radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache), 1,
512bf215546Sopenharmony_ci      &vk_pipeline_info, NULL, &device->meta_state.btoi_r32g32b32.pipeline);
513bf215546Sopenharmony_ci
514bf215546Sopenharmony_cifail:
515bf215546Sopenharmony_ci   ralloc_free(cs);
516bf215546Sopenharmony_ci   return result;
517bf215546Sopenharmony_ci}
518bf215546Sopenharmony_ci
519bf215546Sopenharmony_cistatic void
520bf215546Sopenharmony_ciradv_device_finish_meta_btoi_r32g32b32_state(struct radv_device *device)
521bf215546Sopenharmony_ci{
522bf215546Sopenharmony_ci   struct radv_meta_state *state = &device->meta_state;
523bf215546Sopenharmony_ci
524bf215546Sopenharmony_ci   radv_DestroyPipelineLayout(radv_device_to_handle(device), state->btoi_r32g32b32.img_p_layout,
525bf215546Sopenharmony_ci                              &state->alloc);
526bf215546Sopenharmony_ci   device->vk.dispatch_table.DestroyDescriptorSetLayout(
527bf215546Sopenharmony_ci      radv_device_to_handle(device), state->btoi_r32g32b32.img_ds_layout, &state->alloc);
528bf215546Sopenharmony_ci   radv_DestroyPipeline(radv_device_to_handle(device), state->btoi_r32g32b32.pipeline,
529bf215546Sopenharmony_ci                        &state->alloc);
530bf215546Sopenharmony_ci}
531bf215546Sopenharmony_ci
532bf215546Sopenharmony_cistatic nir_shader *
533bf215546Sopenharmony_cibuild_nir_itoi_compute_shader(struct radv_device *dev, bool is_3d, int samples)
534bf215546Sopenharmony_ci{
535bf215546Sopenharmony_ci   bool is_multisampled = samples > 1;
536bf215546Sopenharmony_ci   enum glsl_sampler_dim dim = is_3d             ? GLSL_SAMPLER_DIM_3D
537bf215546Sopenharmony_ci                               : is_multisampled ? GLSL_SAMPLER_DIM_MS
538bf215546Sopenharmony_ci                                                 : GLSL_SAMPLER_DIM_2D;
539bf215546Sopenharmony_ci   const struct glsl_type *buf_type = glsl_sampler_type(dim, false, false, GLSL_TYPE_FLOAT);
540bf215546Sopenharmony_ci   const struct glsl_type *img_type = glsl_image_type(dim, false, GLSL_TYPE_FLOAT);
541bf215546Sopenharmony_ci   nir_builder b = radv_meta_init_shader(dev, MESA_SHADER_COMPUTE,
542bf215546Sopenharmony_ci                                         is_3d ? "meta_itoi_cs_3d-%d" : "meta_itoi_cs-%d", samples);
543bf215546Sopenharmony_ci   b.shader->info.workgroup_size[0] = 8;
544bf215546Sopenharmony_ci   b.shader->info.workgroup_size[1] = 8;
545bf215546Sopenharmony_ci   nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, buf_type, "s_tex");
546bf215546Sopenharmony_ci   input_img->data.descriptor_set = 0;
547bf215546Sopenharmony_ci   input_img->data.binding = 0;
548bf215546Sopenharmony_ci
549bf215546Sopenharmony_ci   nir_variable *output_img = nir_variable_create(b.shader, nir_var_image, img_type, "out_img");
550bf215546Sopenharmony_ci   output_img->data.descriptor_set = 0;
551bf215546Sopenharmony_ci   output_img->data.binding = 1;
552bf215546Sopenharmony_ci
553bf215546Sopenharmony_ci   nir_ssa_def *global_id = get_global_ids(&b, is_3d ? 3 : 2);
554bf215546Sopenharmony_ci
555bf215546Sopenharmony_ci   nir_ssa_def *src_offset =
556bf215546Sopenharmony_ci      nir_load_push_constant(&b, is_3d ? 3 : 2, 32, nir_imm_int(&b, 0), .range = is_3d ? 12 : 8);
557bf215546Sopenharmony_ci   nir_ssa_def *dst_offset =
558bf215546Sopenharmony_ci      nir_load_push_constant(&b, is_3d ? 3 : 2, 32, nir_imm_int(&b, 12), .range = is_3d ? 24 : 20);
559bf215546Sopenharmony_ci
560bf215546Sopenharmony_ci   nir_ssa_def *src_coord = nir_iadd(&b, global_id, src_offset);
561bf215546Sopenharmony_ci   nir_ssa_def *input_img_deref = &nir_build_deref_var(&b, input_img)->dest.ssa;
562bf215546Sopenharmony_ci
563bf215546Sopenharmony_ci   nir_ssa_def *dst_coord = nir_iadd(&b, global_id, dst_offset);
564bf215546Sopenharmony_ci
565bf215546Sopenharmony_ci   nir_tex_instr *tex_instr[8];
566bf215546Sopenharmony_ci   for (uint32_t i = 0; i < samples; i++) {
567bf215546Sopenharmony_ci      tex_instr[i] = nir_tex_instr_create(b.shader, is_multisampled ? 4 : 3);
568bf215546Sopenharmony_ci
569bf215546Sopenharmony_ci      nir_tex_instr *tex = tex_instr[i];
570bf215546Sopenharmony_ci      tex->sampler_dim = dim;
571bf215546Sopenharmony_ci      tex->op = is_multisampled ? nir_texop_txf_ms : nir_texop_txf;
572bf215546Sopenharmony_ci      tex->src[0].src_type = nir_tex_src_coord;
573bf215546Sopenharmony_ci      tex->src[0].src = nir_src_for_ssa(nir_trim_vector(&b, src_coord, 2 + is_3d));
574bf215546Sopenharmony_ci      tex->src[1].src_type = nir_tex_src_lod;
575bf215546Sopenharmony_ci      tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0));
576bf215546Sopenharmony_ci      tex->src[2].src_type = nir_tex_src_texture_deref;
577bf215546Sopenharmony_ci      tex->src[2].src = nir_src_for_ssa(input_img_deref);
578bf215546Sopenharmony_ci      if (is_multisampled) {
579bf215546Sopenharmony_ci         tex->src[3].src_type = nir_tex_src_ms_index;
580bf215546Sopenharmony_ci         tex->src[3].src = nir_src_for_ssa(nir_imm_int(&b, i));
581bf215546Sopenharmony_ci      }
582bf215546Sopenharmony_ci      tex->dest_type = nir_type_float32;
583bf215546Sopenharmony_ci      tex->is_array = false;
584bf215546Sopenharmony_ci      tex->coord_components = is_3d ? 3 : 2;
585bf215546Sopenharmony_ci
586bf215546Sopenharmony_ci      nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
587bf215546Sopenharmony_ci      nir_builder_instr_insert(&b, &tex->instr);
588bf215546Sopenharmony_ci   }
589bf215546Sopenharmony_ci
590bf215546Sopenharmony_ci   nir_ssa_def *img_coord = nir_vec4(&b, nir_channel(&b, dst_coord, 0),
591bf215546Sopenharmony_ci                                         nir_channel(&b, dst_coord, 1),
592bf215546Sopenharmony_ci                                         is_3d ? nir_channel(&b, dst_coord, 2) : nir_ssa_undef(&b, 1, 32),
593bf215546Sopenharmony_ci                                         nir_ssa_undef(&b, 1, 32));
594bf215546Sopenharmony_ci
595bf215546Sopenharmony_ci   for (uint32_t i = 0; i < samples; i++) {
596bf215546Sopenharmony_ci      nir_ssa_def *outval = &tex_instr[i]->dest.ssa;
597bf215546Sopenharmony_ci      nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img)->dest.ssa, img_coord,
598bf215546Sopenharmony_ci                            nir_imm_int(&b, i), outval, nir_imm_int(&b, 0), .image_dim = dim);
599bf215546Sopenharmony_ci   }
600bf215546Sopenharmony_ci
601bf215546Sopenharmony_ci   return b.shader;
602bf215546Sopenharmony_ci}
603bf215546Sopenharmony_ci
604bf215546Sopenharmony_cistatic VkResult
605bf215546Sopenharmony_cicreate_itoi_pipeline(struct radv_device *device, int samples, VkPipeline *pipeline)
606bf215546Sopenharmony_ci{
607bf215546Sopenharmony_ci   struct radv_meta_state *state = &device->meta_state;
608bf215546Sopenharmony_ci   nir_shader *cs = build_nir_itoi_compute_shader(device, false, samples);
609bf215546Sopenharmony_ci   VkResult result;
610bf215546Sopenharmony_ci
611bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
612bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
613bf215546Sopenharmony_ci      .stage = VK_SHADER_STAGE_COMPUTE_BIT,
614bf215546Sopenharmony_ci      .module = vk_shader_module_handle_from_nir(cs),
615bf215546Sopenharmony_ci      .pName = "main",
616bf215546Sopenharmony_ci      .pSpecializationInfo = NULL,
617bf215546Sopenharmony_ci   };
618bf215546Sopenharmony_ci
619bf215546Sopenharmony_ci   VkComputePipelineCreateInfo vk_pipeline_info = {
620bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
621bf215546Sopenharmony_ci      .stage = pipeline_shader_stage,
622bf215546Sopenharmony_ci      .flags = 0,
623bf215546Sopenharmony_ci      .layout = state->itoi.img_p_layout,
624bf215546Sopenharmony_ci   };
625bf215546Sopenharmony_ci
626bf215546Sopenharmony_ci   result = radv_CreateComputePipelines(radv_device_to_handle(device),
627bf215546Sopenharmony_ci                                        radv_pipeline_cache_to_handle(&state->cache), 1,
628bf215546Sopenharmony_ci                                        &vk_pipeline_info, NULL, pipeline);
629bf215546Sopenharmony_ci   ralloc_free(cs);
630bf215546Sopenharmony_ci   return result;
631bf215546Sopenharmony_ci}
632bf215546Sopenharmony_ci
633bf215546Sopenharmony_ci/* image to image - don't write use image accessors */
634bf215546Sopenharmony_cistatic VkResult
635bf215546Sopenharmony_ciradv_device_init_meta_itoi_state(struct radv_device *device)
636bf215546Sopenharmony_ci{
637bf215546Sopenharmony_ci   VkResult result;
638bf215546Sopenharmony_ci
639bf215546Sopenharmony_ci   /*
640bf215546Sopenharmony_ci    * two descriptors one for the image being sampled
641bf215546Sopenharmony_ci    * one for the buffer being written.
642bf215546Sopenharmony_ci    */
643bf215546Sopenharmony_ci   VkDescriptorSetLayoutCreateInfo ds_create_info = {
644bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
645bf215546Sopenharmony_ci      .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
646bf215546Sopenharmony_ci      .bindingCount = 2,
647bf215546Sopenharmony_ci      .pBindings = (VkDescriptorSetLayoutBinding[]){
648bf215546Sopenharmony_ci         {.binding = 0,
649bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
650bf215546Sopenharmony_ci          .descriptorCount = 1,
651bf215546Sopenharmony_ci          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
652bf215546Sopenharmony_ci          .pImmutableSamplers = NULL},
653bf215546Sopenharmony_ci         {.binding = 1,
654bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
655bf215546Sopenharmony_ci          .descriptorCount = 1,
656bf215546Sopenharmony_ci          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
657bf215546Sopenharmony_ci          .pImmutableSamplers = NULL},
658bf215546Sopenharmony_ci      }};
659bf215546Sopenharmony_ci
660bf215546Sopenharmony_ci   result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &ds_create_info,
661bf215546Sopenharmony_ci                                           &device->meta_state.alloc,
662bf215546Sopenharmony_ci                                           &device->meta_state.itoi.img_ds_layout);
663bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
664bf215546Sopenharmony_ci      goto fail;
665bf215546Sopenharmony_ci
666bf215546Sopenharmony_ci   VkPipelineLayoutCreateInfo pl_create_info = {
667bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
668bf215546Sopenharmony_ci      .setLayoutCount = 1,
669bf215546Sopenharmony_ci      .pSetLayouts = &device->meta_state.itoi.img_ds_layout,
670bf215546Sopenharmony_ci      .pushConstantRangeCount = 1,
671bf215546Sopenharmony_ci      .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_COMPUTE_BIT, 0, 24},
672bf215546Sopenharmony_ci   };
673bf215546Sopenharmony_ci
674bf215546Sopenharmony_ci   result =
675bf215546Sopenharmony_ci      radv_CreatePipelineLayout(radv_device_to_handle(device), &pl_create_info,
676bf215546Sopenharmony_ci                                &device->meta_state.alloc, &device->meta_state.itoi.img_p_layout);
677bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
678bf215546Sopenharmony_ci      goto fail;
679bf215546Sopenharmony_ci
680bf215546Sopenharmony_ci   for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; i++) {
681bf215546Sopenharmony_ci      uint32_t samples = 1 << i;
682bf215546Sopenharmony_ci      result = create_itoi_pipeline(device, samples, &device->meta_state.itoi.pipeline[i]);
683bf215546Sopenharmony_ci      if (result != VK_SUCCESS)
684bf215546Sopenharmony_ci         goto fail;
685bf215546Sopenharmony_ci   }
686bf215546Sopenharmony_ci
687bf215546Sopenharmony_ci   nir_shader *cs_3d = build_nir_itoi_compute_shader(device, true, 1);
688bf215546Sopenharmony_ci
689bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stage_3d = {
690bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
691bf215546Sopenharmony_ci      .stage = VK_SHADER_STAGE_COMPUTE_BIT,
692bf215546Sopenharmony_ci      .module = vk_shader_module_handle_from_nir(cs_3d),
693bf215546Sopenharmony_ci      .pName = "main",
694bf215546Sopenharmony_ci      .pSpecializationInfo = NULL,
695bf215546Sopenharmony_ci   };
696bf215546Sopenharmony_ci
697bf215546Sopenharmony_ci   VkComputePipelineCreateInfo vk_pipeline_info_3d = {
698bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
699bf215546Sopenharmony_ci      .stage = pipeline_shader_stage_3d,
700bf215546Sopenharmony_ci      .flags = 0,
701bf215546Sopenharmony_ci      .layout = device->meta_state.itoi.img_p_layout,
702bf215546Sopenharmony_ci   };
703bf215546Sopenharmony_ci
704bf215546Sopenharmony_ci   result = radv_CreateComputePipelines(
705bf215546Sopenharmony_ci      radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache), 1,
706bf215546Sopenharmony_ci      &vk_pipeline_info_3d, NULL, &device->meta_state.itoi.pipeline_3d);
707bf215546Sopenharmony_ci   ralloc_free(cs_3d);
708bf215546Sopenharmony_ci
709bf215546Sopenharmony_ci   return VK_SUCCESS;
710bf215546Sopenharmony_cifail:
711bf215546Sopenharmony_ci   return result;
712bf215546Sopenharmony_ci}
713bf215546Sopenharmony_ci
714bf215546Sopenharmony_cistatic void
715bf215546Sopenharmony_ciradv_device_finish_meta_itoi_state(struct radv_device *device)
716bf215546Sopenharmony_ci{
717bf215546Sopenharmony_ci   struct radv_meta_state *state = &device->meta_state;
718bf215546Sopenharmony_ci
719bf215546Sopenharmony_ci   radv_DestroyPipelineLayout(radv_device_to_handle(device), state->itoi.img_p_layout,
720bf215546Sopenharmony_ci                              &state->alloc);
721bf215546Sopenharmony_ci   device->vk.dispatch_table.DestroyDescriptorSetLayout(radv_device_to_handle(device),
722bf215546Sopenharmony_ci                                                        state->itoi.img_ds_layout, &state->alloc);
723bf215546Sopenharmony_ci
724bf215546Sopenharmony_ci   for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; ++i) {
725bf215546Sopenharmony_ci      radv_DestroyPipeline(radv_device_to_handle(device), state->itoi.pipeline[i], &state->alloc);
726bf215546Sopenharmony_ci   }
727bf215546Sopenharmony_ci
728bf215546Sopenharmony_ci   radv_DestroyPipeline(radv_device_to_handle(device), state->itoi.pipeline_3d, &state->alloc);
729bf215546Sopenharmony_ci}
730bf215546Sopenharmony_ci
731bf215546Sopenharmony_cistatic nir_shader *
732bf215546Sopenharmony_cibuild_nir_itoi_r32g32b32_compute_shader(struct radv_device *dev)
733bf215546Sopenharmony_ci{
734bf215546Sopenharmony_ci   const struct glsl_type *type =
735bf215546Sopenharmony_ci      glsl_sampler_type(GLSL_SAMPLER_DIM_BUF, false, false, GLSL_TYPE_FLOAT);
736bf215546Sopenharmony_ci   const struct glsl_type *img_type = glsl_image_type(GLSL_SAMPLER_DIM_BUF, false, GLSL_TYPE_FLOAT);
737bf215546Sopenharmony_ci   nir_builder b = radv_meta_init_shader(dev, MESA_SHADER_COMPUTE, "meta_itoi_r32g32b32_cs");
738bf215546Sopenharmony_ci   b.shader->info.workgroup_size[0] = 8;
739bf215546Sopenharmony_ci   b.shader->info.workgroup_size[1] = 8;
740bf215546Sopenharmony_ci   nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, type, "input_img");
741bf215546Sopenharmony_ci   input_img->data.descriptor_set = 0;
742bf215546Sopenharmony_ci   input_img->data.binding = 0;
743bf215546Sopenharmony_ci
744bf215546Sopenharmony_ci   nir_variable *output_img =
745bf215546Sopenharmony_ci      nir_variable_create(b.shader, nir_var_image, img_type, "output_img");
746bf215546Sopenharmony_ci   output_img->data.descriptor_set = 0;
747bf215546Sopenharmony_ci   output_img->data.binding = 1;
748bf215546Sopenharmony_ci
749bf215546Sopenharmony_ci   nir_ssa_def *global_id = get_global_ids(&b, 2);
750bf215546Sopenharmony_ci
751bf215546Sopenharmony_ci   nir_ssa_def *src_offset = nir_load_push_constant(&b, 3, 32, nir_imm_int(&b, 0), .range = 12);
752bf215546Sopenharmony_ci   nir_ssa_def *dst_offset = nir_load_push_constant(&b, 3, 32, nir_imm_int(&b, 12), .range = 24);
753bf215546Sopenharmony_ci
754bf215546Sopenharmony_ci   nir_ssa_def *src_stride = nir_channel(&b, src_offset, 2);
755bf215546Sopenharmony_ci   nir_ssa_def *dst_stride = nir_channel(&b, dst_offset, 2);
756bf215546Sopenharmony_ci
757bf215546Sopenharmony_ci   nir_ssa_def *src_img_coord = nir_iadd(&b, global_id, src_offset);
758bf215546Sopenharmony_ci   nir_ssa_def *dst_img_coord = nir_iadd(&b, global_id, dst_offset);
759bf215546Sopenharmony_ci
760bf215546Sopenharmony_ci   nir_ssa_def *src_global_pos =
761bf215546Sopenharmony_ci      nir_iadd(&b, nir_imul(&b, nir_channel(&b, src_img_coord, 1), src_stride),
762bf215546Sopenharmony_ci               nir_imul_imm(&b, nir_channel(&b, src_img_coord, 0), 3));
763bf215546Sopenharmony_ci
764bf215546Sopenharmony_ci   nir_ssa_def *dst_global_pos =
765bf215546Sopenharmony_ci      nir_iadd(&b, nir_imul(&b, nir_channel(&b, dst_img_coord, 1), dst_stride),
766bf215546Sopenharmony_ci               nir_imul_imm(&b, nir_channel(&b, dst_img_coord, 0), 3));
767bf215546Sopenharmony_ci
768bf215546Sopenharmony_ci   for (int chan = 0; chan < 3; chan++) {
769bf215546Sopenharmony_ci      /* src */
770bf215546Sopenharmony_ci      nir_ssa_def *src_local_pos = nir_iadd_imm(&b, src_global_pos, chan);
771bf215546Sopenharmony_ci      nir_ssa_def *input_img_deref = &nir_build_deref_var(&b, input_img)->dest.ssa;
772bf215546Sopenharmony_ci
773bf215546Sopenharmony_ci      nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3);
774bf215546Sopenharmony_ci      tex->sampler_dim = GLSL_SAMPLER_DIM_BUF;
775bf215546Sopenharmony_ci      tex->op = nir_texop_txf;
776bf215546Sopenharmony_ci      tex->src[0].src_type = nir_tex_src_coord;
777bf215546Sopenharmony_ci      tex->src[0].src = nir_src_for_ssa(src_local_pos);
778bf215546Sopenharmony_ci      tex->src[1].src_type = nir_tex_src_lod;
779bf215546Sopenharmony_ci      tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0));
780bf215546Sopenharmony_ci      tex->src[2].src_type = nir_tex_src_texture_deref;
781bf215546Sopenharmony_ci      tex->src[2].src = nir_src_for_ssa(input_img_deref);
782bf215546Sopenharmony_ci      tex->dest_type = nir_type_float32;
783bf215546Sopenharmony_ci      tex->is_array = false;
784bf215546Sopenharmony_ci      tex->coord_components = 1;
785bf215546Sopenharmony_ci      nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
786bf215546Sopenharmony_ci      nir_builder_instr_insert(&b, &tex->instr);
787bf215546Sopenharmony_ci
788bf215546Sopenharmony_ci      nir_ssa_def *outval = &tex->dest.ssa;
789bf215546Sopenharmony_ci
790bf215546Sopenharmony_ci      /* dst */
791bf215546Sopenharmony_ci      nir_ssa_def *dst_local_pos = nir_iadd_imm(&b, dst_global_pos, chan);
792bf215546Sopenharmony_ci
793bf215546Sopenharmony_ci      nir_ssa_def *dst_coord =
794bf215546Sopenharmony_ci         nir_vec4(&b, dst_local_pos, dst_local_pos, dst_local_pos, dst_local_pos);
795bf215546Sopenharmony_ci
796bf215546Sopenharmony_ci      nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img)->dest.ssa, dst_coord,
797bf215546Sopenharmony_ci                            nir_ssa_undef(&b, 1, 32), nir_channel(&b, outval, 0),
798bf215546Sopenharmony_ci                            nir_imm_int(&b, 0), .image_dim = GLSL_SAMPLER_DIM_BUF);
799bf215546Sopenharmony_ci   }
800bf215546Sopenharmony_ci
801bf215546Sopenharmony_ci   return b.shader;
802bf215546Sopenharmony_ci}
803bf215546Sopenharmony_ci
804bf215546Sopenharmony_ci/* Image to image - special path for R32G32B32 */
805bf215546Sopenharmony_cistatic VkResult
806bf215546Sopenharmony_ciradv_device_init_meta_itoi_r32g32b32_state(struct radv_device *device)
807bf215546Sopenharmony_ci{
808bf215546Sopenharmony_ci   VkResult result;
809bf215546Sopenharmony_ci   nir_shader *cs = build_nir_itoi_r32g32b32_compute_shader(device);
810bf215546Sopenharmony_ci
811bf215546Sopenharmony_ci   VkDescriptorSetLayoutCreateInfo ds_create_info = {
812bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
813bf215546Sopenharmony_ci      .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
814bf215546Sopenharmony_ci      .bindingCount = 2,
815bf215546Sopenharmony_ci      .pBindings = (VkDescriptorSetLayoutBinding[]){
816bf215546Sopenharmony_ci         {.binding = 0,
817bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
818bf215546Sopenharmony_ci          .descriptorCount = 1,
819bf215546Sopenharmony_ci          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
820bf215546Sopenharmony_ci          .pImmutableSamplers = NULL},
821bf215546Sopenharmony_ci         {.binding = 1,
822bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
823bf215546Sopenharmony_ci          .descriptorCount = 1,
824bf215546Sopenharmony_ci          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
825bf215546Sopenharmony_ci          .pImmutableSamplers = NULL},
826bf215546Sopenharmony_ci      }};
827bf215546Sopenharmony_ci
828bf215546Sopenharmony_ci   result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &ds_create_info,
829bf215546Sopenharmony_ci                                           &device->meta_state.alloc,
830bf215546Sopenharmony_ci                                           &device->meta_state.itoi_r32g32b32.img_ds_layout);
831bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
832bf215546Sopenharmony_ci      goto fail;
833bf215546Sopenharmony_ci
834bf215546Sopenharmony_ci   VkPipelineLayoutCreateInfo pl_create_info = {
835bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
836bf215546Sopenharmony_ci      .setLayoutCount = 1,
837bf215546Sopenharmony_ci      .pSetLayouts = &device->meta_state.itoi_r32g32b32.img_ds_layout,
838bf215546Sopenharmony_ci      .pushConstantRangeCount = 1,
839bf215546Sopenharmony_ci      .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_COMPUTE_BIT, 0, 24},
840bf215546Sopenharmony_ci   };
841bf215546Sopenharmony_ci
842bf215546Sopenharmony_ci   result = radv_CreatePipelineLayout(radv_device_to_handle(device), &pl_create_info,
843bf215546Sopenharmony_ci                                      &device->meta_state.alloc,
844bf215546Sopenharmony_ci                                      &device->meta_state.itoi_r32g32b32.img_p_layout);
845bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
846bf215546Sopenharmony_ci      goto fail;
847bf215546Sopenharmony_ci
848bf215546Sopenharmony_ci   /* compute shader */
849bf215546Sopenharmony_ci
850bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
851bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
852bf215546Sopenharmony_ci      .stage = VK_SHADER_STAGE_COMPUTE_BIT,
853bf215546Sopenharmony_ci      .module = vk_shader_module_handle_from_nir(cs),
854bf215546Sopenharmony_ci      .pName = "main",
855bf215546Sopenharmony_ci      .pSpecializationInfo = NULL,
856bf215546Sopenharmony_ci   };
857bf215546Sopenharmony_ci
858bf215546Sopenharmony_ci   VkComputePipelineCreateInfo vk_pipeline_info = {
859bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
860bf215546Sopenharmony_ci      .stage = pipeline_shader_stage,
861bf215546Sopenharmony_ci      .flags = 0,
862bf215546Sopenharmony_ci      .layout = device->meta_state.itoi_r32g32b32.img_p_layout,
863bf215546Sopenharmony_ci   };
864bf215546Sopenharmony_ci
865bf215546Sopenharmony_ci   result = radv_CreateComputePipelines(
866bf215546Sopenharmony_ci      radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache), 1,
867bf215546Sopenharmony_ci      &vk_pipeline_info, NULL, &device->meta_state.itoi_r32g32b32.pipeline);
868bf215546Sopenharmony_ci
869bf215546Sopenharmony_cifail:
870bf215546Sopenharmony_ci   ralloc_free(cs);
871bf215546Sopenharmony_ci   return result;
872bf215546Sopenharmony_ci}
873bf215546Sopenharmony_ci
874bf215546Sopenharmony_cistatic void
875bf215546Sopenharmony_ciradv_device_finish_meta_itoi_r32g32b32_state(struct radv_device *device)
876bf215546Sopenharmony_ci{
877bf215546Sopenharmony_ci   struct radv_meta_state *state = &device->meta_state;
878bf215546Sopenharmony_ci
879bf215546Sopenharmony_ci   radv_DestroyPipelineLayout(radv_device_to_handle(device), state->itoi_r32g32b32.img_p_layout,
880bf215546Sopenharmony_ci                              &state->alloc);
881bf215546Sopenharmony_ci   device->vk.dispatch_table.DestroyDescriptorSetLayout(
882bf215546Sopenharmony_ci      radv_device_to_handle(device), state->itoi_r32g32b32.img_ds_layout, &state->alloc);
883bf215546Sopenharmony_ci   radv_DestroyPipeline(radv_device_to_handle(device), state->itoi_r32g32b32.pipeline,
884bf215546Sopenharmony_ci                        &state->alloc);
885bf215546Sopenharmony_ci}
886bf215546Sopenharmony_ci
887bf215546Sopenharmony_cistatic nir_shader *
888bf215546Sopenharmony_cibuild_nir_cleari_compute_shader(struct radv_device *dev, bool is_3d, int samples)
889bf215546Sopenharmony_ci{
890bf215546Sopenharmony_ci   bool is_multisampled = samples > 1;
891bf215546Sopenharmony_ci   enum glsl_sampler_dim dim = is_3d             ? GLSL_SAMPLER_DIM_3D
892bf215546Sopenharmony_ci                               : is_multisampled ? GLSL_SAMPLER_DIM_MS
893bf215546Sopenharmony_ci                                                 : GLSL_SAMPLER_DIM_2D;
894bf215546Sopenharmony_ci   const struct glsl_type *img_type = glsl_image_type(dim, false, GLSL_TYPE_FLOAT);
895bf215546Sopenharmony_ci   nir_builder b = radv_meta_init_shader(
896bf215546Sopenharmony_ci      dev, MESA_SHADER_COMPUTE, is_3d ? "meta_cleari_cs_3d-%d" : "meta_cleari_cs-%d", samples);
897bf215546Sopenharmony_ci   b.shader->info.workgroup_size[0] = 8;
898bf215546Sopenharmony_ci   b.shader->info.workgroup_size[1] = 8;
899bf215546Sopenharmony_ci
900bf215546Sopenharmony_ci   nir_variable *output_img = nir_variable_create(b.shader, nir_var_image, img_type, "out_img");
901bf215546Sopenharmony_ci   output_img->data.descriptor_set = 0;
902bf215546Sopenharmony_ci   output_img->data.binding = 0;
903bf215546Sopenharmony_ci
904bf215546Sopenharmony_ci   nir_ssa_def *global_id = get_global_ids(&b, 2);
905bf215546Sopenharmony_ci
906bf215546Sopenharmony_ci   nir_ssa_def *clear_val = nir_load_push_constant(&b, 4, 32, nir_imm_int(&b, 0), .range = 16);
907bf215546Sopenharmony_ci   nir_ssa_def *layer = nir_load_push_constant(&b, 1, 32, nir_imm_int(&b, 16), .range = 20);
908bf215546Sopenharmony_ci
909bf215546Sopenharmony_ci   nir_ssa_def *comps[4];
910bf215546Sopenharmony_ci   comps[0] = nir_channel(&b, global_id, 0);
911bf215546Sopenharmony_ci   comps[1] = nir_channel(&b, global_id, 1);
912bf215546Sopenharmony_ci   comps[2] = layer;
913bf215546Sopenharmony_ci   comps[3] = nir_ssa_undef(&b, 1, 32);
914bf215546Sopenharmony_ci   global_id = nir_vec(&b, comps, 4);
915bf215546Sopenharmony_ci
916bf215546Sopenharmony_ci   for (uint32_t i = 0; i < samples; i++) {
917bf215546Sopenharmony_ci      nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img)->dest.ssa, global_id,
918bf215546Sopenharmony_ci                            nir_imm_int(&b, i), clear_val, nir_imm_int(&b, 0), .image_dim = dim);
919bf215546Sopenharmony_ci   }
920bf215546Sopenharmony_ci
921bf215546Sopenharmony_ci   return b.shader;
922bf215546Sopenharmony_ci}
923bf215546Sopenharmony_ci
924bf215546Sopenharmony_cistatic VkResult
925bf215546Sopenharmony_cicreate_cleari_pipeline(struct radv_device *device, int samples, VkPipeline *pipeline)
926bf215546Sopenharmony_ci{
927bf215546Sopenharmony_ci   nir_shader *cs = build_nir_cleari_compute_shader(device, false, samples);
928bf215546Sopenharmony_ci   VkResult result;
929bf215546Sopenharmony_ci
930bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
931bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
932bf215546Sopenharmony_ci      .stage = VK_SHADER_STAGE_COMPUTE_BIT,
933bf215546Sopenharmony_ci      .module = vk_shader_module_handle_from_nir(cs),
934bf215546Sopenharmony_ci      .pName = "main",
935bf215546Sopenharmony_ci      .pSpecializationInfo = NULL,
936bf215546Sopenharmony_ci   };
937bf215546Sopenharmony_ci
938bf215546Sopenharmony_ci   VkComputePipelineCreateInfo vk_pipeline_info = {
939bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
940bf215546Sopenharmony_ci      .stage = pipeline_shader_stage,
941bf215546Sopenharmony_ci      .flags = 0,
942bf215546Sopenharmony_ci      .layout = device->meta_state.cleari.img_p_layout,
943bf215546Sopenharmony_ci   };
944bf215546Sopenharmony_ci
945bf215546Sopenharmony_ci   result = radv_CreateComputePipelines(radv_device_to_handle(device),
946bf215546Sopenharmony_ci                                        radv_pipeline_cache_to_handle(&device->meta_state.cache), 1,
947bf215546Sopenharmony_ci                                        &vk_pipeline_info, NULL, pipeline);
948bf215546Sopenharmony_ci   ralloc_free(cs);
949bf215546Sopenharmony_ci   return result;
950bf215546Sopenharmony_ci}
951bf215546Sopenharmony_ci
952bf215546Sopenharmony_cistatic VkResult
953bf215546Sopenharmony_ciradv_device_init_meta_cleari_state(struct radv_device *device)
954bf215546Sopenharmony_ci{
955bf215546Sopenharmony_ci   VkResult result;
956bf215546Sopenharmony_ci
957bf215546Sopenharmony_ci   /*
958bf215546Sopenharmony_ci    * two descriptors one for the image being sampled
959bf215546Sopenharmony_ci    * one for the buffer being written.
960bf215546Sopenharmony_ci    */
961bf215546Sopenharmony_ci   VkDescriptorSetLayoutCreateInfo ds_create_info = {
962bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
963bf215546Sopenharmony_ci      .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
964bf215546Sopenharmony_ci      .bindingCount = 1,
965bf215546Sopenharmony_ci      .pBindings = (VkDescriptorSetLayoutBinding[]){
966bf215546Sopenharmony_ci         {.binding = 0,
967bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
968bf215546Sopenharmony_ci          .descriptorCount = 1,
969bf215546Sopenharmony_ci          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
970bf215546Sopenharmony_ci          .pImmutableSamplers = NULL},
971bf215546Sopenharmony_ci      }};
972bf215546Sopenharmony_ci
973bf215546Sopenharmony_ci   result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &ds_create_info,
974bf215546Sopenharmony_ci                                           &device->meta_state.alloc,
975bf215546Sopenharmony_ci                                           &device->meta_state.cleari.img_ds_layout);
976bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
977bf215546Sopenharmony_ci      goto fail;
978bf215546Sopenharmony_ci
979bf215546Sopenharmony_ci   VkPipelineLayoutCreateInfo pl_create_info = {
980bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
981bf215546Sopenharmony_ci      .setLayoutCount = 1,
982bf215546Sopenharmony_ci      .pSetLayouts = &device->meta_state.cleari.img_ds_layout,
983bf215546Sopenharmony_ci      .pushConstantRangeCount = 1,
984bf215546Sopenharmony_ci      .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_COMPUTE_BIT, 0, 20},
985bf215546Sopenharmony_ci   };
986bf215546Sopenharmony_ci
987bf215546Sopenharmony_ci   result =
988bf215546Sopenharmony_ci      radv_CreatePipelineLayout(radv_device_to_handle(device), &pl_create_info,
989bf215546Sopenharmony_ci                                &device->meta_state.alloc, &device->meta_state.cleari.img_p_layout);
990bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
991bf215546Sopenharmony_ci      goto fail;
992bf215546Sopenharmony_ci
993bf215546Sopenharmony_ci   for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; i++) {
994bf215546Sopenharmony_ci      uint32_t samples = 1 << i;
995bf215546Sopenharmony_ci      result = create_cleari_pipeline(device, samples, &device->meta_state.cleari.pipeline[i]);
996bf215546Sopenharmony_ci      if (result != VK_SUCCESS)
997bf215546Sopenharmony_ci         goto fail;
998bf215546Sopenharmony_ci   }
999bf215546Sopenharmony_ci
1000bf215546Sopenharmony_ci   nir_shader *cs_3d = build_nir_cleari_compute_shader(device, true, 1);
1001bf215546Sopenharmony_ci
1002bf215546Sopenharmony_ci   /* compute shader */
1003bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stage_3d = {
1004bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1005bf215546Sopenharmony_ci      .stage = VK_SHADER_STAGE_COMPUTE_BIT,
1006bf215546Sopenharmony_ci      .module = vk_shader_module_handle_from_nir(cs_3d),
1007bf215546Sopenharmony_ci      .pName = "main",
1008bf215546Sopenharmony_ci      .pSpecializationInfo = NULL,
1009bf215546Sopenharmony_ci   };
1010bf215546Sopenharmony_ci
1011bf215546Sopenharmony_ci   VkComputePipelineCreateInfo vk_pipeline_info_3d = {
1012bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1013bf215546Sopenharmony_ci      .stage = pipeline_shader_stage_3d,
1014bf215546Sopenharmony_ci      .flags = 0,
1015bf215546Sopenharmony_ci      .layout = device->meta_state.cleari.img_p_layout,
1016bf215546Sopenharmony_ci   };
1017bf215546Sopenharmony_ci
1018bf215546Sopenharmony_ci   result = radv_CreateComputePipelines(
1019bf215546Sopenharmony_ci      radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache), 1,
1020bf215546Sopenharmony_ci      &vk_pipeline_info_3d, NULL, &device->meta_state.cleari.pipeline_3d);
1021bf215546Sopenharmony_ci   ralloc_free(cs_3d);
1022bf215546Sopenharmony_ci
1023bf215546Sopenharmony_ci   return VK_SUCCESS;
1024bf215546Sopenharmony_cifail:
1025bf215546Sopenharmony_ci   return result;
1026bf215546Sopenharmony_ci}
1027bf215546Sopenharmony_ci
1028bf215546Sopenharmony_cistatic void
1029bf215546Sopenharmony_ciradv_device_finish_meta_cleari_state(struct radv_device *device)
1030bf215546Sopenharmony_ci{
1031bf215546Sopenharmony_ci   struct radv_meta_state *state = &device->meta_state;
1032bf215546Sopenharmony_ci
1033bf215546Sopenharmony_ci   radv_DestroyPipelineLayout(radv_device_to_handle(device), state->cleari.img_p_layout,
1034bf215546Sopenharmony_ci                              &state->alloc);
1035bf215546Sopenharmony_ci   device->vk.dispatch_table.DestroyDescriptorSetLayout(radv_device_to_handle(device),
1036bf215546Sopenharmony_ci                                                        state->cleari.img_ds_layout, &state->alloc);
1037bf215546Sopenharmony_ci
1038bf215546Sopenharmony_ci   for (uint32_t i = 0; i < MAX_SAMPLES_LOG2; ++i) {
1039bf215546Sopenharmony_ci      radv_DestroyPipeline(radv_device_to_handle(device), state->cleari.pipeline[i], &state->alloc);
1040bf215546Sopenharmony_ci   }
1041bf215546Sopenharmony_ci
1042bf215546Sopenharmony_ci   radv_DestroyPipeline(radv_device_to_handle(device), state->cleari.pipeline_3d, &state->alloc);
1043bf215546Sopenharmony_ci}
1044bf215546Sopenharmony_ci
1045bf215546Sopenharmony_ci/* Special path for clearing R32G32B32 images using a compute shader. */
1046bf215546Sopenharmony_cistatic nir_shader *
1047bf215546Sopenharmony_cibuild_nir_cleari_r32g32b32_compute_shader(struct radv_device *dev)
1048bf215546Sopenharmony_ci{
1049bf215546Sopenharmony_ci   const struct glsl_type *img_type = glsl_image_type(GLSL_SAMPLER_DIM_BUF, false, GLSL_TYPE_FLOAT);
1050bf215546Sopenharmony_ci   nir_builder b = radv_meta_init_shader(dev, MESA_SHADER_COMPUTE, "meta_cleari_r32g32b32_cs");
1051bf215546Sopenharmony_ci   b.shader->info.workgroup_size[0] = 8;
1052bf215546Sopenharmony_ci   b.shader->info.workgroup_size[1] = 8;
1053bf215546Sopenharmony_ci
1054bf215546Sopenharmony_ci   nir_variable *output_img = nir_variable_create(b.shader, nir_var_image, img_type, "out_img");
1055bf215546Sopenharmony_ci   output_img->data.descriptor_set = 0;
1056bf215546Sopenharmony_ci   output_img->data.binding = 0;
1057bf215546Sopenharmony_ci
1058bf215546Sopenharmony_ci   nir_ssa_def *global_id = get_global_ids(&b, 2);
1059bf215546Sopenharmony_ci
1060bf215546Sopenharmony_ci   nir_ssa_def *clear_val = nir_load_push_constant(&b, 3, 32, nir_imm_int(&b, 0), .range = 12);
1061bf215546Sopenharmony_ci   nir_ssa_def *stride = nir_load_push_constant(&b, 1, 32, nir_imm_int(&b, 12), .range = 16);
1062bf215546Sopenharmony_ci
1063bf215546Sopenharmony_ci   nir_ssa_def *global_x = nir_channel(&b, global_id, 0);
1064bf215546Sopenharmony_ci   nir_ssa_def *global_y = nir_channel(&b, global_id, 1);
1065bf215546Sopenharmony_ci
1066bf215546Sopenharmony_ci   nir_ssa_def *global_pos =
1067bf215546Sopenharmony_ci      nir_iadd(&b, nir_imul(&b, global_y, stride), nir_imul_imm(&b, global_x, 3));
1068bf215546Sopenharmony_ci
1069bf215546Sopenharmony_ci   for (unsigned chan = 0; chan < 3; chan++) {
1070bf215546Sopenharmony_ci      nir_ssa_def *local_pos = nir_iadd_imm(&b, global_pos, chan);
1071bf215546Sopenharmony_ci
1072bf215546Sopenharmony_ci      nir_ssa_def *coord = nir_vec4(&b, local_pos, local_pos, local_pos, local_pos);
1073bf215546Sopenharmony_ci
1074bf215546Sopenharmony_ci      nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img)->dest.ssa, coord,
1075bf215546Sopenharmony_ci                            nir_ssa_undef(&b, 1, 32), nir_channel(&b, clear_val, chan),
1076bf215546Sopenharmony_ci                            nir_imm_int(&b, 0), .image_dim = GLSL_SAMPLER_DIM_BUF);
1077bf215546Sopenharmony_ci   }
1078bf215546Sopenharmony_ci
1079bf215546Sopenharmony_ci   return b.shader;
1080bf215546Sopenharmony_ci}
1081bf215546Sopenharmony_ci
1082bf215546Sopenharmony_cistatic VkResult
1083bf215546Sopenharmony_ciradv_device_init_meta_cleari_r32g32b32_state(struct radv_device *device)
1084bf215546Sopenharmony_ci{
1085bf215546Sopenharmony_ci   VkResult result;
1086bf215546Sopenharmony_ci   nir_shader *cs = build_nir_cleari_r32g32b32_compute_shader(device);
1087bf215546Sopenharmony_ci
1088bf215546Sopenharmony_ci   VkDescriptorSetLayoutCreateInfo ds_create_info = {
1089bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1090bf215546Sopenharmony_ci      .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
1091bf215546Sopenharmony_ci      .bindingCount = 1,
1092bf215546Sopenharmony_ci      .pBindings = (VkDescriptorSetLayoutBinding[]){
1093bf215546Sopenharmony_ci         {.binding = 0,
1094bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
1095bf215546Sopenharmony_ci          .descriptorCount = 1,
1096bf215546Sopenharmony_ci          .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
1097bf215546Sopenharmony_ci          .pImmutableSamplers = NULL},
1098bf215546Sopenharmony_ci      }};
1099bf215546Sopenharmony_ci
1100bf215546Sopenharmony_ci   result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &ds_create_info,
1101bf215546Sopenharmony_ci                                           &device->meta_state.alloc,
1102bf215546Sopenharmony_ci                                           &device->meta_state.cleari_r32g32b32.img_ds_layout);
1103bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
1104bf215546Sopenharmony_ci      goto fail;
1105bf215546Sopenharmony_ci
1106bf215546Sopenharmony_ci   VkPipelineLayoutCreateInfo pl_create_info = {
1107bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1108bf215546Sopenharmony_ci      .setLayoutCount = 1,
1109bf215546Sopenharmony_ci      .pSetLayouts = &device->meta_state.cleari_r32g32b32.img_ds_layout,
1110bf215546Sopenharmony_ci      .pushConstantRangeCount = 1,
1111bf215546Sopenharmony_ci      .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_COMPUTE_BIT, 0, 16},
1112bf215546Sopenharmony_ci   };
1113bf215546Sopenharmony_ci
1114bf215546Sopenharmony_ci   result = radv_CreatePipelineLayout(radv_device_to_handle(device), &pl_create_info,
1115bf215546Sopenharmony_ci                                      &device->meta_state.alloc,
1116bf215546Sopenharmony_ci                                      &device->meta_state.cleari_r32g32b32.img_p_layout);
1117bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
1118bf215546Sopenharmony_ci      goto fail;
1119bf215546Sopenharmony_ci
1120bf215546Sopenharmony_ci   /* compute shader */
1121bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
1122bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1123bf215546Sopenharmony_ci      .stage = VK_SHADER_STAGE_COMPUTE_BIT,
1124bf215546Sopenharmony_ci      .module = vk_shader_module_handle_from_nir(cs),
1125bf215546Sopenharmony_ci      .pName = "main",
1126bf215546Sopenharmony_ci      .pSpecializationInfo = NULL,
1127bf215546Sopenharmony_ci   };
1128bf215546Sopenharmony_ci
1129bf215546Sopenharmony_ci   VkComputePipelineCreateInfo vk_pipeline_info = {
1130bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1131bf215546Sopenharmony_ci      .stage = pipeline_shader_stage,
1132bf215546Sopenharmony_ci      .flags = 0,
1133bf215546Sopenharmony_ci      .layout = device->meta_state.cleari_r32g32b32.img_p_layout,
1134bf215546Sopenharmony_ci   };
1135bf215546Sopenharmony_ci
1136bf215546Sopenharmony_ci   result = radv_CreateComputePipelines(
1137bf215546Sopenharmony_ci      radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache), 1,
1138bf215546Sopenharmony_ci      &vk_pipeline_info, NULL, &device->meta_state.cleari_r32g32b32.pipeline);
1139bf215546Sopenharmony_ci
1140bf215546Sopenharmony_cifail:
1141bf215546Sopenharmony_ci   ralloc_free(cs);
1142bf215546Sopenharmony_ci   return result;
1143bf215546Sopenharmony_ci}
1144bf215546Sopenharmony_ci
1145bf215546Sopenharmony_cistatic void
1146bf215546Sopenharmony_ciradv_device_finish_meta_cleari_r32g32b32_state(struct radv_device *device)
1147bf215546Sopenharmony_ci{
1148bf215546Sopenharmony_ci   struct radv_meta_state *state = &device->meta_state;
1149bf215546Sopenharmony_ci
1150bf215546Sopenharmony_ci   radv_DestroyPipelineLayout(radv_device_to_handle(device), state->cleari_r32g32b32.img_p_layout,
1151bf215546Sopenharmony_ci                              &state->alloc);
1152bf215546Sopenharmony_ci   device->vk.dispatch_table.DestroyDescriptorSetLayout(
1153bf215546Sopenharmony_ci      radv_device_to_handle(device), state->cleari_r32g32b32.img_ds_layout, &state->alloc);
1154bf215546Sopenharmony_ci   radv_DestroyPipeline(radv_device_to_handle(device), state->cleari_r32g32b32.pipeline,
1155bf215546Sopenharmony_ci                        &state->alloc);
1156bf215546Sopenharmony_ci}
1157bf215546Sopenharmony_ci
1158bf215546Sopenharmony_civoid
1159bf215546Sopenharmony_ciradv_device_finish_meta_bufimage_state(struct radv_device *device)
1160bf215546Sopenharmony_ci{
1161bf215546Sopenharmony_ci   radv_device_finish_meta_itob_state(device);
1162bf215546Sopenharmony_ci   radv_device_finish_meta_btoi_state(device);
1163bf215546Sopenharmony_ci   radv_device_finish_meta_btoi_r32g32b32_state(device);
1164bf215546Sopenharmony_ci   radv_device_finish_meta_itoi_state(device);
1165bf215546Sopenharmony_ci   radv_device_finish_meta_itoi_r32g32b32_state(device);
1166bf215546Sopenharmony_ci   radv_device_finish_meta_cleari_state(device);
1167bf215546Sopenharmony_ci   radv_device_finish_meta_cleari_r32g32b32_state(device);
1168bf215546Sopenharmony_ci}
1169bf215546Sopenharmony_ci
1170bf215546Sopenharmony_ciVkResult
1171bf215546Sopenharmony_ciradv_device_init_meta_bufimage_state(struct radv_device *device)
1172bf215546Sopenharmony_ci{
1173bf215546Sopenharmony_ci   VkResult result;
1174bf215546Sopenharmony_ci
1175bf215546Sopenharmony_ci   result = radv_device_init_meta_itob_state(device);
1176bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
1177bf215546Sopenharmony_ci      return result;
1178bf215546Sopenharmony_ci
1179bf215546Sopenharmony_ci   result = radv_device_init_meta_btoi_state(device);
1180bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
1181bf215546Sopenharmony_ci      return result;
1182bf215546Sopenharmony_ci
1183bf215546Sopenharmony_ci   result = radv_device_init_meta_btoi_r32g32b32_state(device);
1184bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
1185bf215546Sopenharmony_ci      return result;
1186bf215546Sopenharmony_ci
1187bf215546Sopenharmony_ci   result = radv_device_init_meta_itoi_state(device);
1188bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
1189bf215546Sopenharmony_ci      return result;
1190bf215546Sopenharmony_ci
1191bf215546Sopenharmony_ci   result = radv_device_init_meta_itoi_r32g32b32_state(device);
1192bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
1193bf215546Sopenharmony_ci      return result;
1194bf215546Sopenharmony_ci
1195bf215546Sopenharmony_ci   result = radv_device_init_meta_cleari_state(device);
1196bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
1197bf215546Sopenharmony_ci      return result;
1198bf215546Sopenharmony_ci
1199bf215546Sopenharmony_ci   result = radv_device_init_meta_cleari_r32g32b32_state(device);
1200bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
1201bf215546Sopenharmony_ci      return result;
1202bf215546Sopenharmony_ci
1203bf215546Sopenharmony_ci   return VK_SUCCESS;
1204bf215546Sopenharmony_ci}
1205bf215546Sopenharmony_ci
1206bf215546Sopenharmony_cistatic void
1207bf215546Sopenharmony_cicreate_iview(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *surf,
1208bf215546Sopenharmony_ci             struct radv_image_view *iview, VkFormat format, VkImageAspectFlagBits aspects)
1209bf215546Sopenharmony_ci{
1210bf215546Sopenharmony_ci   if (format == VK_FORMAT_UNDEFINED)
1211bf215546Sopenharmony_ci      format = surf->format;
1212bf215546Sopenharmony_ci
1213bf215546Sopenharmony_ci   radv_image_view_init(iview, cmd_buffer->device,
1214bf215546Sopenharmony_ci                        &(VkImageViewCreateInfo){
1215bf215546Sopenharmony_ci                           .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1216bf215546Sopenharmony_ci                           .image = radv_image_to_handle(surf->image),
1217bf215546Sopenharmony_ci                           .viewType = radv_meta_get_view_type(surf->image),
1218bf215546Sopenharmony_ci                           .format = format,
1219bf215546Sopenharmony_ci                           .subresourceRange = {.aspectMask = aspects,
1220bf215546Sopenharmony_ci                                                .baseMipLevel = surf->level,
1221bf215546Sopenharmony_ci                                                .levelCount = 1,
1222bf215546Sopenharmony_ci                                                .baseArrayLayer = surf->layer,
1223bf215546Sopenharmony_ci                                                .layerCount = 1},
1224bf215546Sopenharmony_ci                        },
1225bf215546Sopenharmony_ci                        0, &(struct radv_image_view_extra_create_info){
1226bf215546Sopenharmony_ci                           .disable_compression = surf->disable_compression,
1227bf215546Sopenharmony_ci                        });
1228bf215546Sopenharmony_ci}
1229bf215546Sopenharmony_ci
1230bf215546Sopenharmony_cistatic void
1231bf215546Sopenharmony_cicreate_bview(struct radv_cmd_buffer *cmd_buffer, struct radv_buffer *buffer, unsigned offset,
1232bf215546Sopenharmony_ci             VkFormat format, struct radv_buffer_view *bview)
1233bf215546Sopenharmony_ci{
1234bf215546Sopenharmony_ci   radv_buffer_view_init(bview, cmd_buffer->device,
1235bf215546Sopenharmony_ci                         &(VkBufferViewCreateInfo){
1236bf215546Sopenharmony_ci                            .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
1237bf215546Sopenharmony_ci                            .flags = 0,
1238bf215546Sopenharmony_ci                            .buffer = radv_buffer_to_handle(buffer),
1239bf215546Sopenharmony_ci                            .format = format,
1240bf215546Sopenharmony_ci                            .offset = offset,
1241bf215546Sopenharmony_ci                            .range = VK_WHOLE_SIZE,
1242bf215546Sopenharmony_ci                         });
1243bf215546Sopenharmony_ci}
1244bf215546Sopenharmony_ci
1245bf215546Sopenharmony_cistatic void
1246bf215546Sopenharmony_cicreate_buffer_from_image(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *surf,
1247bf215546Sopenharmony_ci                         VkBufferUsageFlagBits usage, VkBuffer *buffer)
1248bf215546Sopenharmony_ci{
1249bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
1250bf215546Sopenharmony_ci   struct radv_device_memory mem;
1251bf215546Sopenharmony_ci
1252bf215546Sopenharmony_ci   radv_device_memory_init(&mem, device, surf->image->bindings[0].bo);
1253bf215546Sopenharmony_ci
1254bf215546Sopenharmony_ci   radv_CreateBuffer(radv_device_to_handle(device),
1255bf215546Sopenharmony_ci                     &(VkBufferCreateInfo){
1256bf215546Sopenharmony_ci                        .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1257bf215546Sopenharmony_ci                        .flags = 0,
1258bf215546Sopenharmony_ci                        .size = surf->image->size,
1259bf215546Sopenharmony_ci                        .usage = usage,
1260bf215546Sopenharmony_ci                        .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
1261bf215546Sopenharmony_ci                     },
1262bf215546Sopenharmony_ci                     NULL, buffer);
1263bf215546Sopenharmony_ci
1264bf215546Sopenharmony_ci   radv_BindBufferMemory2(radv_device_to_handle(device), 1,
1265bf215546Sopenharmony_ci                          (VkBindBufferMemoryInfo[]){{
1266bf215546Sopenharmony_ci                             .sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
1267bf215546Sopenharmony_ci                             .buffer = *buffer,
1268bf215546Sopenharmony_ci                             .memory = radv_device_memory_to_handle(&mem),
1269bf215546Sopenharmony_ci                             .memoryOffset = surf->image->bindings[0].offset,
1270bf215546Sopenharmony_ci                          }});
1271bf215546Sopenharmony_ci
1272bf215546Sopenharmony_ci   radv_device_memory_finish(&mem);
1273bf215546Sopenharmony_ci}
1274bf215546Sopenharmony_ci
1275bf215546Sopenharmony_cistatic void
1276bf215546Sopenharmony_cicreate_bview_for_r32g32b32(struct radv_cmd_buffer *cmd_buffer, struct radv_buffer *buffer,
1277bf215546Sopenharmony_ci                           unsigned offset, VkFormat src_format, struct radv_buffer_view *bview)
1278bf215546Sopenharmony_ci{
1279bf215546Sopenharmony_ci   VkFormat format;
1280bf215546Sopenharmony_ci
1281bf215546Sopenharmony_ci   switch (src_format) {
1282bf215546Sopenharmony_ci   case VK_FORMAT_R32G32B32_UINT:
1283bf215546Sopenharmony_ci      format = VK_FORMAT_R32_UINT;
1284bf215546Sopenharmony_ci      break;
1285bf215546Sopenharmony_ci   case VK_FORMAT_R32G32B32_SINT:
1286bf215546Sopenharmony_ci      format = VK_FORMAT_R32_SINT;
1287bf215546Sopenharmony_ci      break;
1288bf215546Sopenharmony_ci   case VK_FORMAT_R32G32B32_SFLOAT:
1289bf215546Sopenharmony_ci      format = VK_FORMAT_R32_SFLOAT;
1290bf215546Sopenharmony_ci      break;
1291bf215546Sopenharmony_ci   default:
1292bf215546Sopenharmony_ci      unreachable("invalid R32G32B32 format");
1293bf215546Sopenharmony_ci   }
1294bf215546Sopenharmony_ci
1295bf215546Sopenharmony_ci   radv_buffer_view_init(bview, cmd_buffer->device,
1296bf215546Sopenharmony_ci                         &(VkBufferViewCreateInfo){
1297bf215546Sopenharmony_ci                            .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
1298bf215546Sopenharmony_ci                            .flags = 0,
1299bf215546Sopenharmony_ci                            .buffer = radv_buffer_to_handle(buffer),
1300bf215546Sopenharmony_ci                            .format = format,
1301bf215546Sopenharmony_ci                            .offset = offset,
1302bf215546Sopenharmony_ci                            .range = VK_WHOLE_SIZE,
1303bf215546Sopenharmony_ci                         });
1304bf215546Sopenharmony_ci}
1305bf215546Sopenharmony_ci
1306bf215546Sopenharmony_cistatic unsigned
1307bf215546Sopenharmony_ciget_image_stride_for_r32g32b32(struct radv_cmd_buffer *cmd_buffer,
1308bf215546Sopenharmony_ci                               struct radv_meta_blit2d_surf *surf)
1309bf215546Sopenharmony_ci{
1310bf215546Sopenharmony_ci   unsigned stride;
1311bf215546Sopenharmony_ci
1312bf215546Sopenharmony_ci   if (cmd_buffer->device->physical_device->rad_info.gfx_level >= GFX9) {
1313bf215546Sopenharmony_ci      stride = surf->image->planes[0].surface.u.gfx9.surf_pitch;
1314bf215546Sopenharmony_ci   } else {
1315bf215546Sopenharmony_ci      stride = surf->image->planes[0].surface.u.legacy.level[0].nblk_x * 3;
1316bf215546Sopenharmony_ci   }
1317bf215546Sopenharmony_ci
1318bf215546Sopenharmony_ci   return stride;
1319bf215546Sopenharmony_ci}
1320bf215546Sopenharmony_ci
1321bf215546Sopenharmony_cistatic void
1322bf215546Sopenharmony_ciitob_bind_descriptors(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src,
1323bf215546Sopenharmony_ci                      struct radv_buffer_view *dst)
1324bf215546Sopenharmony_ci{
1325bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
1326bf215546Sopenharmony_ci
1327bf215546Sopenharmony_ci   radv_meta_push_descriptor_set(
1328bf215546Sopenharmony_ci      cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, device->meta_state.itob.img_p_layout, 0, /* set */
1329bf215546Sopenharmony_ci      2, /* descriptorWriteCount */
1330bf215546Sopenharmony_ci      (VkWriteDescriptorSet[]){
1331bf215546Sopenharmony_ci         {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1332bf215546Sopenharmony_ci          .dstBinding = 0,
1333bf215546Sopenharmony_ci          .dstArrayElement = 0,
1334bf215546Sopenharmony_ci          .descriptorCount = 1,
1335bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
1336bf215546Sopenharmony_ci          .pImageInfo =
1337bf215546Sopenharmony_ci             (VkDescriptorImageInfo[]){
1338bf215546Sopenharmony_ci                {
1339bf215546Sopenharmony_ci                   .sampler = VK_NULL_HANDLE,
1340bf215546Sopenharmony_ci                   .imageView = radv_image_view_to_handle(src),
1341bf215546Sopenharmony_ci                   .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
1342bf215546Sopenharmony_ci                },
1343bf215546Sopenharmony_ci             }},
1344bf215546Sopenharmony_ci         {
1345bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1346bf215546Sopenharmony_ci            .dstBinding = 1,
1347bf215546Sopenharmony_ci            .dstArrayElement = 0,
1348bf215546Sopenharmony_ci            .descriptorCount = 1,
1349bf215546Sopenharmony_ci            .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
1350bf215546Sopenharmony_ci            .pTexelBufferView = (VkBufferView[]){radv_buffer_view_to_handle(dst)},
1351bf215546Sopenharmony_ci         }});
1352bf215546Sopenharmony_ci}
1353bf215546Sopenharmony_ci
1354bf215546Sopenharmony_civoid
1355bf215546Sopenharmony_ciradv_meta_image_to_buffer(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *src,
1356bf215546Sopenharmony_ci                          struct radv_meta_blit2d_buffer *dst, unsigned num_rects,
1357bf215546Sopenharmony_ci                          struct radv_meta_blit2d_rect *rects)
1358bf215546Sopenharmony_ci{
1359bf215546Sopenharmony_ci   VkPipeline pipeline = cmd_buffer->device->meta_state.itob.pipeline;
1360bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
1361bf215546Sopenharmony_ci   struct radv_image_view src_view;
1362bf215546Sopenharmony_ci   struct radv_buffer_view dst_view;
1363bf215546Sopenharmony_ci
1364bf215546Sopenharmony_ci   create_iview(cmd_buffer, src, &src_view, VK_FORMAT_UNDEFINED, src->aspect_mask);
1365bf215546Sopenharmony_ci   create_bview(cmd_buffer, dst->buffer, dst->offset, dst->format, &dst_view);
1366bf215546Sopenharmony_ci   itob_bind_descriptors(cmd_buffer, &src_view, &dst_view);
1367bf215546Sopenharmony_ci
1368bf215546Sopenharmony_ci   if (src->image->vk.image_type == VK_IMAGE_TYPE_3D)
1369bf215546Sopenharmony_ci      pipeline = cmd_buffer->device->meta_state.itob.pipeline_3d;
1370bf215546Sopenharmony_ci
1371bf215546Sopenharmony_ci   radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE,
1372bf215546Sopenharmony_ci                        pipeline);
1373bf215546Sopenharmony_ci
1374bf215546Sopenharmony_ci   for (unsigned r = 0; r < num_rects; ++r) {
1375bf215546Sopenharmony_ci      unsigned push_constants[4] = {rects[r].src_x, rects[r].src_y, src->layer, dst->pitch};
1376bf215546Sopenharmony_ci      radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
1377bf215546Sopenharmony_ci                            device->meta_state.itob.img_p_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0,
1378bf215546Sopenharmony_ci                            16, push_constants);
1379bf215546Sopenharmony_ci
1380bf215546Sopenharmony_ci      radv_unaligned_dispatch(cmd_buffer, rects[r].width, rects[r].height, 1);
1381bf215546Sopenharmony_ci   }
1382bf215546Sopenharmony_ci
1383bf215546Sopenharmony_ci   radv_image_view_finish(&src_view);
1384bf215546Sopenharmony_ci   radv_buffer_view_finish(&dst_view);
1385bf215546Sopenharmony_ci}
1386bf215546Sopenharmony_ci
1387bf215546Sopenharmony_cistatic void
1388bf215546Sopenharmony_cibtoi_r32g32b32_bind_descriptors(struct radv_cmd_buffer *cmd_buffer, struct radv_buffer_view *src,
1389bf215546Sopenharmony_ci                                struct radv_buffer_view *dst)
1390bf215546Sopenharmony_ci{
1391bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
1392bf215546Sopenharmony_ci
1393bf215546Sopenharmony_ci   radv_meta_push_descriptor_set(
1394bf215546Sopenharmony_ci      cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, device->meta_state.btoi_r32g32b32.img_p_layout,
1395bf215546Sopenharmony_ci      0, /* set */
1396bf215546Sopenharmony_ci      2, /* descriptorWriteCount */
1397bf215546Sopenharmony_ci      (VkWriteDescriptorSet[]){
1398bf215546Sopenharmony_ci         {
1399bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1400bf215546Sopenharmony_ci            .dstBinding = 0,
1401bf215546Sopenharmony_ci            .dstArrayElement = 0,
1402bf215546Sopenharmony_ci            .descriptorCount = 1,
1403bf215546Sopenharmony_ci            .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
1404bf215546Sopenharmony_ci            .pTexelBufferView = (VkBufferView[]){radv_buffer_view_to_handle(src)},
1405bf215546Sopenharmony_ci         },
1406bf215546Sopenharmony_ci         {
1407bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1408bf215546Sopenharmony_ci            .dstBinding = 1,
1409bf215546Sopenharmony_ci            .dstArrayElement = 0,
1410bf215546Sopenharmony_ci            .descriptorCount = 1,
1411bf215546Sopenharmony_ci            .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
1412bf215546Sopenharmony_ci            .pTexelBufferView = (VkBufferView[]){radv_buffer_view_to_handle(dst)},
1413bf215546Sopenharmony_ci         }});
1414bf215546Sopenharmony_ci}
1415bf215546Sopenharmony_ci
1416bf215546Sopenharmony_cistatic void
1417bf215546Sopenharmony_ciradv_meta_buffer_to_image_cs_r32g32b32(struct radv_cmd_buffer *cmd_buffer,
1418bf215546Sopenharmony_ci                                       struct radv_meta_blit2d_buffer *src,
1419bf215546Sopenharmony_ci                                       struct radv_meta_blit2d_surf *dst, unsigned num_rects,
1420bf215546Sopenharmony_ci                                       struct radv_meta_blit2d_rect *rects)
1421bf215546Sopenharmony_ci{
1422bf215546Sopenharmony_ci   VkPipeline pipeline = cmd_buffer->device->meta_state.btoi_r32g32b32.pipeline;
1423bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
1424bf215546Sopenharmony_ci   struct radv_buffer_view src_view, dst_view;
1425bf215546Sopenharmony_ci   unsigned dst_offset = 0;
1426bf215546Sopenharmony_ci   unsigned stride;
1427bf215546Sopenharmony_ci   VkBuffer buffer;
1428bf215546Sopenharmony_ci
1429bf215546Sopenharmony_ci   /* This special btoi path for R32G32B32 formats will write the linear
1430bf215546Sopenharmony_ci    * image as a buffer with the same underlying memory. The compute
1431bf215546Sopenharmony_ci    * shader will copy all components separately using a R32 format.
1432bf215546Sopenharmony_ci    */
1433bf215546Sopenharmony_ci   create_buffer_from_image(cmd_buffer, dst, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, &buffer);
1434bf215546Sopenharmony_ci
1435bf215546Sopenharmony_ci   create_bview(cmd_buffer, src->buffer, src->offset, src->format, &src_view);
1436bf215546Sopenharmony_ci   create_bview_for_r32g32b32(cmd_buffer, radv_buffer_from_handle(buffer), dst_offset, dst->format,
1437bf215546Sopenharmony_ci                              &dst_view);
1438bf215546Sopenharmony_ci   btoi_r32g32b32_bind_descriptors(cmd_buffer, &src_view, &dst_view);
1439bf215546Sopenharmony_ci
1440bf215546Sopenharmony_ci   radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE,
1441bf215546Sopenharmony_ci                        pipeline);
1442bf215546Sopenharmony_ci
1443bf215546Sopenharmony_ci   stride = get_image_stride_for_r32g32b32(cmd_buffer, dst);
1444bf215546Sopenharmony_ci
1445bf215546Sopenharmony_ci   for (unsigned r = 0; r < num_rects; ++r) {
1446bf215546Sopenharmony_ci      unsigned push_constants[4] = {
1447bf215546Sopenharmony_ci         rects[r].dst_x,
1448bf215546Sopenharmony_ci         rects[r].dst_y,
1449bf215546Sopenharmony_ci         stride,
1450bf215546Sopenharmony_ci         src->pitch,
1451bf215546Sopenharmony_ci      };
1452bf215546Sopenharmony_ci
1453bf215546Sopenharmony_ci      radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
1454bf215546Sopenharmony_ci                            device->meta_state.btoi_r32g32b32.img_p_layout,
1455bf215546Sopenharmony_ci                            VK_SHADER_STAGE_COMPUTE_BIT, 0, 16, push_constants);
1456bf215546Sopenharmony_ci
1457bf215546Sopenharmony_ci      radv_unaligned_dispatch(cmd_buffer, rects[r].width, rects[r].height, 1);
1458bf215546Sopenharmony_ci   }
1459bf215546Sopenharmony_ci
1460bf215546Sopenharmony_ci   radv_buffer_view_finish(&src_view);
1461bf215546Sopenharmony_ci   radv_buffer_view_finish(&dst_view);
1462bf215546Sopenharmony_ci   radv_DestroyBuffer(radv_device_to_handle(device), buffer, NULL);
1463bf215546Sopenharmony_ci}
1464bf215546Sopenharmony_ci
1465bf215546Sopenharmony_cistatic void
1466bf215546Sopenharmony_cibtoi_bind_descriptors(struct radv_cmd_buffer *cmd_buffer, struct radv_buffer_view *src,
1467bf215546Sopenharmony_ci                      struct radv_image_view *dst)
1468bf215546Sopenharmony_ci{
1469bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
1470bf215546Sopenharmony_ci
1471bf215546Sopenharmony_ci   radv_meta_push_descriptor_set(
1472bf215546Sopenharmony_ci      cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, device->meta_state.btoi.img_p_layout, 0, /* set */
1473bf215546Sopenharmony_ci      2, /* descriptorWriteCount */
1474bf215546Sopenharmony_ci      (VkWriteDescriptorSet[]){
1475bf215546Sopenharmony_ci         {
1476bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1477bf215546Sopenharmony_ci            .dstBinding = 0,
1478bf215546Sopenharmony_ci            .dstArrayElement = 0,
1479bf215546Sopenharmony_ci            .descriptorCount = 1,
1480bf215546Sopenharmony_ci            .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
1481bf215546Sopenharmony_ci            .pTexelBufferView = (VkBufferView[]){radv_buffer_view_to_handle(src)},
1482bf215546Sopenharmony_ci         },
1483bf215546Sopenharmony_ci         {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1484bf215546Sopenharmony_ci          .dstBinding = 1,
1485bf215546Sopenharmony_ci          .dstArrayElement = 0,
1486bf215546Sopenharmony_ci          .descriptorCount = 1,
1487bf215546Sopenharmony_ci          .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1488bf215546Sopenharmony_ci          .pImageInfo = (VkDescriptorImageInfo[]){
1489bf215546Sopenharmony_ci             {
1490bf215546Sopenharmony_ci                .sampler = VK_NULL_HANDLE,
1491bf215546Sopenharmony_ci                .imageView = radv_image_view_to_handle(dst),
1492bf215546Sopenharmony_ci                .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
1493bf215546Sopenharmony_ci             },
1494bf215546Sopenharmony_ci          }}});
1495bf215546Sopenharmony_ci}
1496bf215546Sopenharmony_ci
1497bf215546Sopenharmony_civoid
1498bf215546Sopenharmony_ciradv_meta_buffer_to_image_cs(struct radv_cmd_buffer *cmd_buffer,
1499bf215546Sopenharmony_ci                             struct radv_meta_blit2d_buffer *src, struct radv_meta_blit2d_surf *dst,
1500bf215546Sopenharmony_ci                             unsigned num_rects, struct radv_meta_blit2d_rect *rects)
1501bf215546Sopenharmony_ci{
1502bf215546Sopenharmony_ci   VkPipeline pipeline = cmd_buffer->device->meta_state.btoi.pipeline;
1503bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
1504bf215546Sopenharmony_ci   struct radv_buffer_view src_view;
1505bf215546Sopenharmony_ci   struct radv_image_view dst_view;
1506bf215546Sopenharmony_ci
1507bf215546Sopenharmony_ci   if (dst->image->vk.format == VK_FORMAT_R32G32B32_UINT ||
1508bf215546Sopenharmony_ci       dst->image->vk.format == VK_FORMAT_R32G32B32_SINT ||
1509bf215546Sopenharmony_ci       dst->image->vk.format == VK_FORMAT_R32G32B32_SFLOAT) {
1510bf215546Sopenharmony_ci      radv_meta_buffer_to_image_cs_r32g32b32(cmd_buffer, src, dst, num_rects, rects);
1511bf215546Sopenharmony_ci      return;
1512bf215546Sopenharmony_ci   }
1513bf215546Sopenharmony_ci
1514bf215546Sopenharmony_ci   create_bview(cmd_buffer, src->buffer, src->offset, src->format, &src_view);
1515bf215546Sopenharmony_ci   create_iview(cmd_buffer, dst, &dst_view, VK_FORMAT_UNDEFINED, dst->aspect_mask);
1516bf215546Sopenharmony_ci   btoi_bind_descriptors(cmd_buffer, &src_view, &dst_view);
1517bf215546Sopenharmony_ci
1518bf215546Sopenharmony_ci   if (dst->image->vk.image_type == VK_IMAGE_TYPE_3D)
1519bf215546Sopenharmony_ci      pipeline = cmd_buffer->device->meta_state.btoi.pipeline_3d;
1520bf215546Sopenharmony_ci   radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE,
1521bf215546Sopenharmony_ci                        pipeline);
1522bf215546Sopenharmony_ci
1523bf215546Sopenharmony_ci   for (unsigned r = 0; r < num_rects; ++r) {
1524bf215546Sopenharmony_ci      unsigned push_constants[4] = {
1525bf215546Sopenharmony_ci         rects[r].dst_x,
1526bf215546Sopenharmony_ci         rects[r].dst_y,
1527bf215546Sopenharmony_ci         dst->layer,
1528bf215546Sopenharmony_ci         src->pitch,
1529bf215546Sopenharmony_ci      };
1530bf215546Sopenharmony_ci      radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
1531bf215546Sopenharmony_ci                            device->meta_state.btoi.img_p_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0,
1532bf215546Sopenharmony_ci                            16, push_constants);
1533bf215546Sopenharmony_ci
1534bf215546Sopenharmony_ci      radv_unaligned_dispatch(cmd_buffer, rects[r].width, rects[r].height, 1);
1535bf215546Sopenharmony_ci   }
1536bf215546Sopenharmony_ci
1537bf215546Sopenharmony_ci   radv_image_view_finish(&dst_view);
1538bf215546Sopenharmony_ci   radv_buffer_view_finish(&src_view);
1539bf215546Sopenharmony_ci}
1540bf215546Sopenharmony_ci
1541bf215546Sopenharmony_cistatic void
1542bf215546Sopenharmony_ciitoi_r32g32b32_bind_descriptors(struct radv_cmd_buffer *cmd_buffer, struct radv_buffer_view *src,
1543bf215546Sopenharmony_ci                                struct radv_buffer_view *dst)
1544bf215546Sopenharmony_ci{
1545bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
1546bf215546Sopenharmony_ci
1547bf215546Sopenharmony_ci   radv_meta_push_descriptor_set(
1548bf215546Sopenharmony_ci      cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, device->meta_state.itoi_r32g32b32.img_p_layout,
1549bf215546Sopenharmony_ci      0, /* set */
1550bf215546Sopenharmony_ci      2, /* descriptorWriteCount */
1551bf215546Sopenharmony_ci      (VkWriteDescriptorSet[]){
1552bf215546Sopenharmony_ci         {
1553bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1554bf215546Sopenharmony_ci            .dstBinding = 0,
1555bf215546Sopenharmony_ci            .dstArrayElement = 0,
1556bf215546Sopenharmony_ci            .descriptorCount = 1,
1557bf215546Sopenharmony_ci            .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
1558bf215546Sopenharmony_ci            .pTexelBufferView = (VkBufferView[]){radv_buffer_view_to_handle(src)},
1559bf215546Sopenharmony_ci         },
1560bf215546Sopenharmony_ci         {
1561bf215546Sopenharmony_ci            .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1562bf215546Sopenharmony_ci            .dstBinding = 1,
1563bf215546Sopenharmony_ci            .dstArrayElement = 0,
1564bf215546Sopenharmony_ci            .descriptorCount = 1,
1565bf215546Sopenharmony_ci            .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
1566bf215546Sopenharmony_ci            .pTexelBufferView = (VkBufferView[]){radv_buffer_view_to_handle(dst)},
1567bf215546Sopenharmony_ci         }});
1568bf215546Sopenharmony_ci}
1569bf215546Sopenharmony_ci
1570bf215546Sopenharmony_cistatic void
1571bf215546Sopenharmony_ciradv_meta_image_to_image_cs_r32g32b32(struct radv_cmd_buffer *cmd_buffer,
1572bf215546Sopenharmony_ci                                      struct radv_meta_blit2d_surf *src,
1573bf215546Sopenharmony_ci                                      struct radv_meta_blit2d_surf *dst, unsigned num_rects,
1574bf215546Sopenharmony_ci                                      struct radv_meta_blit2d_rect *rects)
1575bf215546Sopenharmony_ci{
1576bf215546Sopenharmony_ci   VkPipeline pipeline = cmd_buffer->device->meta_state.itoi_r32g32b32.pipeline;
1577bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
1578bf215546Sopenharmony_ci   struct radv_buffer_view src_view, dst_view;
1579bf215546Sopenharmony_ci   unsigned src_offset = 0, dst_offset = 0;
1580bf215546Sopenharmony_ci   unsigned src_stride, dst_stride;
1581bf215546Sopenharmony_ci   VkBuffer src_buffer, dst_buffer;
1582bf215546Sopenharmony_ci
1583bf215546Sopenharmony_ci   /* 96-bit formats are only compatible to themselves. */
1584bf215546Sopenharmony_ci   assert(dst->format == VK_FORMAT_R32G32B32_UINT || dst->format == VK_FORMAT_R32G32B32_SINT ||
1585bf215546Sopenharmony_ci          dst->format == VK_FORMAT_R32G32B32_SFLOAT);
1586bf215546Sopenharmony_ci
1587bf215546Sopenharmony_ci   /* This special itoi path for R32G32B32 formats will write the linear
1588bf215546Sopenharmony_ci    * image as a buffer with the same underlying memory. The compute
1589bf215546Sopenharmony_ci    * shader will copy all components separately using a R32 format.
1590bf215546Sopenharmony_ci    */
1591bf215546Sopenharmony_ci   create_buffer_from_image(cmd_buffer, src, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, &src_buffer);
1592bf215546Sopenharmony_ci   create_buffer_from_image(cmd_buffer, dst, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, &dst_buffer);
1593bf215546Sopenharmony_ci
1594bf215546Sopenharmony_ci   create_bview_for_r32g32b32(cmd_buffer, radv_buffer_from_handle(src_buffer), src_offset,
1595bf215546Sopenharmony_ci                              src->format, &src_view);
1596bf215546Sopenharmony_ci   create_bview_for_r32g32b32(cmd_buffer, radv_buffer_from_handle(dst_buffer), dst_offset,
1597bf215546Sopenharmony_ci                              dst->format, &dst_view);
1598bf215546Sopenharmony_ci   itoi_r32g32b32_bind_descriptors(cmd_buffer, &src_view, &dst_view);
1599bf215546Sopenharmony_ci
1600bf215546Sopenharmony_ci   radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE,
1601bf215546Sopenharmony_ci                        pipeline);
1602bf215546Sopenharmony_ci
1603bf215546Sopenharmony_ci   src_stride = get_image_stride_for_r32g32b32(cmd_buffer, src);
1604bf215546Sopenharmony_ci   dst_stride = get_image_stride_for_r32g32b32(cmd_buffer, dst);
1605bf215546Sopenharmony_ci
1606bf215546Sopenharmony_ci   for (unsigned r = 0; r < num_rects; ++r) {
1607bf215546Sopenharmony_ci      unsigned push_constants[6] = {
1608bf215546Sopenharmony_ci         rects[r].src_x, rects[r].src_y, src_stride, rects[r].dst_x, rects[r].dst_y, dst_stride,
1609bf215546Sopenharmony_ci      };
1610bf215546Sopenharmony_ci      radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
1611bf215546Sopenharmony_ci                            device->meta_state.itoi_r32g32b32.img_p_layout,
1612bf215546Sopenharmony_ci                            VK_SHADER_STAGE_COMPUTE_BIT, 0, 24, push_constants);
1613bf215546Sopenharmony_ci
1614bf215546Sopenharmony_ci      radv_unaligned_dispatch(cmd_buffer, rects[r].width, rects[r].height, 1);
1615bf215546Sopenharmony_ci   }
1616bf215546Sopenharmony_ci
1617bf215546Sopenharmony_ci   radv_buffer_view_finish(&src_view);
1618bf215546Sopenharmony_ci   radv_buffer_view_finish(&dst_view);
1619bf215546Sopenharmony_ci   radv_DestroyBuffer(radv_device_to_handle(device), src_buffer, NULL);
1620bf215546Sopenharmony_ci   radv_DestroyBuffer(radv_device_to_handle(device), dst_buffer, NULL);
1621bf215546Sopenharmony_ci}
1622bf215546Sopenharmony_ci
1623bf215546Sopenharmony_cistatic void
1624bf215546Sopenharmony_ciitoi_bind_descriptors(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src,
1625bf215546Sopenharmony_ci                      struct radv_image_view *dst)
1626bf215546Sopenharmony_ci{
1627bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
1628bf215546Sopenharmony_ci
1629bf215546Sopenharmony_ci   radv_meta_push_descriptor_set(
1630bf215546Sopenharmony_ci      cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, device->meta_state.itoi.img_p_layout, 0, /* set */
1631bf215546Sopenharmony_ci      2, /* descriptorWriteCount */
1632bf215546Sopenharmony_ci      (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1633bf215546Sopenharmony_ci                                .dstBinding = 0,
1634bf215546Sopenharmony_ci                                .dstArrayElement = 0,
1635bf215546Sopenharmony_ci                                .descriptorCount = 1,
1636bf215546Sopenharmony_ci                                .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
1637bf215546Sopenharmony_ci                                .pImageInfo =
1638bf215546Sopenharmony_ci                                   (VkDescriptorImageInfo[]){
1639bf215546Sopenharmony_ci                                      {
1640bf215546Sopenharmony_ci                                         .sampler = VK_NULL_HANDLE,
1641bf215546Sopenharmony_ci                                         .imageView = radv_image_view_to_handle(src),
1642bf215546Sopenharmony_ci                                         .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
1643bf215546Sopenharmony_ci                                      },
1644bf215546Sopenharmony_ci                                   }},
1645bf215546Sopenharmony_ci                               {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1646bf215546Sopenharmony_ci                                .dstBinding = 1,
1647bf215546Sopenharmony_ci                                .dstArrayElement = 0,
1648bf215546Sopenharmony_ci                                .descriptorCount = 1,
1649bf215546Sopenharmony_ci                                .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1650bf215546Sopenharmony_ci                                .pImageInfo = (VkDescriptorImageInfo[]){
1651bf215546Sopenharmony_ci                                   {
1652bf215546Sopenharmony_ci                                      .sampler = VK_NULL_HANDLE,
1653bf215546Sopenharmony_ci                                      .imageView = radv_image_view_to_handle(dst),
1654bf215546Sopenharmony_ci                                      .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
1655bf215546Sopenharmony_ci                                   },
1656bf215546Sopenharmony_ci                                }}});
1657bf215546Sopenharmony_ci}
1658bf215546Sopenharmony_ci
1659bf215546Sopenharmony_civoid
1660bf215546Sopenharmony_ciradv_meta_image_to_image_cs(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *src,
1661bf215546Sopenharmony_ci                            struct radv_meta_blit2d_surf *dst, unsigned num_rects,
1662bf215546Sopenharmony_ci                            struct radv_meta_blit2d_rect *rects)
1663bf215546Sopenharmony_ci{
1664bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
1665bf215546Sopenharmony_ci   struct radv_image_view src_view, dst_view;
1666bf215546Sopenharmony_ci   uint32_t samples = src->image->info.samples;
1667bf215546Sopenharmony_ci   uint32_t samples_log2 = ffs(samples) - 1;
1668bf215546Sopenharmony_ci
1669bf215546Sopenharmony_ci   if (src->format == VK_FORMAT_R32G32B32_UINT || src->format == VK_FORMAT_R32G32B32_SINT ||
1670bf215546Sopenharmony_ci       src->format == VK_FORMAT_R32G32B32_SFLOAT) {
1671bf215546Sopenharmony_ci      radv_meta_image_to_image_cs_r32g32b32(cmd_buffer, src, dst, num_rects, rects);
1672bf215546Sopenharmony_ci      return;
1673bf215546Sopenharmony_ci   }
1674bf215546Sopenharmony_ci
1675bf215546Sopenharmony_ci   u_foreach_bit(i, dst->aspect_mask) {
1676bf215546Sopenharmony_ci      unsigned aspect_mask = 1u << i;
1677bf215546Sopenharmony_ci      VkFormat depth_format = 0;
1678bf215546Sopenharmony_ci      if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
1679bf215546Sopenharmony_ci         depth_format = vk_format_stencil_only(dst->image->vk.format);
1680bf215546Sopenharmony_ci      else if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT)
1681bf215546Sopenharmony_ci         depth_format = vk_format_depth_only(dst->image->vk.format);
1682bf215546Sopenharmony_ci
1683bf215546Sopenharmony_ci      create_iview(cmd_buffer, src, &src_view, depth_format, aspect_mask);
1684bf215546Sopenharmony_ci      create_iview(cmd_buffer, dst, &dst_view, depth_format, aspect_mask);
1685bf215546Sopenharmony_ci
1686bf215546Sopenharmony_ci      itoi_bind_descriptors(cmd_buffer, &src_view, &dst_view);
1687bf215546Sopenharmony_ci
1688bf215546Sopenharmony_ci      VkPipeline pipeline = cmd_buffer->device->meta_state.itoi.pipeline[samples_log2];
1689bf215546Sopenharmony_ci      if (src->image->vk.image_type == VK_IMAGE_TYPE_3D ||
1690bf215546Sopenharmony_ci          dst->image->vk.image_type == VK_IMAGE_TYPE_3D)
1691bf215546Sopenharmony_ci         pipeline = cmd_buffer->device->meta_state.itoi.pipeline_3d;
1692bf215546Sopenharmony_ci      radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE,
1693bf215546Sopenharmony_ci                           pipeline);
1694bf215546Sopenharmony_ci
1695bf215546Sopenharmony_ci      for (unsigned r = 0; r < num_rects; ++r) {
1696bf215546Sopenharmony_ci         unsigned push_constants[6] = {
1697bf215546Sopenharmony_ci            rects[r].src_x, rects[r].src_y, src->layer, rects[r].dst_x, rects[r].dst_y, dst->layer,
1698bf215546Sopenharmony_ci         };
1699bf215546Sopenharmony_ci         radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
1700bf215546Sopenharmony_ci                               device->meta_state.itoi.img_p_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0,
1701bf215546Sopenharmony_ci                               24, push_constants);
1702bf215546Sopenharmony_ci
1703bf215546Sopenharmony_ci         radv_unaligned_dispatch(cmd_buffer, rects[r].width, rects[r].height, 1);
1704bf215546Sopenharmony_ci      }
1705bf215546Sopenharmony_ci
1706bf215546Sopenharmony_ci      radv_image_view_finish(&src_view);
1707bf215546Sopenharmony_ci      radv_image_view_finish(&dst_view);
1708bf215546Sopenharmony_ci   }
1709bf215546Sopenharmony_ci}
1710bf215546Sopenharmony_ci
1711bf215546Sopenharmony_cistatic void
1712bf215546Sopenharmony_cicleari_r32g32b32_bind_descriptors(struct radv_cmd_buffer *cmd_buffer, struct radv_buffer_view *view)
1713bf215546Sopenharmony_ci{
1714bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
1715bf215546Sopenharmony_ci
1716bf215546Sopenharmony_ci   radv_meta_push_descriptor_set(
1717bf215546Sopenharmony_ci      cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, device->meta_state.cleari_r32g32b32.img_p_layout,
1718bf215546Sopenharmony_ci      0, /* set */
1719bf215546Sopenharmony_ci      1, /* descriptorWriteCount */
1720bf215546Sopenharmony_ci      (VkWriteDescriptorSet[]){{
1721bf215546Sopenharmony_ci         .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1722bf215546Sopenharmony_ci         .dstBinding = 0,
1723bf215546Sopenharmony_ci         .dstArrayElement = 0,
1724bf215546Sopenharmony_ci         .descriptorCount = 1,
1725bf215546Sopenharmony_ci         .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
1726bf215546Sopenharmony_ci         .pTexelBufferView = (VkBufferView[]){radv_buffer_view_to_handle(view)},
1727bf215546Sopenharmony_ci      }});
1728bf215546Sopenharmony_ci}
1729bf215546Sopenharmony_ci
1730bf215546Sopenharmony_cistatic void
1731bf215546Sopenharmony_ciradv_meta_clear_image_cs_r32g32b32(struct radv_cmd_buffer *cmd_buffer,
1732bf215546Sopenharmony_ci                                   struct radv_meta_blit2d_surf *dst,
1733bf215546Sopenharmony_ci                                   const VkClearColorValue *clear_color)
1734bf215546Sopenharmony_ci{
1735bf215546Sopenharmony_ci   VkPipeline pipeline = cmd_buffer->device->meta_state.cleari_r32g32b32.pipeline;
1736bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
1737bf215546Sopenharmony_ci   struct radv_buffer_view dst_view;
1738bf215546Sopenharmony_ci   unsigned stride;
1739bf215546Sopenharmony_ci   VkBuffer buffer;
1740bf215546Sopenharmony_ci
1741bf215546Sopenharmony_ci   /* This special clear path for R32G32B32 formats will write the linear
1742bf215546Sopenharmony_ci    * image as a buffer with the same underlying memory. The compute
1743bf215546Sopenharmony_ci    * shader will clear all components separately using a R32 format.
1744bf215546Sopenharmony_ci    */
1745bf215546Sopenharmony_ci   create_buffer_from_image(cmd_buffer, dst, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, &buffer);
1746bf215546Sopenharmony_ci
1747bf215546Sopenharmony_ci   create_bview_for_r32g32b32(cmd_buffer, radv_buffer_from_handle(buffer), 0, dst->format,
1748bf215546Sopenharmony_ci                              &dst_view);
1749bf215546Sopenharmony_ci   cleari_r32g32b32_bind_descriptors(cmd_buffer, &dst_view);
1750bf215546Sopenharmony_ci
1751bf215546Sopenharmony_ci   radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE,
1752bf215546Sopenharmony_ci                        pipeline);
1753bf215546Sopenharmony_ci
1754bf215546Sopenharmony_ci   stride = get_image_stride_for_r32g32b32(cmd_buffer, dst);
1755bf215546Sopenharmony_ci
1756bf215546Sopenharmony_ci   unsigned push_constants[4] = {
1757bf215546Sopenharmony_ci      clear_color->uint32[0],
1758bf215546Sopenharmony_ci      clear_color->uint32[1],
1759bf215546Sopenharmony_ci      clear_color->uint32[2],
1760bf215546Sopenharmony_ci      stride,
1761bf215546Sopenharmony_ci   };
1762bf215546Sopenharmony_ci
1763bf215546Sopenharmony_ci   radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
1764bf215546Sopenharmony_ci                         device->meta_state.cleari_r32g32b32.img_p_layout,
1765bf215546Sopenharmony_ci                         VK_SHADER_STAGE_COMPUTE_BIT, 0, 16, push_constants);
1766bf215546Sopenharmony_ci
1767bf215546Sopenharmony_ci   radv_unaligned_dispatch(cmd_buffer, dst->image->info.width, dst->image->info.height, 1);
1768bf215546Sopenharmony_ci
1769bf215546Sopenharmony_ci   radv_buffer_view_finish(&dst_view);
1770bf215546Sopenharmony_ci   radv_DestroyBuffer(radv_device_to_handle(device), buffer, NULL);
1771bf215546Sopenharmony_ci}
1772bf215546Sopenharmony_ci
1773bf215546Sopenharmony_cistatic void
1774bf215546Sopenharmony_cicleari_bind_descriptors(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *dst_iview)
1775bf215546Sopenharmony_ci{
1776bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
1777bf215546Sopenharmony_ci
1778bf215546Sopenharmony_ci   radv_meta_push_descriptor_set(cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE,
1779bf215546Sopenharmony_ci                                 device->meta_state.cleari.img_p_layout, 0, /* set */
1780bf215546Sopenharmony_ci                                 1, /* descriptorWriteCount */
1781bf215546Sopenharmony_ci                                 (VkWriteDescriptorSet[]){
1782bf215546Sopenharmony_ci                                    {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1783bf215546Sopenharmony_ci                                     .dstBinding = 0,
1784bf215546Sopenharmony_ci                                     .dstArrayElement = 0,
1785bf215546Sopenharmony_ci                                     .descriptorCount = 1,
1786bf215546Sopenharmony_ci                                     .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1787bf215546Sopenharmony_ci                                     .pImageInfo =
1788bf215546Sopenharmony_ci                                        (VkDescriptorImageInfo[]){
1789bf215546Sopenharmony_ci                                           {
1790bf215546Sopenharmony_ci                                              .sampler = VK_NULL_HANDLE,
1791bf215546Sopenharmony_ci                                              .imageView = radv_image_view_to_handle(dst_iview),
1792bf215546Sopenharmony_ci                                              .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
1793bf215546Sopenharmony_ci                                           },
1794bf215546Sopenharmony_ci                                        }},
1795bf215546Sopenharmony_ci                                 });
1796bf215546Sopenharmony_ci}
1797bf215546Sopenharmony_ci
1798bf215546Sopenharmony_civoid
1799bf215546Sopenharmony_ciradv_meta_clear_image_cs(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *dst,
1800bf215546Sopenharmony_ci                         const VkClearColorValue *clear_color)
1801bf215546Sopenharmony_ci{
1802bf215546Sopenharmony_ci   struct radv_device *device = cmd_buffer->device;
1803bf215546Sopenharmony_ci   struct radv_image_view dst_iview;
1804bf215546Sopenharmony_ci   uint32_t samples = dst->image->info.samples;
1805bf215546Sopenharmony_ci   uint32_t samples_log2 = ffs(samples) - 1;
1806bf215546Sopenharmony_ci
1807bf215546Sopenharmony_ci   if (dst->format == VK_FORMAT_R32G32B32_UINT || dst->format == VK_FORMAT_R32G32B32_SINT ||
1808bf215546Sopenharmony_ci       dst->format == VK_FORMAT_R32G32B32_SFLOAT) {
1809bf215546Sopenharmony_ci      radv_meta_clear_image_cs_r32g32b32(cmd_buffer, dst, clear_color);
1810bf215546Sopenharmony_ci      return;
1811bf215546Sopenharmony_ci   }
1812bf215546Sopenharmony_ci
1813bf215546Sopenharmony_ci   create_iview(cmd_buffer, dst, &dst_iview, VK_FORMAT_UNDEFINED, dst->aspect_mask);
1814bf215546Sopenharmony_ci   cleari_bind_descriptors(cmd_buffer, &dst_iview);
1815bf215546Sopenharmony_ci
1816bf215546Sopenharmony_ci   VkPipeline pipeline = cmd_buffer->device->meta_state.cleari.pipeline[samples_log2];
1817bf215546Sopenharmony_ci   if (dst->image->vk.image_type == VK_IMAGE_TYPE_3D)
1818bf215546Sopenharmony_ci      pipeline = cmd_buffer->device->meta_state.cleari.pipeline_3d;
1819bf215546Sopenharmony_ci
1820bf215546Sopenharmony_ci   radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE,
1821bf215546Sopenharmony_ci                        pipeline);
1822bf215546Sopenharmony_ci
1823bf215546Sopenharmony_ci   unsigned push_constants[5] = {
1824bf215546Sopenharmony_ci      clear_color->uint32[0],
1825bf215546Sopenharmony_ci      clear_color->uint32[1],
1826bf215546Sopenharmony_ci      clear_color->uint32[2],
1827bf215546Sopenharmony_ci      clear_color->uint32[3],
1828bf215546Sopenharmony_ci      dst->layer,
1829bf215546Sopenharmony_ci   };
1830bf215546Sopenharmony_ci
1831bf215546Sopenharmony_ci   radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
1832bf215546Sopenharmony_ci                         device->meta_state.cleari.img_p_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, 20,
1833bf215546Sopenharmony_ci                         push_constants);
1834bf215546Sopenharmony_ci
1835bf215546Sopenharmony_ci   radv_unaligned_dispatch(cmd_buffer, dst->image->info.width, dst->image->info.height, 1);
1836bf215546Sopenharmony_ci
1837bf215546Sopenharmony_ci   radv_image_view_finish(&dst_iview);
1838bf215546Sopenharmony_ci}
1839