a40d4b430c13f8e333c79d7ec119130c77e8f4a3
[mesa.git] / src / amd / vulkan / radv_meta_bufimage.c
1 /*
2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24 #include "radv_meta.h"
25 #include "nir/nir_builder.h"
26
27 /*
28 * GFX queue: Compute shader implementation of image->buffer copy
29 * Compute queue: implementation also of buffer->image, image->image, and image clear.
30 */
31
32 static nir_shader *
33 build_nir_itob_compute_shader(struct radv_device *dev)
34 {
35 nir_builder b;
36 const struct glsl_type *sampler_type = glsl_sampler_type(GLSL_SAMPLER_DIM_2D,
37 false,
38 false,
39 GLSL_TYPE_FLOAT);
40 const struct glsl_type *img_type = glsl_sampler_type(GLSL_SAMPLER_DIM_BUF,
41 false,
42 false,
43 GLSL_TYPE_FLOAT);
44 nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_COMPUTE, NULL);
45 b.shader->info->name = ralloc_strdup(b.shader, "meta_itob_cs");
46 b.shader->info->cs.local_size[0] = 16;
47 b.shader->info->cs.local_size[1] = 16;
48 b.shader->info->cs.local_size[2] = 1;
49 nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform,
50 sampler_type, "s_tex");
51 input_img->data.descriptor_set = 0;
52 input_img->data.binding = 0;
53
54 nir_variable *output_img = nir_variable_create(b.shader, nir_var_uniform,
55 img_type, "out_img");
56 output_img->data.descriptor_set = 0;
57 output_img->data.binding = 1;
58
59 nir_ssa_def *invoc_id = nir_load_system_value(&b, nir_intrinsic_load_local_invocation_id, 0);
60 nir_ssa_def *wg_id = nir_load_system_value(&b, nir_intrinsic_load_work_group_id, 0);
61 nir_ssa_def *block_size = nir_imm_ivec4(&b,
62 b.shader->info->cs.local_size[0],
63 b.shader->info->cs.local_size[1],
64 b.shader->info->cs.local_size[2], 0);
65
66 nir_ssa_def *global_id = nir_iadd(&b, nir_imul(&b, wg_id, block_size), invoc_id);
67
68
69
70 nir_intrinsic_instr *offset = nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_push_constant);
71 nir_intrinsic_set_base(offset, 0);
72 nir_intrinsic_set_range(offset, 12);
73 offset->src[0] = nir_src_for_ssa(nir_imm_int(&b, 0));
74 offset->num_components = 2;
75 nir_ssa_dest_init(&offset->instr, &offset->dest, 2, 32, "offset");
76 nir_builder_instr_insert(&b, &offset->instr);
77
78 nir_intrinsic_instr *stride = nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_push_constant);
79 nir_intrinsic_set_base(stride, 0);
80 nir_intrinsic_set_range(stride, 12);
81 stride->src[0] = nir_src_for_ssa(nir_imm_int(&b, 8));
82 stride->num_components = 1;
83 nir_ssa_dest_init(&stride->instr, &stride->dest, 1, 32, "stride");
84 nir_builder_instr_insert(&b, &stride->instr);
85
86 nir_ssa_def *img_coord = nir_iadd(&b, global_id, &offset->dest.ssa);
87
88 nir_tex_instr *tex = nir_tex_instr_create(b.shader, 2);
89 tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
90 tex->op = nir_texop_txf;
91 tex->src[0].src_type = nir_tex_src_coord;
92 tex->src[0].src = nir_src_for_ssa(nir_channels(&b, img_coord, 0x3));
93 tex->src[1].src_type = nir_tex_src_lod;
94 tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0));
95 tex->dest_type = nir_type_float;
96 tex->is_array = false;
97 tex->coord_components = 2;
98 tex->texture = nir_deref_var_create(tex, input_img);
99 tex->sampler = NULL;
100
101 nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
102 nir_builder_instr_insert(&b, &tex->instr);
103
104 nir_ssa_def *pos_x = nir_channel(&b, global_id, 0);
105 nir_ssa_def *pos_y = nir_channel(&b, global_id, 1);
106
107 nir_ssa_def *tmp = nir_imul(&b, pos_y, &stride->dest.ssa);
108 tmp = nir_iadd(&b, tmp, pos_x);
109
110 nir_ssa_def *coord = nir_vec4(&b, tmp, tmp, tmp, tmp);
111
112 nir_ssa_def *outval = &tex->dest.ssa;
113 nir_intrinsic_instr *store = nir_intrinsic_instr_create(b.shader, nir_intrinsic_image_store);
114 store->src[0] = nir_src_for_ssa(coord);
115 store->src[1] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
116 store->src[2] = nir_src_for_ssa(outval);
117 store->variables[0] = nir_deref_var_create(store, output_img);
118
119 nir_builder_instr_insert(&b, &store->instr);
120 return b.shader;
121 }
122
123 /* Image to buffer - don't write use image accessors */
124 static VkResult
125 radv_device_init_meta_itob_state(struct radv_device *device)
126 {
127 VkResult result;
128 struct radv_shader_module cs = { .nir = NULL };
129
130 zero(device->meta_state.itob);
131
132 cs.nir = build_nir_itob_compute_shader(device);
133
134 /*
135 * two descriptors one for the image being sampled
136 * one for the buffer being written.
137 */
138 VkDescriptorSetLayoutCreateInfo ds_create_info = {
139 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
140 .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
141 .bindingCount = 2,
142 .pBindings = (VkDescriptorSetLayoutBinding[]) {
143 {
144 .binding = 0,
145 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
146 .descriptorCount = 1,
147 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
148 .pImmutableSamplers = NULL
149 },
150 {
151 .binding = 1,
152 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
153 .descriptorCount = 1,
154 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
155 .pImmutableSamplers = NULL
156 },
157 }
158 };
159
160 result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device),
161 &ds_create_info,
162 &device->meta_state.alloc,
163 &device->meta_state.itob.img_ds_layout);
164 if (result != VK_SUCCESS)
165 goto fail;
166
167
168 VkPipelineLayoutCreateInfo pl_create_info = {
169 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
170 .setLayoutCount = 1,
171 .pSetLayouts = &device->meta_state.itob.img_ds_layout,
172 .pushConstantRangeCount = 1,
173 .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_COMPUTE_BIT, 0, 12},
174 };
175
176 result = radv_CreatePipelineLayout(radv_device_to_handle(device),
177 &pl_create_info,
178 &device->meta_state.alloc,
179 &device->meta_state.itob.img_p_layout);
180 if (result != VK_SUCCESS)
181 goto fail;
182
183 /* compute shader */
184
185 VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
186 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
187 .stage = VK_SHADER_STAGE_COMPUTE_BIT,
188 .module = radv_shader_module_to_handle(&cs),
189 .pName = "main",
190 .pSpecializationInfo = NULL,
191 };
192
193 VkComputePipelineCreateInfo vk_pipeline_info = {
194 .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
195 .stage = pipeline_shader_stage,
196 .flags = 0,
197 .layout = device->meta_state.itob.img_p_layout,
198 };
199
200 result = radv_CreateComputePipelines(radv_device_to_handle(device),
201 radv_pipeline_cache_to_handle(&device->meta_state.cache),
202 1, &vk_pipeline_info, NULL,
203 &device->meta_state.itob.pipeline);
204 if (result != VK_SUCCESS)
205 goto fail;
206
207 ralloc_free(cs.nir);
208 return VK_SUCCESS;
209 fail:
210 ralloc_free(cs.nir);
211 return result;
212 }
213
214 static void
215 radv_device_finish_meta_itob_state(struct radv_device *device)
216 {
217 if (device->meta_state.itob.img_p_layout) {
218 radv_DestroyPipelineLayout(radv_device_to_handle(device),
219 device->meta_state.itob.img_p_layout,
220 &device->meta_state.alloc);
221 }
222 if (device->meta_state.itob.img_ds_layout) {
223 radv_DestroyDescriptorSetLayout(radv_device_to_handle(device),
224 device->meta_state.itob.img_ds_layout,
225 &device->meta_state.alloc);
226 }
227 if (device->meta_state.itob.pipeline) {
228 radv_DestroyPipeline(radv_device_to_handle(device),
229 device->meta_state.itob.pipeline,
230 &device->meta_state.alloc);
231 }
232 }
233
234 static nir_shader *
235 build_nir_btoi_compute_shader(struct radv_device *dev)
236 {
237 nir_builder b;
238 const struct glsl_type *buf_type = glsl_sampler_type(GLSL_SAMPLER_DIM_BUF,
239 false,
240 false,
241 GLSL_TYPE_FLOAT);
242 const struct glsl_type *img_type = glsl_sampler_type(GLSL_SAMPLER_DIM_2D,
243 false,
244 false,
245 GLSL_TYPE_FLOAT);
246 nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_COMPUTE, NULL);
247 b.shader->info->name = ralloc_strdup(b.shader, "meta_btoi_cs");
248 b.shader->info->cs.local_size[0] = 16;
249 b.shader->info->cs.local_size[1] = 16;
250 b.shader->info->cs.local_size[2] = 1;
251 nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform,
252 buf_type, "s_tex");
253 input_img->data.descriptor_set = 0;
254 input_img->data.binding = 0;
255
256 nir_variable *output_img = nir_variable_create(b.shader, nir_var_uniform,
257 img_type, "out_img");
258 output_img->data.descriptor_set = 0;
259 output_img->data.binding = 1;
260
261 nir_ssa_def *invoc_id = nir_load_system_value(&b, nir_intrinsic_load_local_invocation_id, 0);
262 nir_ssa_def *wg_id = nir_load_system_value(&b, nir_intrinsic_load_work_group_id, 0);
263 nir_ssa_def *block_size = nir_imm_ivec4(&b,
264 b.shader->info->cs.local_size[0],
265 b.shader->info->cs.local_size[1],
266 b.shader->info->cs.local_size[2], 0);
267
268 nir_ssa_def *global_id = nir_iadd(&b, nir_imul(&b, wg_id, block_size), invoc_id);
269
270 nir_intrinsic_instr *offset = nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_push_constant);
271 nir_intrinsic_set_base(offset, 0);
272 nir_intrinsic_set_range(offset, 12);
273 offset->src[0] = nir_src_for_ssa(nir_imm_int(&b, 0));
274 offset->num_components = 2;
275 nir_ssa_dest_init(&offset->instr, &offset->dest, 2, 32, "offset");
276 nir_builder_instr_insert(&b, &offset->instr);
277
278 nir_intrinsic_instr *stride = nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_push_constant);
279 nir_intrinsic_set_base(stride, 0);
280 nir_intrinsic_set_range(stride, 12);
281 stride->src[0] = nir_src_for_ssa(nir_imm_int(&b, 8));
282 stride->num_components = 1;
283 nir_ssa_dest_init(&stride->instr, &stride->dest, 1, 32, "stride");
284 nir_builder_instr_insert(&b, &stride->instr);
285
286 nir_ssa_def *pos_x = nir_channel(&b, global_id, 0);
287 nir_ssa_def *pos_y = nir_channel(&b, global_id, 1);
288
289 nir_ssa_def *tmp = nir_imul(&b, pos_y, &stride->dest.ssa);
290 tmp = nir_iadd(&b, tmp, pos_x);
291
292 nir_ssa_def *buf_coord = nir_vec4(&b, tmp, tmp, tmp, tmp);
293
294 nir_ssa_def *img_coord = nir_iadd(&b, global_id, &offset->dest.ssa);
295
296 nir_tex_instr *tex = nir_tex_instr_create(b.shader, 2);
297 tex->sampler_dim = GLSL_SAMPLER_DIM_BUF;
298 tex->op = nir_texop_txf;
299 tex->src[0].src_type = nir_tex_src_coord;
300 tex->src[0].src = nir_src_for_ssa(nir_channels(&b, buf_coord, 1));
301 tex->src[1].src_type = nir_tex_src_lod;
302 tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0));
303 tex->dest_type = nir_type_float;
304 tex->is_array = false;
305 tex->coord_components = 1;
306 tex->texture = nir_deref_var_create(tex, input_img);
307 tex->sampler = NULL;
308
309 nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
310 nir_builder_instr_insert(&b, &tex->instr);
311
312 nir_ssa_def *outval = &tex->dest.ssa;
313 nir_intrinsic_instr *store = nir_intrinsic_instr_create(b.shader, nir_intrinsic_image_store);
314 store->src[0] = nir_src_for_ssa(img_coord);
315 store->src[1] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
316 store->src[2] = nir_src_for_ssa(outval);
317 store->variables[0] = nir_deref_var_create(store, output_img);
318
319 nir_builder_instr_insert(&b, &store->instr);
320 return b.shader;
321 }
322
323 /* Buffer to image - don't write use image accessors */
324 static VkResult
325 radv_device_init_meta_btoi_state(struct radv_device *device)
326 {
327 VkResult result;
328 struct radv_shader_module cs = { .nir = NULL };
329
330 zero(device->meta_state.btoi);
331
332 cs.nir = build_nir_btoi_compute_shader(device);
333
334 /*
335 * two descriptors one for the image being sampled
336 * one for the buffer being written.
337 */
338 VkDescriptorSetLayoutCreateInfo ds_create_info = {
339 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
340 .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
341 .bindingCount = 2,
342 .pBindings = (VkDescriptorSetLayoutBinding[]) {
343 {
344 .binding = 0,
345 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
346 .descriptorCount = 1,
347 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
348 .pImmutableSamplers = NULL
349 },
350 {
351 .binding = 1,
352 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
353 .descriptorCount = 1,
354 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
355 .pImmutableSamplers = NULL
356 },
357 }
358 };
359
360 result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device),
361 &ds_create_info,
362 &device->meta_state.alloc,
363 &device->meta_state.btoi.img_ds_layout);
364 if (result != VK_SUCCESS)
365 goto fail;
366
367
368 VkPipelineLayoutCreateInfo pl_create_info = {
369 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
370 .setLayoutCount = 1,
371 .pSetLayouts = &device->meta_state.btoi.img_ds_layout,
372 .pushConstantRangeCount = 1,
373 .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_COMPUTE_BIT, 0, 12},
374 };
375
376 result = radv_CreatePipelineLayout(radv_device_to_handle(device),
377 &pl_create_info,
378 &device->meta_state.alloc,
379 &device->meta_state.btoi.img_p_layout);
380 if (result != VK_SUCCESS)
381 goto fail;
382
383 /* compute shader */
384
385 VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
386 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
387 .stage = VK_SHADER_STAGE_COMPUTE_BIT,
388 .module = radv_shader_module_to_handle(&cs),
389 .pName = "main",
390 .pSpecializationInfo = NULL,
391 };
392
393 VkComputePipelineCreateInfo vk_pipeline_info = {
394 .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
395 .stage = pipeline_shader_stage,
396 .flags = 0,
397 .layout = device->meta_state.btoi.img_p_layout,
398 };
399
400 result = radv_CreateComputePipelines(radv_device_to_handle(device),
401 radv_pipeline_cache_to_handle(&device->meta_state.cache),
402 1, &vk_pipeline_info, NULL,
403 &device->meta_state.btoi.pipeline);
404 if (result != VK_SUCCESS)
405 goto fail;
406
407 ralloc_free(cs.nir);
408 return VK_SUCCESS;
409 fail:
410 ralloc_free(cs.nir);
411 return result;
412 }
413
414 static void
415 radv_device_finish_meta_btoi_state(struct radv_device *device)
416 {
417 if (device->meta_state.btoi.img_p_layout) {
418 radv_DestroyPipelineLayout(radv_device_to_handle(device),
419 device->meta_state.btoi.img_p_layout,
420 &device->meta_state.alloc);
421 }
422 if (device->meta_state.btoi.img_ds_layout) {
423 radv_DestroyDescriptorSetLayout(radv_device_to_handle(device),
424 device->meta_state.btoi.img_ds_layout,
425 &device->meta_state.alloc);
426 }
427 if (device->meta_state.btoi.pipeline) {
428 radv_DestroyPipeline(radv_device_to_handle(device),
429 device->meta_state.btoi.pipeline,
430 &device->meta_state.alloc);
431 }
432 }
433
434 static nir_shader *
435 build_nir_itoi_compute_shader(struct radv_device *dev)
436 {
437 nir_builder b;
438 const struct glsl_type *buf_type = glsl_sampler_type(GLSL_SAMPLER_DIM_2D,
439 false,
440 false,
441 GLSL_TYPE_FLOAT);
442 const struct glsl_type *img_type = glsl_sampler_type(GLSL_SAMPLER_DIM_2D,
443 false,
444 false,
445 GLSL_TYPE_FLOAT);
446 nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_COMPUTE, NULL);
447 b.shader->info->name = ralloc_strdup(b.shader, "meta_itoi_cs");
448 b.shader->info->cs.local_size[0] = 16;
449 b.shader->info->cs.local_size[1] = 16;
450 b.shader->info->cs.local_size[2] = 1;
451 nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform,
452 buf_type, "s_tex");
453 input_img->data.descriptor_set = 0;
454 input_img->data.binding = 0;
455
456 nir_variable *output_img = nir_variable_create(b.shader, nir_var_uniform,
457 img_type, "out_img");
458 output_img->data.descriptor_set = 0;
459 output_img->data.binding = 1;
460
461 nir_ssa_def *invoc_id = nir_load_system_value(&b, nir_intrinsic_load_local_invocation_id, 0);
462 nir_ssa_def *wg_id = nir_load_system_value(&b, nir_intrinsic_load_work_group_id, 0);
463 nir_ssa_def *block_size = nir_imm_ivec4(&b,
464 b.shader->info->cs.local_size[0],
465 b.shader->info->cs.local_size[1],
466 b.shader->info->cs.local_size[2], 0);
467
468 nir_ssa_def *global_id = nir_iadd(&b, nir_imul(&b, wg_id, block_size), invoc_id);
469
470 nir_intrinsic_instr *src_offset = nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_push_constant);
471 nir_intrinsic_set_base(src_offset, 0);
472 nir_intrinsic_set_range(src_offset, 16);
473 src_offset->src[0] = nir_src_for_ssa(nir_imm_int(&b, 0));
474 src_offset->num_components = 2;
475 nir_ssa_dest_init(&src_offset->instr, &src_offset->dest, 2, 32, "src_offset");
476 nir_builder_instr_insert(&b, &src_offset->instr);
477
478 nir_intrinsic_instr *dst_offset = nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_push_constant);
479 nir_intrinsic_set_base(dst_offset, 0);
480 nir_intrinsic_set_range(dst_offset, 16);
481 dst_offset->src[0] = nir_src_for_ssa(nir_imm_int(&b, 8));
482 dst_offset->num_components = 2;
483 nir_ssa_dest_init(&dst_offset->instr, &dst_offset->dest, 2, 32, "dst_offset");
484 nir_builder_instr_insert(&b, &dst_offset->instr);
485
486 nir_ssa_def *src_coord = nir_iadd(&b, global_id, &src_offset->dest.ssa);
487
488 nir_ssa_def *dst_coord = nir_iadd(&b, global_id, &dst_offset->dest.ssa);
489
490 nir_tex_instr *tex = nir_tex_instr_create(b.shader, 2);
491 tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
492 tex->op = nir_texop_txf;
493 tex->src[0].src_type = nir_tex_src_coord;
494 tex->src[0].src = nir_src_for_ssa(nir_channels(&b, src_coord, 3));
495 tex->src[1].src_type = nir_tex_src_lod;
496 tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0));
497 tex->dest_type = nir_type_float;
498 tex->is_array = false;
499 tex->coord_components = 2;
500 tex->texture = nir_deref_var_create(tex, input_img);
501 tex->sampler = NULL;
502
503 nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
504 nir_builder_instr_insert(&b, &tex->instr);
505
506 nir_ssa_def *outval = &tex->dest.ssa;
507 nir_intrinsic_instr *store = nir_intrinsic_instr_create(b.shader, nir_intrinsic_image_store);
508 store->src[0] = nir_src_for_ssa(dst_coord);
509 store->src[1] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
510 store->src[2] = nir_src_for_ssa(outval);
511 store->variables[0] = nir_deref_var_create(store, output_img);
512
513 nir_builder_instr_insert(&b, &store->instr);
514 return b.shader;
515 }
516
517 /* image to image - don't write use image accessors */
518 static VkResult
519 radv_device_init_meta_itoi_state(struct radv_device *device)
520 {
521 VkResult result;
522 struct radv_shader_module cs = { .nir = NULL };
523
524 zero(device->meta_state.itoi);
525
526 cs.nir = build_nir_itoi_compute_shader(device);
527
528 /*
529 * two descriptors one for the image being sampled
530 * one for the buffer being written.
531 */
532 VkDescriptorSetLayoutCreateInfo ds_create_info = {
533 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
534 .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
535 .bindingCount = 2,
536 .pBindings = (VkDescriptorSetLayoutBinding[]) {
537 {
538 .binding = 0,
539 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
540 .descriptorCount = 1,
541 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
542 .pImmutableSamplers = NULL
543 },
544 {
545 .binding = 1,
546 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
547 .descriptorCount = 1,
548 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
549 .pImmutableSamplers = NULL
550 },
551 }
552 };
553
554 result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device),
555 &ds_create_info,
556 &device->meta_state.alloc,
557 &device->meta_state.itoi.img_ds_layout);
558 if (result != VK_SUCCESS)
559 goto fail;
560
561
562 VkPipelineLayoutCreateInfo pl_create_info = {
563 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
564 .setLayoutCount = 1,
565 .pSetLayouts = &device->meta_state.itoi.img_ds_layout,
566 .pushConstantRangeCount = 1,
567 .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_COMPUTE_BIT, 0, 16},
568 };
569
570 result = radv_CreatePipelineLayout(radv_device_to_handle(device),
571 &pl_create_info,
572 &device->meta_state.alloc,
573 &device->meta_state.itoi.img_p_layout);
574 if (result != VK_SUCCESS)
575 goto fail;
576
577 /* compute shader */
578
579 VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
580 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
581 .stage = VK_SHADER_STAGE_COMPUTE_BIT,
582 .module = radv_shader_module_to_handle(&cs),
583 .pName = "main",
584 .pSpecializationInfo = NULL,
585 };
586
587 VkComputePipelineCreateInfo vk_pipeline_info = {
588 .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
589 .stage = pipeline_shader_stage,
590 .flags = 0,
591 .layout = device->meta_state.itoi.img_p_layout,
592 };
593
594 result = radv_CreateComputePipelines(radv_device_to_handle(device),
595 radv_pipeline_cache_to_handle(&device->meta_state.cache),
596 1, &vk_pipeline_info, NULL,
597 &device->meta_state.itoi.pipeline);
598 if (result != VK_SUCCESS)
599 goto fail;
600
601 ralloc_free(cs.nir);
602 return VK_SUCCESS;
603 fail:
604 ralloc_free(cs.nir);
605 return result;
606 }
607
608 static void
609 radv_device_finish_meta_itoi_state(struct radv_device *device)
610 {
611 if (device->meta_state.itoi.img_p_layout) {
612 radv_DestroyPipelineLayout(radv_device_to_handle(device),
613 device->meta_state.itoi.img_p_layout,
614 &device->meta_state.alloc);
615 }
616 if (device->meta_state.itoi.img_ds_layout) {
617 radv_DestroyDescriptorSetLayout(radv_device_to_handle(device),
618 device->meta_state.itoi.img_ds_layout,
619 &device->meta_state.alloc);
620 }
621 if (device->meta_state.itoi.pipeline) {
622 radv_DestroyPipeline(radv_device_to_handle(device),
623 device->meta_state.itoi.pipeline,
624 &device->meta_state.alloc);
625 }
626 }
627
628 static nir_shader *
629 build_nir_cleari_compute_shader(struct radv_device *dev)
630 {
631 nir_builder b;
632 const struct glsl_type *img_type = glsl_sampler_type(GLSL_SAMPLER_DIM_2D,
633 false,
634 false,
635 GLSL_TYPE_FLOAT);
636 nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_COMPUTE, NULL);
637 b.shader->info->name = ralloc_strdup(b.shader, "meta_cleari_cs");
638 b.shader->info->cs.local_size[0] = 16;
639 b.shader->info->cs.local_size[1] = 16;
640 b.shader->info->cs.local_size[2] = 1;
641
642 nir_variable *output_img = nir_variable_create(b.shader, nir_var_uniform,
643 img_type, "out_img");
644 output_img->data.descriptor_set = 0;
645 output_img->data.binding = 0;
646
647 nir_ssa_def *invoc_id = nir_load_system_value(&b, nir_intrinsic_load_local_invocation_id, 0);
648 nir_ssa_def *wg_id = nir_load_system_value(&b, nir_intrinsic_load_work_group_id, 0);
649 nir_ssa_def *block_size = nir_imm_ivec4(&b,
650 b.shader->info->cs.local_size[0],
651 b.shader->info->cs.local_size[1],
652 b.shader->info->cs.local_size[2], 0);
653
654 nir_ssa_def *global_id = nir_iadd(&b, nir_imul(&b, wg_id, block_size), invoc_id);
655
656 nir_intrinsic_instr *clear_val = nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_push_constant);
657 nir_intrinsic_set_base(clear_val, 0);
658 nir_intrinsic_set_range(clear_val, 16);
659 clear_val->src[0] = nir_src_for_ssa(nir_imm_int(&b, 0));
660 clear_val->num_components = 4;
661 nir_ssa_dest_init(&clear_val->instr, &clear_val->dest, 4, 32, "clear_value");
662 nir_builder_instr_insert(&b, &clear_val->instr);
663
664 nir_intrinsic_instr *store = nir_intrinsic_instr_create(b.shader, nir_intrinsic_image_store);
665 store->src[0] = nir_src_for_ssa(global_id);
666 store->src[1] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
667 store->src[2] = nir_src_for_ssa(&clear_val->dest.ssa);
668 store->variables[0] = nir_deref_var_create(store, output_img);
669
670 nir_builder_instr_insert(&b, &store->instr);
671 return b.shader;
672 }
673
674 static VkResult
675 radv_device_init_meta_cleari_state(struct radv_device *device)
676 {
677 VkResult result;
678 struct radv_shader_module cs = { .nir = NULL };
679
680 zero(device->meta_state.cleari);
681
682 cs.nir = build_nir_cleari_compute_shader(device);
683
684 /*
685 * two descriptors one for the image being sampled
686 * one for the buffer being written.
687 */
688 VkDescriptorSetLayoutCreateInfo ds_create_info = {
689 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
690 .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
691 .bindingCount = 1,
692 .pBindings = (VkDescriptorSetLayoutBinding[]) {
693 {
694 .binding = 0,
695 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
696 .descriptorCount = 1,
697 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
698 .pImmutableSamplers = NULL
699 },
700 }
701 };
702
703 result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device),
704 &ds_create_info,
705 &device->meta_state.alloc,
706 &device->meta_state.cleari.img_ds_layout);
707 if (result != VK_SUCCESS)
708 goto fail;
709
710
711 VkPipelineLayoutCreateInfo pl_create_info = {
712 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
713 .setLayoutCount = 1,
714 .pSetLayouts = &device->meta_state.cleari.img_ds_layout,
715 .pushConstantRangeCount = 1,
716 .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_COMPUTE_BIT, 0, 16},
717 };
718
719 result = radv_CreatePipelineLayout(radv_device_to_handle(device),
720 &pl_create_info,
721 &device->meta_state.alloc,
722 &device->meta_state.cleari.img_p_layout);
723 if (result != VK_SUCCESS)
724 goto fail;
725
726 /* compute shader */
727
728 VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
729 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
730 .stage = VK_SHADER_STAGE_COMPUTE_BIT,
731 .module = radv_shader_module_to_handle(&cs),
732 .pName = "main",
733 .pSpecializationInfo = NULL,
734 };
735
736 VkComputePipelineCreateInfo vk_pipeline_info = {
737 .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
738 .stage = pipeline_shader_stage,
739 .flags = 0,
740 .layout = device->meta_state.cleari.img_p_layout,
741 };
742
743 result = radv_CreateComputePipelines(radv_device_to_handle(device),
744 radv_pipeline_cache_to_handle(&device->meta_state.cache),
745 1, &vk_pipeline_info, NULL,
746 &device->meta_state.cleari.pipeline);
747 if (result != VK_SUCCESS)
748 goto fail;
749
750 ralloc_free(cs.nir);
751 return VK_SUCCESS;
752 fail:
753 ralloc_free(cs.nir);
754 return result;
755 }
756
757 static void
758 radv_device_finish_meta_cleari_state(struct radv_device *device)
759 {
760 if (device->meta_state.cleari.img_p_layout) {
761 radv_DestroyPipelineLayout(radv_device_to_handle(device),
762 device->meta_state.cleari.img_p_layout,
763 &device->meta_state.alloc);
764 }
765 if (device->meta_state.cleari.img_ds_layout) {
766 radv_DestroyDescriptorSetLayout(radv_device_to_handle(device),
767 device->meta_state.cleari.img_ds_layout,
768 &device->meta_state.alloc);
769 }
770 if (device->meta_state.cleari.pipeline) {
771 radv_DestroyPipeline(radv_device_to_handle(device),
772 device->meta_state.cleari.pipeline,
773 &device->meta_state.alloc);
774 }
775 }
776
777 void
778 radv_device_finish_meta_bufimage_state(struct radv_device *device)
779 {
780 radv_device_finish_meta_itob_state(device);
781 radv_device_finish_meta_btoi_state(device);
782 radv_device_finish_meta_itoi_state(device);
783 radv_device_finish_meta_cleari_state(device);
784 }
785
786 VkResult
787 radv_device_init_meta_bufimage_state(struct radv_device *device)
788 {
789 VkResult result;
790
791 result = radv_device_init_meta_itob_state(device);
792 if (result != VK_SUCCESS)
793 return result;
794
795 result = radv_device_init_meta_btoi_state(device);
796 if (result != VK_SUCCESS)
797 goto fail_itob;
798
799 result = radv_device_init_meta_itoi_state(device);
800 if (result != VK_SUCCESS)
801 goto fail_btoi;
802
803 result = radv_device_init_meta_cleari_state(device);
804 if (result != VK_SUCCESS)
805 goto fail_itoi;
806
807 return VK_SUCCESS;
808 fail_itoi:
809 radv_device_finish_meta_itoi_state(device);
810 fail_btoi:
811 radv_device_finish_meta_btoi_state(device);
812 fail_itob:
813 radv_device_finish_meta_itob_state(device);
814 return result;
815 }
816
817 void
818 radv_meta_begin_itoi(struct radv_cmd_buffer *cmd_buffer,
819 struct radv_meta_saved_compute_state *save)
820 {
821 radv_meta_save_compute(save, cmd_buffer, 16);
822 }
823
824 void
825 radv_meta_end_itoi(struct radv_cmd_buffer *cmd_buffer,
826 struct radv_meta_saved_compute_state *save)
827 {
828 radv_meta_restore_compute(save, cmd_buffer, 16);
829 }
830
831 void
832 radv_meta_begin_bufimage(struct radv_cmd_buffer *cmd_buffer,
833 struct radv_meta_saved_compute_state *save)
834 {
835 radv_meta_save_compute(save, cmd_buffer, 12);
836 }
837
838 void
839 radv_meta_end_bufimage(struct radv_cmd_buffer *cmd_buffer,
840 struct radv_meta_saved_compute_state *save)
841 {
842 radv_meta_restore_compute(save, cmd_buffer, 12);
843 }
844
845 void
846 radv_meta_begin_cleari(struct radv_cmd_buffer *cmd_buffer,
847 struct radv_meta_saved_compute_state *save)
848 {
849 radv_meta_save_compute(save, cmd_buffer, 16);
850 }
851
852 void
853 radv_meta_end_cleari(struct radv_cmd_buffer *cmd_buffer,
854 struct radv_meta_saved_compute_state *save)
855 {
856 radv_meta_restore_compute(save, cmd_buffer, 16);
857 }
858
859 static void
860 create_iview(struct radv_cmd_buffer *cmd_buffer,
861 struct radv_meta_blit2d_surf *surf,
862 VkImageUsageFlags usage,
863 struct radv_image_view *iview)
864 {
865
866 radv_image_view_init(iview, cmd_buffer->device,
867 &(VkImageViewCreateInfo) {
868 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
869 .image = radv_image_to_handle(surf->image),
870 .viewType = VK_IMAGE_VIEW_TYPE_2D,
871 .format = surf->format,
872 .subresourceRange = {
873 .aspectMask = surf->aspect_mask,
874 .baseMipLevel = surf->level,
875 .levelCount = 1,
876 .baseArrayLayer = surf->layer,
877 .layerCount = 1
878 },
879 }, cmd_buffer, usage);
880 }
881
882 static void
883 create_bview(struct radv_cmd_buffer *cmd_buffer,
884 struct radv_buffer *buffer,
885 unsigned offset,
886 VkFormat format,
887 struct radv_buffer_view *bview)
888 {
889 radv_buffer_view_init(bview, cmd_buffer->device,
890 &(VkBufferViewCreateInfo) {
891 .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
892 .flags = 0,
893 .buffer = radv_buffer_to_handle(buffer),
894 .format = format,
895 .offset = offset,
896 .range = VK_WHOLE_SIZE,
897 }, cmd_buffer);
898
899 }
900
901 struct itob_temps {
902 struct radv_image_view src_iview;
903 struct radv_buffer_view dst_bview;
904 };
905
906 static void
907 itob_bind_descriptors(struct radv_cmd_buffer *cmd_buffer,
908 struct itob_temps *tmp)
909 {
910 struct radv_device *device = cmd_buffer->device;
911
912 radv_meta_push_descriptor_set(cmd_buffer,
913 VK_PIPELINE_BIND_POINT_COMPUTE,
914 device->meta_state.itob.img_p_layout,
915 0, /* set */
916 2, /* descriptorWriteCount */
917 (VkWriteDescriptorSet[]) {
918 {
919 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
920 .dstBinding = 0,
921 .dstArrayElement = 0,
922 .descriptorCount = 1,
923 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
924 .pImageInfo = (VkDescriptorImageInfo[]) {
925 {
926 .sampler = VK_NULL_HANDLE,
927 .imageView = radv_image_view_to_handle(&tmp->src_iview),
928 .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
929 },
930 }
931 },
932 {
933 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
934 .dstBinding = 1,
935 .dstArrayElement = 0,
936 .descriptorCount = 1,
937 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
938 .pTexelBufferView = (VkBufferView[]) { radv_buffer_view_to_handle(&tmp->dst_bview) },
939 }
940 });
941 }
942
943 static void
944 itob_bind_pipeline(struct radv_cmd_buffer *cmd_buffer)
945 {
946 VkPipeline pipeline =
947 cmd_buffer->device->meta_state.itob.pipeline;
948
949 if (cmd_buffer->state.compute_pipeline != radv_pipeline_from_handle(pipeline)) {
950 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer),
951 VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
952 }
953 }
954
955 void
956 radv_meta_image_to_buffer(struct radv_cmd_buffer *cmd_buffer,
957 struct radv_meta_blit2d_surf *src,
958 struct radv_meta_blit2d_buffer *dst,
959 unsigned num_rects,
960 struct radv_meta_blit2d_rect *rects)
961 {
962 struct radv_device *device = cmd_buffer->device;
963 struct itob_temps temps;
964
965 create_iview(cmd_buffer, src, VK_IMAGE_USAGE_SAMPLED_BIT, &temps.src_iview);
966 create_bview(cmd_buffer, dst->buffer, dst->offset, dst->format, &temps.dst_bview);
967 itob_bind_descriptors(cmd_buffer, &temps);
968
969 itob_bind_pipeline(cmd_buffer);
970
971 for (unsigned r = 0; r < num_rects; ++r) {
972 unsigned push_constants[3] = {
973 rects[r].src_x,
974 rects[r].src_y,
975 dst->pitch
976 };
977 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
978 device->meta_state.itob.img_p_layout,
979 VK_SHADER_STAGE_COMPUTE_BIT, 0, 12,
980 push_constants);
981
982 radv_unaligned_dispatch(cmd_buffer, rects[r].width, rects[r].height, 1);
983 }
984 }
985
986 struct btoi_temps {
987 struct radv_buffer_view src_bview;
988 struct radv_image_view dst_iview;
989 };
990
991 static void
992 btoi_bind_descriptors(struct radv_cmd_buffer *cmd_buffer,
993 struct btoi_temps *tmp)
994 {
995 struct radv_device *device = cmd_buffer->device;
996
997 radv_meta_push_descriptor_set(cmd_buffer,
998 VK_PIPELINE_BIND_POINT_COMPUTE,
999 device->meta_state.btoi.img_p_layout,
1000 0, /* set */
1001 2, /* descriptorWriteCount */
1002 (VkWriteDescriptorSet[]) {
1003 {
1004 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1005 .dstBinding = 0,
1006 .dstArrayElement = 0,
1007 .descriptorCount = 1,
1008 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
1009 .pTexelBufferView = (VkBufferView[]) { radv_buffer_view_to_handle(&tmp->src_bview) },
1010 },
1011 {
1012 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1013 .dstBinding = 1,
1014 .dstArrayElement = 0,
1015 .descriptorCount = 1,
1016 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1017 .pImageInfo = (VkDescriptorImageInfo[]) {
1018 {
1019 .sampler = VK_NULL_HANDLE,
1020 .imageView = radv_image_view_to_handle(&tmp->dst_iview),
1021 .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
1022 },
1023 }
1024 }
1025 });
1026 }
1027
1028 static void
1029 btoi_bind_pipeline(struct radv_cmd_buffer *cmd_buffer)
1030 {
1031 VkPipeline pipeline =
1032 cmd_buffer->device->meta_state.btoi.pipeline;
1033
1034 if (cmd_buffer->state.compute_pipeline != radv_pipeline_from_handle(pipeline)) {
1035 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer),
1036 VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
1037 }
1038 }
1039
1040 void
1041 radv_meta_buffer_to_image_cs(struct radv_cmd_buffer *cmd_buffer,
1042 struct radv_meta_blit2d_buffer *src,
1043 struct radv_meta_blit2d_surf *dst,
1044 unsigned num_rects,
1045 struct radv_meta_blit2d_rect *rects)
1046 {
1047 struct radv_device *device = cmd_buffer->device;
1048 struct btoi_temps temps;
1049
1050 create_bview(cmd_buffer, src->buffer, src->offset, src->format, &temps.src_bview);
1051 create_iview(cmd_buffer, dst, VK_IMAGE_USAGE_STORAGE_BIT, &temps.dst_iview);
1052 btoi_bind_descriptors(cmd_buffer, &temps);
1053
1054 btoi_bind_pipeline(cmd_buffer);
1055
1056 for (unsigned r = 0; r < num_rects; ++r) {
1057 unsigned push_constants[3] = {
1058 rects[r].dst_x,
1059 rects[r].dst_y,
1060 src->pitch
1061 };
1062 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
1063 device->meta_state.btoi.img_p_layout,
1064 VK_SHADER_STAGE_COMPUTE_BIT, 0, 12,
1065 push_constants);
1066
1067 radv_unaligned_dispatch(cmd_buffer, rects[r].width, rects[r].height, 1);
1068 }
1069 }
1070
1071 struct itoi_temps {
1072 struct radv_image_view src_iview;
1073 struct radv_image_view dst_iview;
1074 };
1075
1076 static void
1077 itoi_bind_descriptors(struct radv_cmd_buffer *cmd_buffer,
1078 struct itoi_temps *tmp)
1079 {
1080 struct radv_device *device = cmd_buffer->device;
1081
1082 radv_meta_push_descriptor_set(cmd_buffer,
1083 VK_PIPELINE_BIND_POINT_COMPUTE,
1084 device->meta_state.itoi.img_p_layout,
1085 0, /* set */
1086 2, /* descriptorWriteCount */
1087 (VkWriteDescriptorSet[]) {
1088 {
1089 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1090 .dstBinding = 0,
1091 .dstArrayElement = 0,
1092 .descriptorCount = 1,
1093 .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
1094 .pImageInfo = (VkDescriptorImageInfo[]) {
1095 {
1096 .sampler = VK_NULL_HANDLE,
1097 .imageView = radv_image_view_to_handle(&tmp->src_iview),
1098 .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
1099 },
1100 }
1101 },
1102 {
1103 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1104 .dstBinding = 1,
1105 .dstArrayElement = 0,
1106 .descriptorCount = 1,
1107 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1108 .pImageInfo = (VkDescriptorImageInfo[]) {
1109 {
1110 .sampler = VK_NULL_HANDLE,
1111 .imageView = radv_image_view_to_handle(&tmp->dst_iview),
1112 .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
1113 },
1114 }
1115 }
1116 });
1117 }
1118
1119 static void
1120 itoi_bind_pipeline(struct radv_cmd_buffer *cmd_buffer)
1121 {
1122 VkPipeline pipeline =
1123 cmd_buffer->device->meta_state.itoi.pipeline;
1124
1125 if (cmd_buffer->state.compute_pipeline != radv_pipeline_from_handle(pipeline)) {
1126 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer),
1127 VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
1128 }
1129 }
1130
1131 void
1132 radv_meta_image_to_image_cs(struct radv_cmd_buffer *cmd_buffer,
1133 struct radv_meta_blit2d_surf *src,
1134 struct radv_meta_blit2d_surf *dst,
1135 unsigned num_rects,
1136 struct radv_meta_blit2d_rect *rects)
1137 {
1138 struct radv_device *device = cmd_buffer->device;
1139 struct itoi_temps temps;
1140
1141 create_iview(cmd_buffer, src, VK_IMAGE_USAGE_SAMPLED_BIT, &temps.src_iview);
1142 create_iview(cmd_buffer, dst, VK_IMAGE_USAGE_STORAGE_BIT, &temps.dst_iview);
1143
1144 itoi_bind_descriptors(cmd_buffer, &temps);
1145
1146 itoi_bind_pipeline(cmd_buffer);
1147
1148 for (unsigned r = 0; r < num_rects; ++r) {
1149 unsigned push_constants[4] = {
1150 rects[r].src_x,
1151 rects[r].src_y,
1152 rects[r].dst_x,
1153 rects[r].dst_y,
1154 };
1155 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
1156 device->meta_state.itoi.img_p_layout,
1157 VK_SHADER_STAGE_COMPUTE_BIT, 0, 16,
1158 push_constants);
1159
1160 radv_unaligned_dispatch(cmd_buffer, rects[r].width, rects[r].height, 1);
1161 }
1162 }
1163
1164 static void
1165 cleari_bind_descriptors(struct radv_cmd_buffer *cmd_buffer,
1166 struct radv_image_view *dst_iview)
1167 {
1168 struct radv_device *device = cmd_buffer->device;
1169
1170 radv_meta_push_descriptor_set(cmd_buffer,
1171 VK_PIPELINE_BIND_POINT_COMPUTE,
1172 device->meta_state.cleari.img_p_layout,
1173 0, /* set */
1174 1, /* descriptorWriteCount */
1175 (VkWriteDescriptorSet[]) {
1176 {
1177 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1178 .dstBinding = 0,
1179 .dstArrayElement = 0,
1180 .descriptorCount = 1,
1181 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1182 .pImageInfo = (VkDescriptorImageInfo[]) {
1183 {
1184 .sampler = VK_NULL_HANDLE,
1185 .imageView = radv_image_view_to_handle(dst_iview),
1186 .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
1187 },
1188 }
1189 },
1190 });
1191 }
1192
1193 static void
1194 cleari_bind_pipeline(struct radv_cmd_buffer *cmd_buffer)
1195 {
1196 VkPipeline pipeline =
1197 cmd_buffer->device->meta_state.cleari.pipeline;
1198
1199 if (cmd_buffer->state.compute_pipeline != radv_pipeline_from_handle(pipeline)) {
1200 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer),
1201 VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
1202 }
1203 }
1204
1205 void
1206 radv_meta_clear_image_cs(struct radv_cmd_buffer *cmd_buffer,
1207 struct radv_meta_blit2d_surf *dst,
1208 const VkClearColorValue *clear_color)
1209 {
1210 struct radv_device *device = cmd_buffer->device;
1211 struct radv_image_view dst_iview;
1212
1213 create_iview(cmd_buffer, dst, VK_IMAGE_USAGE_STORAGE_BIT, &dst_iview);
1214 cleari_bind_descriptors(cmd_buffer, &dst_iview);
1215
1216 cleari_bind_pipeline(cmd_buffer);
1217
1218 unsigned push_constants[4] = {
1219 clear_color->uint32[0],
1220 clear_color->uint32[1],
1221 clear_color->uint32[2],
1222 clear_color->uint32[3],
1223 };
1224
1225 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
1226 device->meta_state.cleari.img_p_layout,
1227 VK_SHADER_STAGE_COMPUTE_BIT, 0, 16,
1228 push_constants);
1229
1230 radv_unaligned_dispatch(cmd_buffer, dst->image->info.width, dst->image->info.height, 1);
1231 }