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 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 */ 120 static VkResult 121 radv_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; 204 fail: 205 ralloc_free(cs.nir); 206 return result; 207 } 208 209 static void 210 radv_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 229 static nir_shader * 230 build_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 */ 315 static VkResult 316 radv_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; 399 fail: 400 ralloc_free(cs.nir); 401 return result; 402 } 403 404 static void 405 radv_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 424 static nir_shader * 425 build_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 */ 504 static VkResult 505 radv_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; 588 fail: 589 ralloc_free(cs.nir); 590 return result; 591 } 592 593 static void 594 radv_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 613 static nir_shader * 614 build_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 657 static VkResult 658 radv_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; 734 fail: 735 ralloc_free(cs.nir); 736 return result; 737 } 738 739 static void 740 radv_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 759 void 760 radv_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 768 VkResult 769 radv_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; 790 fail_itoi: 791 radv_device_finish_meta_itoi_state(device); 792 fail_btoi: 793 radv_device_finish_meta_btoi_state(device); 794 fail_itob: 795 radv_device_finish_meta_itob_state(device); 796 return result; 797 } 798 799 void 800 radv_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 806 void 807 radv_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 813 void 814 radv_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 820 void 821 radv_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 827 void 828 radv_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 834 void 835 radv_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 841 static void 842 create_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 864 static void 865 create_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 883 struct itob_temps { 884 struct radv_image_view src_iview; 885 struct radv_buffer_view dst_bview; 886 VkDescriptorSet set; 887 }; 888 889 static void 890 itob_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 935 static void 936 itob_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 947 void 948 radv_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 979 struct btoi_temps { 980 struct radv_buffer_view src_bview; 981 struct radv_image_view dst_iview; 982 VkDescriptorSet set; 983 }; 984 985 static void 986 btoi_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 1031 static void 1032 btoi_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 1043 void 1044 radv_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 1075 struct itoi_temps { 1076 struct radv_image_view src_iview; 1077 struct radv_image_view dst_iview; 1078 VkDescriptorSet set; 1079 }; 1080 1081 static void 1082 itoi_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 1133 static void 1134 itoi_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 1145 void 1146 radv_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 1179 struct cleari_temps { 1180 struct radv_image_view dst_iview; 1181 VkDescriptorSet set; 1182 }; 1183 1184 static void 1185 cleari_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 1221 static void 1222 cleari_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 1233 void 1234 radv_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