2 #include "nir/nir_builder.h"
5 build_nir_itob_compute_shader(struct radv_device
*dev
)
8 const struct glsl_type
*sampler_type
= glsl_sampler_type(GLSL_SAMPLER_DIM_2D
,
12 const struct glsl_type
*img_type
= glsl_sampler_type(GLSL_SAMPLER_DIM_BUF
,
16 nir_builder_init_simple_shader(&b
, NULL
, MESA_SHADER_COMPUTE
, NULL
);
17 b
.shader
->info
->name
= ralloc_strdup(b
.shader
, "meta_itob_cs");
18 b
.shader
->info
->cs
.local_size
[0] = 16;
19 b
.shader
->info
->cs
.local_size
[1] = 16;
20 b
.shader
->info
->cs
.local_size
[2] = 1;
21 nir_variable
*input_img
= nir_variable_create(b
.shader
, nir_var_uniform
,
22 sampler_type
, "s_tex");
23 input_img
->data
.descriptor_set
= 0;
24 input_img
->data
.binding
= 0;
26 nir_variable
*output_img
= nir_variable_create(b
.shader
, nir_var_uniform
,
28 output_img
->data
.descriptor_set
= 0;
29 output_img
->data
.binding
= 1;
31 nir_ssa_def
*invoc_id
= nir_load_system_value(&b
, nir_intrinsic_load_local_invocation_id
, 0);
32 nir_ssa_def
*wg_id
= nir_load_system_value(&b
, nir_intrinsic_load_work_group_id
, 0);
33 nir_ssa_def
*block_size
= nir_imm_ivec4(&b
,
34 b
.shader
->info
->cs
.local_size
[0],
35 b
.shader
->info
->cs
.local_size
[1],
36 b
.shader
->info
->cs
.local_size
[2], 0);
38 nir_ssa_def
*global_id
= nir_iadd(&b
, nir_imul(&b
, wg_id
, block_size
), invoc_id
);
42 nir_intrinsic_instr
*offset
= nir_intrinsic_instr_create(b
.shader
, nir_intrinsic_load_push_constant
);
43 offset
->src
[0] = nir_src_for_ssa(nir_imm_int(&b
, 0));
44 offset
->num_components
= 2;
45 nir_ssa_dest_init(&offset
->instr
, &offset
->dest
, 2, 32, "offset");
46 nir_builder_instr_insert(&b
, &offset
->instr
);
48 nir_intrinsic_instr
*stride
= nir_intrinsic_instr_create(b
.shader
, nir_intrinsic_load_push_constant
);
49 stride
->src
[0] = nir_src_for_ssa(nir_imm_int(&b
, 8));
50 stride
->num_components
= 1;
51 nir_ssa_dest_init(&stride
->instr
, &stride
->dest
, 1, 32, "stride");
52 nir_builder_instr_insert(&b
, &stride
->instr
);
54 nir_ssa_def
*img_coord
= nir_iadd(&b
, global_id
, &offset
->dest
.ssa
);
56 nir_tex_instr
*tex
= nir_tex_instr_create(b
.shader
, 2);
57 tex
->sampler_dim
= GLSL_SAMPLER_DIM_2D
;
58 tex
->op
= nir_texop_txf
;
59 tex
->src
[0].src_type
= nir_tex_src_coord
;
60 tex
->src
[0].src
= nir_src_for_ssa(img_coord
);
61 tex
->src
[1].src_type
= nir_tex_src_lod
;
62 tex
->src
[1].src
= nir_src_for_ssa(nir_imm_int(&b
, 0));
63 tex
->dest_type
= nir_type_float
;
64 tex
->is_array
= false;
65 tex
->coord_components
= 2;
66 tex
->texture
= nir_deref_var_create(tex
, input_img
);
69 nir_ssa_dest_init(&tex
->instr
, &tex
->dest
, 4, 32, "tex");
70 nir_builder_instr_insert(&b
, &tex
->instr
);
72 nir_ssa_def
*pos_x
= nir_channel(&b
, global_id
, 0);
73 nir_ssa_def
*pos_y
= nir_channel(&b
, global_id
, 1);
75 nir_ssa_def
*tmp
= nir_imul(&b
, pos_y
, &stride
->dest
.ssa
);
76 tmp
= nir_iadd(&b
, tmp
, pos_x
);
78 nir_ssa_def
*coord
= nir_vec4(&b
, tmp
, tmp
, tmp
, tmp
);
80 nir_ssa_def
*outval
= &tex
->dest
.ssa
;
81 nir_intrinsic_instr
*store
= nir_intrinsic_instr_create(b
.shader
, nir_intrinsic_image_store
);
82 store
->src
[0] = nir_src_for_ssa(coord
);
83 store
->src
[1] = nir_src_for_ssa(nir_ssa_undef(&b
, 1, 32));
84 store
->src
[2] = nir_src_for_ssa(outval
);
85 store
->variables
[0] = nir_deref_var_create(store
, output_img
);
87 nir_builder_instr_insert(&b
, &store
->instr
);
91 /* Image to buffer - don't write use image accessors */
93 radv_device_init_meta_itob_state(struct radv_device
*device
)
96 struct radv_shader_module cs
= { .nir
= NULL
};
98 zero(device
->meta_state
.itob
);
100 cs
.nir
= build_nir_itob_compute_shader(device
);
103 * two descriptors one for the image being sampled
104 * one for the buffer being written.
106 VkDescriptorSetLayoutCreateInfo ds_create_info
= {
107 .sType
= VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
,
109 .pBindings
= (VkDescriptorSetLayoutBinding
[]) {
112 .descriptorType
= VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
,
113 .descriptorCount
= 1,
114 .stageFlags
= VK_SHADER_STAGE_COMPUTE_BIT
,
115 .pImmutableSamplers
= NULL
119 .descriptorType
= VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
,
120 .descriptorCount
= 1,
121 .stageFlags
= VK_SHADER_STAGE_COMPUTE_BIT
,
122 .pImmutableSamplers
= NULL
127 result
= radv_CreateDescriptorSetLayout(radv_device_to_handle(device
),
129 &device
->meta_state
.alloc
,
130 &device
->meta_state
.itob
.img_ds_layout
);
131 if (result
!= VK_SUCCESS
)
135 VkPipelineLayoutCreateInfo pl_create_info
= {
136 .sType
= VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
,
138 .pSetLayouts
= &device
->meta_state
.itob
.img_ds_layout
,
139 .pushConstantRangeCount
= 1,
140 .pPushConstantRanges
= &(VkPushConstantRange
){VK_SHADER_STAGE_COMPUTE_BIT
, 0, 12},
143 result
= radv_CreatePipelineLayout(radv_device_to_handle(device
),
145 &device
->meta_state
.alloc
,
146 &device
->meta_state
.itob
.img_p_layout
);
147 if (result
!= VK_SUCCESS
)
152 VkPipelineShaderStageCreateInfo pipeline_shader_stage
= {
153 .sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
,
154 .stage
= VK_SHADER_STAGE_COMPUTE_BIT
,
155 .module
= radv_shader_module_to_handle(&cs
),
157 .pSpecializationInfo
= NULL
,
160 VkComputePipelineCreateInfo vk_pipeline_info
= {
161 .sType
= VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO
,
162 .stage
= pipeline_shader_stage
,
164 .layout
= device
->meta_state
.itob
.img_p_layout
,
167 result
= radv_CreateComputePipelines(radv_device_to_handle(device
),
168 radv_pipeline_cache_to_handle(&device
->meta_state
.cache
),
169 1, &vk_pipeline_info
, NULL
,
170 &device
->meta_state
.itob
.pipeline
);
171 if (result
!= VK_SUCCESS
)
182 radv_device_finish_meta_itob_state(struct radv_device
*device
)
184 if (device
->meta_state
.itob
.img_p_layout
) {
185 radv_DestroyPipelineLayout(radv_device_to_handle(device
),
186 device
->meta_state
.itob
.img_p_layout
,
187 &device
->meta_state
.alloc
);
189 if (device
->meta_state
.itob
.img_ds_layout
) {
190 radv_DestroyDescriptorSetLayout(radv_device_to_handle(device
),
191 device
->meta_state
.itob
.img_ds_layout
,
192 &device
->meta_state
.alloc
);
194 if (device
->meta_state
.itob
.pipeline
) {
195 radv_DestroyPipeline(radv_device_to_handle(device
),
196 device
->meta_state
.itob
.pipeline
,
197 &device
->meta_state
.alloc
);
202 radv_device_finish_meta_bufimage_state(struct radv_device
*device
)
204 radv_device_finish_meta_itob_state(device
);
208 radv_device_init_meta_bufimage_state(struct radv_device
*device
)
212 result
= radv_device_init_meta_itob_state(device
);
213 if (result
!= VK_SUCCESS
)
219 radv_meta_begin_bufimage(struct radv_cmd_buffer
*cmd_buffer
,
220 struct radv_meta_saved_compute_state
*save
)
222 radv_meta_save_compute(save
, cmd_buffer
, 12);
226 radv_meta_end_bufimage(struct radv_cmd_buffer
*cmd_buffer
,
227 struct radv_meta_saved_compute_state
*save
)
229 radv_meta_restore_compute(save
, cmd_buffer
, 12);
233 create_iview(struct radv_cmd_buffer
*cmd_buffer
,
234 struct radv_meta_blit2d_surf
*surf
,
235 VkImageUsageFlags usage
,
236 struct radv_image_view
*iview
)
239 radv_image_view_init(iview
, cmd_buffer
->device
,
240 &(VkImageViewCreateInfo
) {
241 .sType
= VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
,
242 .image
= radv_image_to_handle(surf
->image
),
243 .viewType
= VK_IMAGE_VIEW_TYPE_2D
,
244 .format
= surf
->format
,
245 .subresourceRange
= {
246 .aspectMask
= surf
->aspect_mask
,
247 .baseMipLevel
= surf
->level
,
249 .baseArrayLayer
= surf
->layer
,
252 }, cmd_buffer
, usage
);
256 create_bview(struct radv_cmd_buffer
*cmd_buffer
,
257 struct radv_buffer
*buffer
,
260 struct radv_buffer_view
*bview
)
262 radv_buffer_view_init(bview
, cmd_buffer
->device
,
263 &(VkBufferViewCreateInfo
) {
264 .sType
= VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO
,
266 .buffer
= radv_buffer_to_handle(buffer
),
269 .range
= VK_WHOLE_SIZE
,
275 struct radv_image_view src_iview
;
277 struct radv_buffer_view dst_bview
;
282 itob_bind_src_image(struct radv_cmd_buffer
*cmd_buffer
,
283 struct radv_meta_blit2d_surf
*src
,
284 struct radv_meta_blit2d_rect
*rect
,
285 struct itob_temps
*tmp
)
287 create_iview(cmd_buffer
, src
, VK_IMAGE_USAGE_SAMPLED_BIT
, &tmp
->src_iview
);
291 itob_bind_dst_buffer(struct radv_cmd_buffer
*cmd_buffer
,
292 struct radv_meta_blit2d_buffer
*dst
,
293 struct radv_meta_blit2d_rect
*rect
,
294 struct itob_temps
*tmp
)
296 create_bview(cmd_buffer
, dst
->buffer
, dst
->offset
, dst
->format
, &tmp
->dst_bview
);
300 itob_bind_descriptors(struct radv_cmd_buffer
*cmd_buffer
,
301 struct itob_temps
*tmp
)
303 struct radv_device
*device
= cmd_buffer
->device
;
304 VkDevice vk_device
= radv_device_to_handle(cmd_buffer
->device
);
306 radv_temp_descriptor_set_create(device
, cmd_buffer
,
307 device
->meta_state
.itob
.img_ds_layout
,
310 radv_UpdateDescriptorSets(vk_device
,
312 (VkWriteDescriptorSet
[]) {
314 .sType
= VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET
,
317 .dstArrayElement
= 0,
318 .descriptorCount
= 1,
319 .descriptorType
= VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
,
320 .pImageInfo
= (VkDescriptorImageInfo
[]) {
323 .imageView
= radv_image_view_to_handle(&tmp
->src_iview
),
324 .imageLayout
= VK_IMAGE_LAYOUT_GENERAL
,
329 .sType
= VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET
,
332 .dstArrayElement
= 0,
333 .descriptorCount
= 1,
334 .descriptorType
= VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
,
335 .pTexelBufferView
= (VkBufferView
[]) { radv_buffer_view_to_handle(&tmp
->dst_bview
) },
339 radv_CmdBindDescriptorSets(radv_cmd_buffer_to_handle(cmd_buffer
),
340 VK_PIPELINE_BIND_POINT_COMPUTE
,
341 device
->meta_state
.itob
.img_p_layout
, 0, 1,
346 itob_unbind_src_image(struct radv_cmd_buffer
*cmd_buffer
,
347 struct itob_temps
*temps
)
352 bind_pipeline(struct radv_cmd_buffer
*cmd_buffer
)
354 VkPipeline pipeline
=
355 cmd_buffer
->device
->meta_state
.itob
.pipeline
;
357 if (cmd_buffer
->state
.compute_pipeline
!= radv_pipeline_from_handle(pipeline
)) {
358 radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer
),
359 VK_PIPELINE_BIND_POINT_COMPUTE
, pipeline
);
364 radv_meta_image_to_buffer(struct radv_cmd_buffer
*cmd_buffer
,
365 struct radv_meta_blit2d_surf
*src
,
366 struct radv_meta_blit2d_buffer
*dst
,
368 struct radv_meta_blit2d_rect
*rects
)
370 struct radv_device
*device
= cmd_buffer
->device
;
372 for (unsigned r
= 0; r
< num_rects
; ++r
) {
373 struct itob_temps temps
;
375 itob_bind_src_image(cmd_buffer
, src
, &rects
[r
], &temps
);
376 itob_bind_dst_buffer(cmd_buffer
, dst
, &rects
[r
], &temps
);
377 itob_bind_descriptors(cmd_buffer
, &temps
);
379 bind_pipeline(cmd_buffer
);
381 unsigned push_constants
[3] = {
386 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer
),
387 device
->meta_state
.itob
.img_p_layout
,
388 VK_SHADER_STAGE_COMPUTE_BIT
, 0, 12,
391 radv_unaligned_dispatch(cmd_buffer
, rects
[r
].width
, rects
[r
].height
, 1);
392 radv_temp_descriptor_set_destroy(cmd_buffer
->device
, temps
.set
);
393 itob_unbind_src_image(cmd_buffer
, &temps
);