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