2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
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:
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
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
24 #include "radv_meta.h"
25 #include "nir/nir_builder.h"
28 * GFX queue: Compute shader implementation of image->buffer copy
29 * Compute queue: implementation also of buffer->image, image->image, and image clear.
33 build_nir_itob_compute_shader(struct radv_device
*dev
)
36 const struct glsl_type
*sampler_type
= glsl_sampler_type(GLSL_SAMPLER_DIM_2D
,
40 const struct glsl_type
*img_type
= glsl_sampler_type(GLSL_SAMPLER_DIM_BUF
,
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;
54 nir_variable
*output_img
= nir_variable_create(b
.shader
, nir_var_uniform
,
56 output_img
->data
.descriptor_set
= 0;
57 output_img
->data
.binding
= 1;
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);
66 nir_ssa_def
*global_id
= nir_iadd(&b
, nir_imul(&b
, wg_id
, block_size
), invoc_id
);
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
);
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
);
86 nir_ssa_def
*img_coord
= nir_iadd(&b
, global_id
, &offset
->dest
.ssa
);
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
);
101 nir_ssa_dest_init(&tex
->instr
, &tex
->dest
, 4, 32, "tex");
102 nir_builder_instr_insert(&b
, &tex
->instr
);
104 nir_ssa_def
*pos_x
= nir_channel(&b
, global_id
, 0);
105 nir_ssa_def
*pos_y
= nir_channel(&b
, global_id
, 1);
107 nir_ssa_def
*tmp
= nir_imul(&b
, pos_y
, &stride
->dest
.ssa
);
108 tmp
= nir_iadd(&b
, tmp
, pos_x
);
110 nir_ssa_def
*coord
= nir_vec4(&b
, tmp
, tmp
, tmp
, tmp
);
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
);
119 nir_builder_instr_insert(&b
, &store
->instr
);
123 /* Image to buffer - don't write use image accessors */
125 radv_device_init_meta_itob_state(struct radv_device
*device
)
128 struct radv_shader_module cs
= { .nir
= NULL
};
130 cs
.nir
= build_nir_itob_compute_shader(device
);
133 * two descriptors one for the image being sampled
134 * one for the buffer being written.
136 VkDescriptorSetLayoutCreateInfo ds_create_info
= {
137 .sType
= VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
,
138 .flags
= VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR
,
140 .pBindings
= (VkDescriptorSetLayoutBinding
[]) {
143 .descriptorType
= VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
,
144 .descriptorCount
= 1,
145 .stageFlags
= VK_SHADER_STAGE_COMPUTE_BIT
,
146 .pImmutableSamplers
= NULL
150 .descriptorType
= VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
,
151 .descriptorCount
= 1,
152 .stageFlags
= VK_SHADER_STAGE_COMPUTE_BIT
,
153 .pImmutableSamplers
= NULL
158 result
= radv_CreateDescriptorSetLayout(radv_device_to_handle(device
),
160 &device
->meta_state
.alloc
,
161 &device
->meta_state
.itob
.img_ds_layout
);
162 if (result
!= VK_SUCCESS
)
166 VkPipelineLayoutCreateInfo pl_create_info
= {
167 .sType
= VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
,
169 .pSetLayouts
= &device
->meta_state
.itob
.img_ds_layout
,
170 .pushConstantRangeCount
= 1,
171 .pPushConstantRanges
= &(VkPushConstantRange
){VK_SHADER_STAGE_COMPUTE_BIT
, 0, 12},
174 result
= radv_CreatePipelineLayout(radv_device_to_handle(device
),
176 &device
->meta_state
.alloc
,
177 &device
->meta_state
.itob
.img_p_layout
);
178 if (result
!= VK_SUCCESS
)
183 VkPipelineShaderStageCreateInfo pipeline_shader_stage
= {
184 .sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
,
185 .stage
= VK_SHADER_STAGE_COMPUTE_BIT
,
186 .module
= radv_shader_module_to_handle(&cs
),
188 .pSpecializationInfo
= NULL
,
191 VkComputePipelineCreateInfo vk_pipeline_info
= {
192 .sType
= VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO
,
193 .stage
= pipeline_shader_stage
,
195 .layout
= device
->meta_state
.itob
.img_p_layout
,
198 result
= radv_CreateComputePipelines(radv_device_to_handle(device
),
199 radv_pipeline_cache_to_handle(&device
->meta_state
.cache
),
200 1, &vk_pipeline_info
, NULL
,
201 &device
->meta_state
.itob
.pipeline
);
202 if (result
!= VK_SUCCESS
)
213 radv_device_finish_meta_itob_state(struct radv_device
*device
)
215 struct radv_meta_state
*state
= &device
->meta_state
;
217 radv_DestroyPipelineLayout(radv_device_to_handle(device
),
218 state
->itob
.img_p_layout
, &state
->alloc
);
219 radv_DestroyDescriptorSetLayout(radv_device_to_handle(device
),
220 state
->itob
.img_ds_layout
,
222 radv_DestroyPipeline(radv_device_to_handle(device
),
223 state
->itob
.pipeline
, &state
->alloc
);
227 build_nir_btoi_compute_shader(struct radv_device
*dev
)
230 const struct glsl_type
*buf_type
= glsl_sampler_type(GLSL_SAMPLER_DIM_BUF
,
234 const struct glsl_type
*img_type
= glsl_sampler_type(GLSL_SAMPLER_DIM_2D
,
238 nir_builder_init_simple_shader(&b
, NULL
, MESA_SHADER_COMPUTE
, NULL
);
239 b
.shader
->info
.name
= ralloc_strdup(b
.shader
, "meta_btoi_cs");
240 b
.shader
->info
.cs
.local_size
[0] = 16;
241 b
.shader
->info
.cs
.local_size
[1] = 16;
242 b
.shader
->info
.cs
.local_size
[2] = 1;
243 nir_variable
*input_img
= nir_variable_create(b
.shader
, nir_var_uniform
,
245 input_img
->data
.descriptor_set
= 0;
246 input_img
->data
.binding
= 0;
248 nir_variable
*output_img
= nir_variable_create(b
.shader
, nir_var_uniform
,
249 img_type
, "out_img");
250 output_img
->data
.descriptor_set
= 0;
251 output_img
->data
.binding
= 1;
253 nir_ssa_def
*invoc_id
= nir_load_system_value(&b
, nir_intrinsic_load_local_invocation_id
, 0);
254 nir_ssa_def
*wg_id
= nir_load_system_value(&b
, nir_intrinsic_load_work_group_id
, 0);
255 nir_ssa_def
*block_size
= nir_imm_ivec4(&b
,
256 b
.shader
->info
.cs
.local_size
[0],
257 b
.shader
->info
.cs
.local_size
[1],
258 b
.shader
->info
.cs
.local_size
[2], 0);
260 nir_ssa_def
*global_id
= nir_iadd(&b
, nir_imul(&b
, wg_id
, block_size
), invoc_id
);
262 nir_intrinsic_instr
*offset
= nir_intrinsic_instr_create(b
.shader
, nir_intrinsic_load_push_constant
);
263 nir_intrinsic_set_base(offset
, 0);
264 nir_intrinsic_set_range(offset
, 12);
265 offset
->src
[0] = nir_src_for_ssa(nir_imm_int(&b
, 0));
266 offset
->num_components
= 2;
267 nir_ssa_dest_init(&offset
->instr
, &offset
->dest
, 2, 32, "offset");
268 nir_builder_instr_insert(&b
, &offset
->instr
);
270 nir_intrinsic_instr
*stride
= nir_intrinsic_instr_create(b
.shader
, nir_intrinsic_load_push_constant
);
271 nir_intrinsic_set_base(stride
, 0);
272 nir_intrinsic_set_range(stride
, 12);
273 stride
->src
[0] = nir_src_for_ssa(nir_imm_int(&b
, 8));
274 stride
->num_components
= 1;
275 nir_ssa_dest_init(&stride
->instr
, &stride
->dest
, 1, 32, "stride");
276 nir_builder_instr_insert(&b
, &stride
->instr
);
278 nir_ssa_def
*pos_x
= nir_channel(&b
, global_id
, 0);
279 nir_ssa_def
*pos_y
= nir_channel(&b
, global_id
, 1);
281 nir_ssa_def
*tmp
= nir_imul(&b
, pos_y
, &stride
->dest
.ssa
);
282 tmp
= nir_iadd(&b
, tmp
, pos_x
);
284 nir_ssa_def
*buf_coord
= nir_vec4(&b
, tmp
, tmp
, tmp
, tmp
);
286 nir_ssa_def
*img_coord
= nir_iadd(&b
, global_id
, &offset
->dest
.ssa
);
288 nir_tex_instr
*tex
= nir_tex_instr_create(b
.shader
, 2);
289 tex
->sampler_dim
= GLSL_SAMPLER_DIM_BUF
;
290 tex
->op
= nir_texop_txf
;
291 tex
->src
[0].src_type
= nir_tex_src_coord
;
292 tex
->src
[0].src
= nir_src_for_ssa(nir_channels(&b
, buf_coord
, 1));
293 tex
->src
[1].src_type
= nir_tex_src_lod
;
294 tex
->src
[1].src
= nir_src_for_ssa(nir_imm_int(&b
, 0));
295 tex
->dest_type
= nir_type_float
;
296 tex
->is_array
= false;
297 tex
->coord_components
= 1;
298 tex
->texture
= nir_deref_var_create(tex
, input_img
);
301 nir_ssa_dest_init(&tex
->instr
, &tex
->dest
, 4, 32, "tex");
302 nir_builder_instr_insert(&b
, &tex
->instr
);
304 nir_ssa_def
*outval
= &tex
->dest
.ssa
;
305 nir_intrinsic_instr
*store
= nir_intrinsic_instr_create(b
.shader
, nir_intrinsic_image_store
);
306 store
->src
[0] = nir_src_for_ssa(img_coord
);
307 store
->src
[1] = nir_src_for_ssa(nir_ssa_undef(&b
, 1, 32));
308 store
->src
[2] = nir_src_for_ssa(outval
);
309 store
->variables
[0] = nir_deref_var_create(store
, output_img
);
311 nir_builder_instr_insert(&b
, &store
->instr
);
315 /* Buffer to image - don't write use image accessors */
317 radv_device_init_meta_btoi_state(struct radv_device
*device
)
320 struct radv_shader_module cs
= { .nir
= NULL
};
322 cs
.nir
= build_nir_btoi_compute_shader(device
);
325 * two descriptors one for the image being sampled
326 * one for the buffer being written.
328 VkDescriptorSetLayoutCreateInfo ds_create_info
= {
329 .sType
= VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
,
330 .flags
= VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR
,
332 .pBindings
= (VkDescriptorSetLayoutBinding
[]) {
335 .descriptorType
= VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
,
336 .descriptorCount
= 1,
337 .stageFlags
= VK_SHADER_STAGE_COMPUTE_BIT
,
338 .pImmutableSamplers
= NULL
342 .descriptorType
= VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
,
343 .descriptorCount
= 1,
344 .stageFlags
= VK_SHADER_STAGE_COMPUTE_BIT
,
345 .pImmutableSamplers
= NULL
350 result
= radv_CreateDescriptorSetLayout(radv_device_to_handle(device
),
352 &device
->meta_state
.alloc
,
353 &device
->meta_state
.btoi
.img_ds_layout
);
354 if (result
!= VK_SUCCESS
)
358 VkPipelineLayoutCreateInfo pl_create_info
= {
359 .sType
= VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
,
361 .pSetLayouts
= &device
->meta_state
.btoi
.img_ds_layout
,
362 .pushConstantRangeCount
= 1,
363 .pPushConstantRanges
= &(VkPushConstantRange
){VK_SHADER_STAGE_COMPUTE_BIT
, 0, 12},
366 result
= radv_CreatePipelineLayout(radv_device_to_handle(device
),
368 &device
->meta_state
.alloc
,
369 &device
->meta_state
.btoi
.img_p_layout
);
370 if (result
!= VK_SUCCESS
)
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
),
380 .pSpecializationInfo
= NULL
,
383 VkComputePipelineCreateInfo vk_pipeline_info
= {
384 .sType
= VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO
,
385 .stage
= pipeline_shader_stage
,
387 .layout
= device
->meta_state
.btoi
.img_p_layout
,
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
)
405 radv_device_finish_meta_btoi_state(struct radv_device
*device
)
407 struct radv_meta_state
*state
= &device
->meta_state
;
409 radv_DestroyPipelineLayout(radv_device_to_handle(device
),
410 state
->btoi
.img_p_layout
, &state
->alloc
);
411 radv_DestroyDescriptorSetLayout(radv_device_to_handle(device
),
412 state
->btoi
.img_ds_layout
,
414 radv_DestroyPipeline(radv_device_to_handle(device
),
415 state
->btoi
.pipeline
, &state
->alloc
);
419 build_nir_itoi_compute_shader(struct radv_device
*dev
)
422 const struct glsl_type
*buf_type
= glsl_sampler_type(GLSL_SAMPLER_DIM_2D
,
426 const struct glsl_type
*img_type
= glsl_sampler_type(GLSL_SAMPLER_DIM_2D
,
430 nir_builder_init_simple_shader(&b
, NULL
, MESA_SHADER_COMPUTE
, NULL
);
431 b
.shader
->info
.name
= ralloc_strdup(b
.shader
, "meta_itoi_cs");
432 b
.shader
->info
.cs
.local_size
[0] = 16;
433 b
.shader
->info
.cs
.local_size
[1] = 16;
434 b
.shader
->info
.cs
.local_size
[2] = 1;
435 nir_variable
*input_img
= nir_variable_create(b
.shader
, nir_var_uniform
,
437 input_img
->data
.descriptor_set
= 0;
438 input_img
->data
.binding
= 0;
440 nir_variable
*output_img
= nir_variable_create(b
.shader
, nir_var_uniform
,
441 img_type
, "out_img");
442 output_img
->data
.descriptor_set
= 0;
443 output_img
->data
.binding
= 1;
445 nir_ssa_def
*invoc_id
= nir_load_system_value(&b
, nir_intrinsic_load_local_invocation_id
, 0);
446 nir_ssa_def
*wg_id
= nir_load_system_value(&b
, nir_intrinsic_load_work_group_id
, 0);
447 nir_ssa_def
*block_size
= nir_imm_ivec4(&b
,
448 b
.shader
->info
.cs
.local_size
[0],
449 b
.shader
->info
.cs
.local_size
[1],
450 b
.shader
->info
.cs
.local_size
[2], 0);
452 nir_ssa_def
*global_id
= nir_iadd(&b
, nir_imul(&b
, wg_id
, block_size
), invoc_id
);
454 nir_intrinsic_instr
*src_offset
= nir_intrinsic_instr_create(b
.shader
, nir_intrinsic_load_push_constant
);
455 nir_intrinsic_set_base(src_offset
, 0);
456 nir_intrinsic_set_range(src_offset
, 16);
457 src_offset
->src
[0] = nir_src_for_ssa(nir_imm_int(&b
, 0));
458 src_offset
->num_components
= 2;
459 nir_ssa_dest_init(&src_offset
->instr
, &src_offset
->dest
, 2, 32, "src_offset");
460 nir_builder_instr_insert(&b
, &src_offset
->instr
);
462 nir_intrinsic_instr
*dst_offset
= nir_intrinsic_instr_create(b
.shader
, nir_intrinsic_load_push_constant
);
463 nir_intrinsic_set_base(dst_offset
, 0);
464 nir_intrinsic_set_range(dst_offset
, 16);
465 dst_offset
->src
[0] = nir_src_for_ssa(nir_imm_int(&b
, 8));
466 dst_offset
->num_components
= 2;
467 nir_ssa_dest_init(&dst_offset
->instr
, &dst_offset
->dest
, 2, 32, "dst_offset");
468 nir_builder_instr_insert(&b
, &dst_offset
->instr
);
470 nir_ssa_def
*src_coord
= nir_iadd(&b
, global_id
, &src_offset
->dest
.ssa
);
472 nir_ssa_def
*dst_coord
= nir_iadd(&b
, global_id
, &dst_offset
->dest
.ssa
);
474 nir_tex_instr
*tex
= nir_tex_instr_create(b
.shader
, 2);
475 tex
->sampler_dim
= GLSL_SAMPLER_DIM_2D
;
476 tex
->op
= nir_texop_txf
;
477 tex
->src
[0].src_type
= nir_tex_src_coord
;
478 tex
->src
[0].src
= nir_src_for_ssa(nir_channels(&b
, src_coord
, 3));
479 tex
->src
[1].src_type
= nir_tex_src_lod
;
480 tex
->src
[1].src
= nir_src_for_ssa(nir_imm_int(&b
, 0));
481 tex
->dest_type
= nir_type_float
;
482 tex
->is_array
= false;
483 tex
->coord_components
= 2;
484 tex
->texture
= nir_deref_var_create(tex
, input_img
);
487 nir_ssa_dest_init(&tex
->instr
, &tex
->dest
, 4, 32, "tex");
488 nir_builder_instr_insert(&b
, &tex
->instr
);
490 nir_ssa_def
*outval
= &tex
->dest
.ssa
;
491 nir_intrinsic_instr
*store
= nir_intrinsic_instr_create(b
.shader
, nir_intrinsic_image_store
);
492 store
->src
[0] = nir_src_for_ssa(dst_coord
);
493 store
->src
[1] = nir_src_for_ssa(nir_ssa_undef(&b
, 1, 32));
494 store
->src
[2] = nir_src_for_ssa(outval
);
495 store
->variables
[0] = nir_deref_var_create(store
, output_img
);
497 nir_builder_instr_insert(&b
, &store
->instr
);
501 /* image to image - don't write use image accessors */
503 radv_device_init_meta_itoi_state(struct radv_device
*device
)
506 struct radv_shader_module cs
= { .nir
= NULL
};
508 cs
.nir
= build_nir_itoi_compute_shader(device
);
511 * two descriptors one for the image being sampled
512 * one for the buffer being written.
514 VkDescriptorSetLayoutCreateInfo ds_create_info
= {
515 .sType
= VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
,
516 .flags
= VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR
,
518 .pBindings
= (VkDescriptorSetLayoutBinding
[]) {
521 .descriptorType
= VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
,
522 .descriptorCount
= 1,
523 .stageFlags
= VK_SHADER_STAGE_COMPUTE_BIT
,
524 .pImmutableSamplers
= NULL
528 .descriptorType
= VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
,
529 .descriptorCount
= 1,
530 .stageFlags
= VK_SHADER_STAGE_COMPUTE_BIT
,
531 .pImmutableSamplers
= NULL
536 result
= radv_CreateDescriptorSetLayout(radv_device_to_handle(device
),
538 &device
->meta_state
.alloc
,
539 &device
->meta_state
.itoi
.img_ds_layout
);
540 if (result
!= VK_SUCCESS
)
544 VkPipelineLayoutCreateInfo pl_create_info
= {
545 .sType
= VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
,
547 .pSetLayouts
= &device
->meta_state
.itoi
.img_ds_layout
,
548 .pushConstantRangeCount
= 1,
549 .pPushConstantRanges
= &(VkPushConstantRange
){VK_SHADER_STAGE_COMPUTE_BIT
, 0, 16},
552 result
= radv_CreatePipelineLayout(radv_device_to_handle(device
),
554 &device
->meta_state
.alloc
,
555 &device
->meta_state
.itoi
.img_p_layout
);
556 if (result
!= VK_SUCCESS
)
561 VkPipelineShaderStageCreateInfo pipeline_shader_stage
= {
562 .sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
,
563 .stage
= VK_SHADER_STAGE_COMPUTE_BIT
,
564 .module
= radv_shader_module_to_handle(&cs
),
566 .pSpecializationInfo
= NULL
,
569 VkComputePipelineCreateInfo vk_pipeline_info
= {
570 .sType
= VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO
,
571 .stage
= pipeline_shader_stage
,
573 .layout
= device
->meta_state
.itoi
.img_p_layout
,
576 result
= radv_CreateComputePipelines(radv_device_to_handle(device
),
577 radv_pipeline_cache_to_handle(&device
->meta_state
.cache
),
578 1, &vk_pipeline_info
, NULL
,
579 &device
->meta_state
.itoi
.pipeline
);
580 if (result
!= VK_SUCCESS
)
591 radv_device_finish_meta_itoi_state(struct radv_device
*device
)
593 struct radv_meta_state
*state
= &device
->meta_state
;
595 radv_DestroyPipelineLayout(radv_device_to_handle(device
),
596 state
->itoi
.img_p_layout
, &state
->alloc
);
597 radv_DestroyDescriptorSetLayout(radv_device_to_handle(device
),
598 state
->itoi
.img_ds_layout
,
600 radv_DestroyPipeline(radv_device_to_handle(device
),
601 state
->itoi
.pipeline
, &state
->alloc
);
605 build_nir_cleari_compute_shader(struct radv_device
*dev
)
608 const struct glsl_type
*img_type
= glsl_sampler_type(GLSL_SAMPLER_DIM_2D
,
612 nir_builder_init_simple_shader(&b
, NULL
, MESA_SHADER_COMPUTE
, NULL
);
613 b
.shader
->info
.name
= ralloc_strdup(b
.shader
, "meta_cleari_cs");
614 b
.shader
->info
.cs
.local_size
[0] = 16;
615 b
.shader
->info
.cs
.local_size
[1] = 16;
616 b
.shader
->info
.cs
.local_size
[2] = 1;
618 nir_variable
*output_img
= nir_variable_create(b
.shader
, nir_var_uniform
,
619 img_type
, "out_img");
620 output_img
->data
.descriptor_set
= 0;
621 output_img
->data
.binding
= 0;
623 nir_ssa_def
*invoc_id
= nir_load_system_value(&b
, nir_intrinsic_load_local_invocation_id
, 0);
624 nir_ssa_def
*wg_id
= nir_load_system_value(&b
, nir_intrinsic_load_work_group_id
, 0);
625 nir_ssa_def
*block_size
= nir_imm_ivec4(&b
,
626 b
.shader
->info
.cs
.local_size
[0],
627 b
.shader
->info
.cs
.local_size
[1],
628 b
.shader
->info
.cs
.local_size
[2], 0);
630 nir_ssa_def
*global_id
= nir_iadd(&b
, nir_imul(&b
, wg_id
, block_size
), invoc_id
);
632 nir_intrinsic_instr
*clear_val
= nir_intrinsic_instr_create(b
.shader
, nir_intrinsic_load_push_constant
);
633 nir_intrinsic_set_base(clear_val
, 0);
634 nir_intrinsic_set_range(clear_val
, 16);
635 clear_val
->src
[0] = nir_src_for_ssa(nir_imm_int(&b
, 0));
636 clear_val
->num_components
= 4;
637 nir_ssa_dest_init(&clear_val
->instr
, &clear_val
->dest
, 4, 32, "clear_value");
638 nir_builder_instr_insert(&b
, &clear_val
->instr
);
640 nir_intrinsic_instr
*store
= nir_intrinsic_instr_create(b
.shader
, nir_intrinsic_image_store
);
641 store
->src
[0] = nir_src_for_ssa(global_id
);
642 store
->src
[1] = nir_src_for_ssa(nir_ssa_undef(&b
, 1, 32));
643 store
->src
[2] = nir_src_for_ssa(&clear_val
->dest
.ssa
);
644 store
->variables
[0] = nir_deref_var_create(store
, output_img
);
646 nir_builder_instr_insert(&b
, &store
->instr
);
651 radv_device_init_meta_cleari_state(struct radv_device
*device
)
654 struct radv_shader_module cs
= { .nir
= NULL
};
656 cs
.nir
= build_nir_cleari_compute_shader(device
);
659 * two descriptors one for the image being sampled
660 * one for the buffer being written.
662 VkDescriptorSetLayoutCreateInfo ds_create_info
= {
663 .sType
= VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
,
664 .flags
= VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR
,
666 .pBindings
= (VkDescriptorSetLayoutBinding
[]) {
669 .descriptorType
= VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
,
670 .descriptorCount
= 1,
671 .stageFlags
= VK_SHADER_STAGE_COMPUTE_BIT
,
672 .pImmutableSamplers
= NULL
677 result
= radv_CreateDescriptorSetLayout(radv_device_to_handle(device
),
679 &device
->meta_state
.alloc
,
680 &device
->meta_state
.cleari
.img_ds_layout
);
681 if (result
!= VK_SUCCESS
)
685 VkPipelineLayoutCreateInfo pl_create_info
= {
686 .sType
= VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
,
688 .pSetLayouts
= &device
->meta_state
.cleari
.img_ds_layout
,
689 .pushConstantRangeCount
= 1,
690 .pPushConstantRanges
= &(VkPushConstantRange
){VK_SHADER_STAGE_COMPUTE_BIT
, 0, 16},
693 result
= radv_CreatePipelineLayout(radv_device_to_handle(device
),
695 &device
->meta_state
.alloc
,
696 &device
->meta_state
.cleari
.img_p_layout
);
697 if (result
!= VK_SUCCESS
)
702 VkPipelineShaderStageCreateInfo pipeline_shader_stage
= {
703 .sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
,
704 .stage
= VK_SHADER_STAGE_COMPUTE_BIT
,
705 .module
= radv_shader_module_to_handle(&cs
),
707 .pSpecializationInfo
= NULL
,
710 VkComputePipelineCreateInfo vk_pipeline_info
= {
711 .sType
= VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO
,
712 .stage
= pipeline_shader_stage
,
714 .layout
= device
->meta_state
.cleari
.img_p_layout
,
717 result
= radv_CreateComputePipelines(radv_device_to_handle(device
),
718 radv_pipeline_cache_to_handle(&device
->meta_state
.cache
),
719 1, &vk_pipeline_info
, NULL
,
720 &device
->meta_state
.cleari
.pipeline
);
721 if (result
!= VK_SUCCESS
)
732 radv_device_finish_meta_cleari_state(struct radv_device
*device
)
734 struct radv_meta_state
*state
= &device
->meta_state
;
736 radv_DestroyPipelineLayout(radv_device_to_handle(device
),
737 state
->cleari
.img_p_layout
, &state
->alloc
);
738 radv_DestroyDescriptorSetLayout(radv_device_to_handle(device
),
739 state
->cleari
.img_ds_layout
,
741 radv_DestroyPipeline(radv_device_to_handle(device
),
742 state
->cleari
.pipeline
, &state
->alloc
);
746 radv_device_finish_meta_bufimage_state(struct radv_device
*device
)
748 radv_device_finish_meta_itob_state(device
);
749 radv_device_finish_meta_btoi_state(device
);
750 radv_device_finish_meta_itoi_state(device
);
751 radv_device_finish_meta_cleari_state(device
);
755 radv_device_init_meta_bufimage_state(struct radv_device
*device
)
759 result
= radv_device_init_meta_itob_state(device
);
760 if (result
!= VK_SUCCESS
)
763 result
= radv_device_init_meta_btoi_state(device
);
764 if (result
!= VK_SUCCESS
)
767 result
= radv_device_init_meta_itoi_state(device
);
768 if (result
!= VK_SUCCESS
)
771 result
= radv_device_init_meta_cleari_state(device
);
772 if (result
!= VK_SUCCESS
)
777 radv_device_finish_meta_itoi_state(device
);
779 radv_device_finish_meta_btoi_state(device
);
781 radv_device_finish_meta_itob_state(device
);
786 create_iview(struct radv_cmd_buffer
*cmd_buffer
,
787 struct radv_meta_blit2d_surf
*surf
,
788 struct radv_image_view
*iview
)
791 radv_image_view_init(iview
, cmd_buffer
->device
,
792 &(VkImageViewCreateInfo
) {
793 .sType
= VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
,
794 .image
= radv_image_to_handle(surf
->image
),
795 .viewType
= VK_IMAGE_VIEW_TYPE_2D
,
796 .format
= surf
->format
,
797 .subresourceRange
= {
798 .aspectMask
= surf
->aspect_mask
,
799 .baseMipLevel
= surf
->level
,
801 .baseArrayLayer
= surf
->layer
,
808 create_bview(struct radv_cmd_buffer
*cmd_buffer
,
809 struct radv_buffer
*buffer
,
812 struct radv_buffer_view
*bview
)
814 radv_buffer_view_init(bview
, cmd_buffer
->device
,
815 &(VkBufferViewCreateInfo
) {
816 .sType
= VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO
,
818 .buffer
= radv_buffer_to_handle(buffer
),
821 .range
= VK_WHOLE_SIZE
,
827 itob_bind_descriptors(struct radv_cmd_buffer
*cmd_buffer
,
828 struct radv_image_view
*src
,
829 struct radv_buffer_view
*dst
)
831 struct radv_device
*device
= cmd_buffer
->device
;
833 radv_meta_push_descriptor_set(cmd_buffer
,
834 VK_PIPELINE_BIND_POINT_COMPUTE
,
835 device
->meta_state
.itob
.img_p_layout
,
837 2, /* descriptorWriteCount */
838 (VkWriteDescriptorSet
[]) {
840 .sType
= VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET
,
842 .dstArrayElement
= 0,
843 .descriptorCount
= 1,
844 .descriptorType
= VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
,
845 .pImageInfo
= (VkDescriptorImageInfo
[]) {
847 .sampler
= VK_NULL_HANDLE
,
848 .imageView
= radv_image_view_to_handle(src
),
849 .imageLayout
= VK_IMAGE_LAYOUT_GENERAL
,
854 .sType
= VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET
,
856 .dstArrayElement
= 0,
857 .descriptorCount
= 1,
858 .descriptorType
= VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
,
859 .pTexelBufferView
= (VkBufferView
[]) { radv_buffer_view_to_handle(dst
) },
865 radv_meta_image_to_buffer(struct radv_cmd_buffer
*cmd_buffer
,
866 struct radv_meta_blit2d_surf
*src
,
867 struct radv_meta_blit2d_buffer
*dst
,
869 struct radv_meta_blit2d_rect
*rects
)
871 VkPipeline pipeline
= cmd_buffer
->device
->meta_state
.itob
.pipeline
;
872 struct radv_device
*device
= cmd_buffer
->device
;
873 struct radv_image_view src_view
;
874 struct radv_buffer_view dst_view
;
876 create_iview(cmd_buffer
, src
, &src_view
);
877 create_bview(cmd_buffer
, dst
->buffer
, dst
->offset
, dst
->format
, &dst_view
);
878 itob_bind_descriptors(cmd_buffer
, &src_view
, &dst_view
);
881 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer
),
882 VK_PIPELINE_BIND_POINT_COMPUTE
, pipeline
);
884 for (unsigned r
= 0; r
< num_rects
; ++r
) {
885 unsigned push_constants
[3] = {
890 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer
),
891 device
->meta_state
.itob
.img_p_layout
,
892 VK_SHADER_STAGE_COMPUTE_BIT
, 0, 12,
895 radv_unaligned_dispatch(cmd_buffer
, rects
[r
].width
, rects
[r
].height
, 1);
900 btoi_bind_descriptors(struct radv_cmd_buffer
*cmd_buffer
,
901 struct radv_buffer_view
*src
,
902 struct radv_image_view
*dst
)
904 struct radv_device
*device
= cmd_buffer
->device
;
906 radv_meta_push_descriptor_set(cmd_buffer
,
907 VK_PIPELINE_BIND_POINT_COMPUTE
,
908 device
->meta_state
.btoi
.img_p_layout
,
910 2, /* descriptorWriteCount */
911 (VkWriteDescriptorSet
[]) {
913 .sType
= VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET
,
915 .dstArrayElement
= 0,
916 .descriptorCount
= 1,
917 .descriptorType
= VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
,
918 .pTexelBufferView
= (VkBufferView
[]) { radv_buffer_view_to_handle(src
) },
921 .sType
= VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET
,
923 .dstArrayElement
= 0,
924 .descriptorCount
= 1,
925 .descriptorType
= VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
,
926 .pImageInfo
= (VkDescriptorImageInfo
[]) {
928 .sampler
= VK_NULL_HANDLE
,
929 .imageView
= radv_image_view_to_handle(dst
),
930 .imageLayout
= VK_IMAGE_LAYOUT_GENERAL
,
938 radv_meta_buffer_to_image_cs(struct radv_cmd_buffer
*cmd_buffer
,
939 struct radv_meta_blit2d_buffer
*src
,
940 struct radv_meta_blit2d_surf
*dst
,
942 struct radv_meta_blit2d_rect
*rects
)
944 VkPipeline pipeline
= cmd_buffer
->device
->meta_state
.btoi
.pipeline
;
945 struct radv_device
*device
= cmd_buffer
->device
;
946 struct radv_buffer_view src_view
;
947 struct radv_image_view dst_view
;
949 create_bview(cmd_buffer
, src
->buffer
, src
->offset
, src
->format
, &src_view
);
950 create_iview(cmd_buffer
, dst
, &dst_view
);
951 btoi_bind_descriptors(cmd_buffer
, &src_view
, &dst_view
);
953 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer
),
954 VK_PIPELINE_BIND_POINT_COMPUTE
, pipeline
);
956 for (unsigned r
= 0; r
< num_rects
; ++r
) {
957 unsigned push_constants
[3] = {
962 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer
),
963 device
->meta_state
.btoi
.img_p_layout
,
964 VK_SHADER_STAGE_COMPUTE_BIT
, 0, 12,
967 radv_unaligned_dispatch(cmd_buffer
, rects
[r
].width
, rects
[r
].height
, 1);
972 itoi_bind_descriptors(struct radv_cmd_buffer
*cmd_buffer
,
973 struct radv_image_view
*src
,
974 struct radv_image_view
*dst
)
976 struct radv_device
*device
= cmd_buffer
->device
;
978 radv_meta_push_descriptor_set(cmd_buffer
,
979 VK_PIPELINE_BIND_POINT_COMPUTE
,
980 device
->meta_state
.itoi
.img_p_layout
,
982 2, /* descriptorWriteCount */
983 (VkWriteDescriptorSet
[]) {
985 .sType
= VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET
,
987 .dstArrayElement
= 0,
988 .descriptorCount
= 1,
989 .descriptorType
= VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
,
990 .pImageInfo
= (VkDescriptorImageInfo
[]) {
992 .sampler
= VK_NULL_HANDLE
,
993 .imageView
= radv_image_view_to_handle(src
),
994 .imageLayout
= VK_IMAGE_LAYOUT_GENERAL
,
999 .sType
= VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET
,
1001 .dstArrayElement
= 0,
1002 .descriptorCount
= 1,
1003 .descriptorType
= VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
,
1004 .pImageInfo
= (VkDescriptorImageInfo
[]) {
1006 .sampler
= VK_NULL_HANDLE
,
1007 .imageView
= radv_image_view_to_handle(dst
),
1008 .imageLayout
= VK_IMAGE_LAYOUT_GENERAL
,
1016 radv_meta_image_to_image_cs(struct radv_cmd_buffer
*cmd_buffer
,
1017 struct radv_meta_blit2d_surf
*src
,
1018 struct radv_meta_blit2d_surf
*dst
,
1020 struct radv_meta_blit2d_rect
*rects
)
1022 VkPipeline pipeline
= cmd_buffer
->device
->meta_state
.itoi
.pipeline
;
1023 struct radv_device
*device
= cmd_buffer
->device
;
1024 struct radv_image_view src_view
, dst_view
;
1026 create_iview(cmd_buffer
, src
, &src_view
);
1027 create_iview(cmd_buffer
, dst
, &dst_view
);
1029 itoi_bind_descriptors(cmd_buffer
, &src_view
, &dst_view
);
1031 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer
),
1032 VK_PIPELINE_BIND_POINT_COMPUTE
, pipeline
);
1034 for (unsigned r
= 0; r
< num_rects
; ++r
) {
1035 unsigned push_constants
[4] = {
1041 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer
),
1042 device
->meta_state
.itoi
.img_p_layout
,
1043 VK_SHADER_STAGE_COMPUTE_BIT
, 0, 16,
1046 radv_unaligned_dispatch(cmd_buffer
, rects
[r
].width
, rects
[r
].height
, 1);
1051 cleari_bind_descriptors(struct radv_cmd_buffer
*cmd_buffer
,
1052 struct radv_image_view
*dst_iview
)
1054 struct radv_device
*device
= cmd_buffer
->device
;
1056 radv_meta_push_descriptor_set(cmd_buffer
,
1057 VK_PIPELINE_BIND_POINT_COMPUTE
,
1058 device
->meta_state
.cleari
.img_p_layout
,
1060 1, /* descriptorWriteCount */
1061 (VkWriteDescriptorSet
[]) {
1063 .sType
= VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET
,
1065 .dstArrayElement
= 0,
1066 .descriptorCount
= 1,
1067 .descriptorType
= VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
,
1068 .pImageInfo
= (VkDescriptorImageInfo
[]) {
1070 .sampler
= VK_NULL_HANDLE
,
1071 .imageView
= radv_image_view_to_handle(dst_iview
),
1072 .imageLayout
= VK_IMAGE_LAYOUT_GENERAL
,
1080 radv_meta_clear_image_cs(struct radv_cmd_buffer
*cmd_buffer
,
1081 struct radv_meta_blit2d_surf
*dst
,
1082 const VkClearColorValue
*clear_color
)
1084 VkPipeline pipeline
= cmd_buffer
->device
->meta_state
.cleari
.pipeline
;
1085 struct radv_device
*device
= cmd_buffer
->device
;
1086 struct radv_image_view dst_iview
;
1088 create_iview(cmd_buffer
, dst
, &dst_iview
);
1089 cleari_bind_descriptors(cmd_buffer
, &dst_iview
);
1091 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer
),
1092 VK_PIPELINE_BIND_POINT_COMPUTE
, pipeline
);
1094 unsigned push_constants
[4] = {
1095 clear_color
->uint32
[0],
1096 clear_color
->uint32
[1],
1097 clear_color
->uint32
[2],
1098 clear_color
->uint32
[3],
1101 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer
),
1102 device
->meta_state
.cleari
.img_p_layout
,
1103 VK_SHADER_STAGE_COMPUTE_BIT
, 0, 16,
1106 radv_unaligned_dispatch(cmd_buffer
, dst
->image
->info
.width
, dst
->image
->info
.height
, 1);