1 /* 2 * Copyright 2016 Red Hat. 3 * Copyright 2016 Bas Nieuwenhuizen 4 * 5 * based in part on anv driver which is: 6 * Copyright 2015 Intel Corporation 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the next 16 * paragraph) shall be included in all copies or substantial portions of the 17 * Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 25 * IN THE SOFTWARE. 26 */ 27 28 #include "util/mesa-sha1.h" 29 #include "radv_private.h" 30 #include "nir/nir.h" 31 #include "nir/nir_builder.h" 32 #include "spirv/nir_spirv.h" 33 34 #include <llvm-c/Core.h> 35 #include <llvm-c/TargetMachine.h> 36 37 #include "sid.h" 38 #include "r600d_common.h" 39 #include "ac_binary.h" 40 #include "ac_llvm_util.h" 41 #include "ac_nir_to_llvm.h" 42 #include "vk_format.h" 43 #include "util/debug.h" 44 void radv_shader_variant_destroy(struct radv_device *device, 45 struct radv_shader_variant *variant); 46 47 static const struct nir_shader_compiler_options nir_options = { 48 .vertex_id_zero_based = true, 49 .lower_scmp = true, 50 .lower_flrp32 = true, 51 .lower_fsat = true, 52 .lower_pack_snorm_2x16 = true, 53 .lower_pack_snorm_4x8 = true, 54 .lower_pack_unorm_2x16 = true, 55 .lower_pack_unorm_4x8 = true, 56 .lower_unpack_snorm_2x16 = true, 57 .lower_unpack_snorm_4x8 = true, 58 .lower_unpack_unorm_2x16 = true, 59 .lower_unpack_unorm_4x8 = true, 60 .lower_extract_byte = true, 61 .lower_extract_word = true, 62 }; 63 64 VkResult radv_CreateShaderModule( 65 VkDevice _device, 66 const VkShaderModuleCreateInfo* pCreateInfo, 67 const VkAllocationCallbacks* pAllocator, 68 VkShaderModule* pShaderModule) 69 { 70 RADV_FROM_HANDLE(radv_device, device, _device); 71 struct radv_shader_module *module; 72 73 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO); 74 assert(pCreateInfo->flags == 0); 75 76 module = vk_alloc2(&device->alloc, pAllocator, 77 sizeof(*module) + pCreateInfo->codeSize, 8, 78 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 79 if (module == NULL) 80 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 81 82 module->nir = NULL; 83 module->size = pCreateInfo->codeSize; 84 memcpy(module->data, pCreateInfo->pCode, module->size); 85 86 _mesa_sha1_compute(module->data, module->size, module->sha1); 87 88 *pShaderModule = radv_shader_module_to_handle(module); 89 90 return VK_SUCCESS; 91 } 92 93 void radv_DestroyShaderModule( 94 VkDevice _device, 95 VkShaderModule _module, 96 const VkAllocationCallbacks* pAllocator) 97 { 98 RADV_FROM_HANDLE(radv_device, device, _device); 99 RADV_FROM_HANDLE(radv_shader_module, module, _module); 100 101 if (!module) 102 return; 103 104 vk_free2(&device->alloc, pAllocator, module); 105 } 106 107 void radv_DestroyPipeline( 108 VkDevice _device, 109 VkPipeline _pipeline, 110 const VkAllocationCallbacks* pAllocator) 111 { 112 RADV_FROM_HANDLE(radv_device, device, _device); 113 RADV_FROM_HANDLE(radv_pipeline, pipeline, _pipeline); 114 115 if (!_pipeline) 116 return; 117 118 for (unsigned i = 0; i < MESA_SHADER_STAGES; ++i) 119 if (pipeline->shaders[i]) 120 radv_shader_variant_destroy(device, pipeline->shaders[i]); 121 122 vk_free2(&device->alloc, pAllocator, pipeline); 123 } 124 125 126 static void 127 radv_optimize_nir(struct nir_shader *shader) 128 { 129 bool progress; 130 131 do { 132 progress = false; 133 134 NIR_PASS_V(shader, nir_lower_vars_to_ssa); 135 NIR_PASS_V(shader, nir_lower_alu_to_scalar); 136 NIR_PASS_V(shader, nir_lower_phis_to_scalar); 137 138 NIR_PASS(progress, shader, nir_copy_prop); 139 NIR_PASS(progress, shader, nir_opt_remove_phis); 140 NIR_PASS(progress, shader, nir_opt_dce); 141 NIR_PASS(progress, shader, nir_opt_dead_cf); 142 NIR_PASS(progress, shader, nir_opt_cse); 143 NIR_PASS(progress, shader, nir_opt_peephole_select, 8); 144 NIR_PASS(progress, shader, nir_opt_algebraic); 145 NIR_PASS(progress, shader, nir_opt_constant_folding); 146 NIR_PASS(progress, shader, nir_opt_undef); 147 NIR_PASS(progress, shader, nir_opt_conditional_discard); 148 } while (progress); 149 } 150 151 static nir_shader * 152 radv_shader_compile_to_nir(struct radv_device *device, 153 struct radv_shader_module *module, 154 const char *entrypoint_name, 155 gl_shader_stage stage, 156 const VkSpecializationInfo *spec_info, 157 bool dump) 158 { 159 if (strcmp(entrypoint_name, "main") != 0) { 160 radv_finishme("Multiple shaders per module not really supported"); 161 } 162 163 nir_shader *nir; 164 nir_function *entry_point; 165 if (module->nir) { 166 /* Some things such as our meta clear/blit code will give us a NIR 167 * shader directly. In that case, we just ignore the SPIR-V entirely 168 * and just use the NIR shader */ 169 nir = module->nir; 170 nir->options = &nir_options; 171 nir_validate_shader(nir); 172 173 assert(exec_list_length(&nir->functions) == 1); 174 struct exec_node *node = exec_list_get_head(&nir->functions); 175 entry_point = exec_node_data(nir_function, node, node); 176 } else { 177 uint32_t *spirv = (uint32_t *) module->data; 178 assert(module->size % 4 == 0); 179 180 uint32_t num_spec_entries = 0; 181 struct nir_spirv_specialization *spec_entries = NULL; 182 if (spec_info && spec_info->mapEntryCount > 0) { 183 num_spec_entries = spec_info->mapEntryCount; 184 spec_entries = malloc(num_spec_entries * sizeof(*spec_entries)); 185 for (uint32_t i = 0; i < num_spec_entries; i++) { 186 VkSpecializationMapEntry entry = spec_info->pMapEntries[i]; 187 const void *data = spec_info->pData + entry.offset; 188 assert(data + entry.size <= spec_info->pData + spec_info->dataSize); 189 190 spec_entries[i].id = spec_info->pMapEntries[i].constantID; 191 if (spec_info->dataSize == 8) 192 spec_entries[i].data64 = *(const uint64_t *)data; 193 else 194 spec_entries[i].data32 = *(const uint32_t *)data; 195 } 196 } 197 const struct nir_spirv_supported_extensions supported_ext = { 198 }; 199 entry_point = spirv_to_nir(spirv, module->size / 4, 200 spec_entries, num_spec_entries, 201 stage, entrypoint_name, &supported_ext, &nir_options); 202 nir = entry_point->shader; 203 assert(nir->stage == stage); 204 nir_validate_shader(nir); 205 206 free(spec_entries); 207 208 /* We have to lower away local constant initializers right before we 209 * inline functions. That way they get properly initialized at the top 210 * of the function and not at the top of its caller. 211 */ 212 NIR_PASS_V(nir, nir_lower_constant_initializers, nir_var_local); 213 NIR_PASS_V(nir, nir_lower_returns); 214 NIR_PASS_V(nir, nir_inline_functions); 215 216 /* Pick off the single entrypoint that we want */ 217 foreach_list_typed_safe(nir_function, func, node, &nir->functions) { 218 if (func != entry_point) 219 exec_node_remove(&func->node); 220 } 221 assert(exec_list_length(&nir->functions) == 1); 222 entry_point->name = ralloc_strdup(entry_point, "main"); 223 224 NIR_PASS_V(nir, nir_remove_dead_variables, 225 nir_var_shader_in | nir_var_shader_out | nir_var_system_value); 226 227 /* Now that we've deleted all but the main function, we can go ahead and 228 * lower the rest of the constant initializers. 229 */ 230 NIR_PASS_V(nir, nir_lower_constant_initializers, ~0); 231 NIR_PASS_V(nir, nir_lower_system_values); 232 } 233 234 /* Vulkan uses the separate-shader linking model */ 235 nir->info->separate_shader = true; 236 237 // nir = brw_preprocess_nir(compiler, nir); 238 239 nir_shader_gather_info(nir, entry_point->impl); 240 241 nir_variable_mode indirect_mask = 0; 242 // if (compiler->glsl_compiler_options[stage].EmitNoIndirectInput) 243 indirect_mask |= nir_var_shader_in; 244 // if (compiler->glsl_compiler_options[stage].EmitNoIndirectTemp) 245 indirect_mask |= nir_var_local; 246 247 nir_lower_indirect_derefs(nir, indirect_mask); 248 249 static const nir_lower_tex_options tex_options = { 250 .lower_txp = ~0, 251 }; 252 253 nir_lower_tex(nir, &tex_options); 254 255 nir_lower_vars_to_ssa(nir); 256 nir_lower_var_copies(nir); 257 nir_lower_global_vars_to_local(nir); 258 nir_remove_dead_variables(nir, nir_var_local); 259 radv_optimize_nir(nir); 260 261 if (dump) 262 nir_print_shader(nir, stderr); 263 264 return nir; 265 } 266 267 static const char *radv_get_shader_name(struct radv_shader_variant *var, 268 gl_shader_stage stage) 269 { 270 switch (stage) { 271 case MESA_SHADER_VERTEX: return "Vertex Shader as VS"; 272 case MESA_SHADER_FRAGMENT: return "Pixel Shader"; 273 case MESA_SHADER_COMPUTE: return "Compute Shader"; 274 default: 275 return "Unknown shader"; 276 }; 277 278 } 279 static void radv_dump_pipeline_stats(struct radv_device *device, struct radv_pipeline *pipeline) 280 { 281 unsigned lds_increment = device->physical_device->rad_info.chip_class >= CIK ? 512 : 256; 282 struct radv_shader_variant *var; 283 struct ac_shader_config *conf; 284 int i; 285 FILE *file = stderr; 286 unsigned max_simd_waves = 10; 287 unsigned lds_per_wave = 0; 288 289 for (i = 0; i < MESA_SHADER_STAGES; i++) { 290 if (!pipeline->shaders[i]) 291 continue; 292 var = pipeline->shaders[i]; 293 294 conf = &var->config; 295 296 if (i == MESA_SHADER_FRAGMENT) { 297 lds_per_wave = conf->lds_size * lds_increment + 298 align(var->info.fs.num_interp * 48, lds_increment); 299 } 300 301 if (conf->num_sgprs) { 302 if (device->physical_device->rad_info.chip_class >= VI) 303 max_simd_waves = MIN2(max_simd_waves, 800 / conf->num_sgprs); 304 else 305 max_simd_waves = MIN2(max_simd_waves, 512 / conf->num_sgprs); 306 } 307 308 if (conf->num_vgprs) 309 max_simd_waves = MIN2(max_simd_waves, 256 / conf->num_vgprs); 310 311 /* LDS is 64KB per CU (4 SIMDs), divided into 16KB blocks per SIMD 312 * that PS can use. 313 */ 314 if (lds_per_wave) 315 max_simd_waves = MIN2(max_simd_waves, 16384 / lds_per_wave); 316 317 fprintf(file, "\n%s:\n", 318 radv_get_shader_name(var, i)); 319 if (i == MESA_SHADER_FRAGMENT) { 320 fprintf(file, "*** SHADER CONFIG ***\n" 321 "SPI_PS_INPUT_ADDR = 0x%04x\n" 322 "SPI_PS_INPUT_ENA = 0x%04x\n", 323 conf->spi_ps_input_addr, conf->spi_ps_input_ena); 324 } 325 fprintf(file, "*** SHADER STATS ***\n" 326 "SGPRS: %d\n" 327 "VGPRS: %d\n" 328 "Spilled SGPRs: %d\n" 329 "Spilled VGPRs: %d\n" 330 "Code Size: %d bytes\n" 331 "LDS: %d blocks\n" 332 "Scratch: %d bytes per wave\n" 333 "Max Waves: %d\n" 334 "********************\n\n\n", 335 conf->num_sgprs, conf->num_vgprs, 336 conf->spilled_sgprs, conf->spilled_vgprs, var->code_size, 337 conf->lds_size, conf->scratch_bytes_per_wave, 338 max_simd_waves); 339 } 340 } 341 342 void radv_shader_variant_destroy(struct radv_device *device, 343 struct radv_shader_variant *variant) 344 { 345 if (__sync_fetch_and_sub(&variant->ref_count, 1) != 1) 346 return; 347 348 device->ws->buffer_destroy(variant->bo); 349 free(variant); 350 } 351 352 static void radv_fill_shader_variant(struct radv_device *device, 353 struct radv_shader_variant *variant, 354 struct ac_shader_binary *binary, 355 gl_shader_stage stage) 356 { 357 variant->code_size = binary->code_size; 358 bool scratch_enabled = variant->config.scratch_bytes_per_wave > 0; 359 unsigned vgpr_comp_cnt = 0; 360 361 if (scratch_enabled) 362 radv_finishme("shader scratch space"); 363 364 switch (stage) { 365 case MESA_SHADER_VERTEX: 366 variant->rsrc2 = S_00B12C_USER_SGPR(variant->info.num_user_sgprs) | 367 S_00B12C_SCRATCH_EN(scratch_enabled); 368 vgpr_comp_cnt = variant->info.vs.vgpr_comp_cnt; 369 break; 370 case MESA_SHADER_FRAGMENT: 371 variant->rsrc2 = S_00B12C_USER_SGPR(variant->info.num_user_sgprs) | 372 S_00B12C_SCRATCH_EN(scratch_enabled); 373 break; 374 case MESA_SHADER_COMPUTE: 375 variant->rsrc2 = S_00B84C_USER_SGPR(variant->info.num_user_sgprs) | 376 S_00B84C_SCRATCH_EN(scratch_enabled) | 377 S_00B84C_TGID_X_EN(1) | S_00B84C_TGID_Y_EN(1) | 378 S_00B84C_TGID_Z_EN(1) | S_00B84C_TIDIG_COMP_CNT(2) | 379 S_00B84C_TG_SIZE_EN(1) | 380 S_00B84C_LDS_SIZE(variant->config.lds_size); 381 break; 382 default: 383 unreachable("unsupported shader type"); 384 break; 385 } 386 387 variant->rsrc1 = S_00B848_VGPRS((variant->config.num_vgprs - 1) / 4) | 388 S_00B848_SGPRS((variant->config.num_sgprs - 1) / 8) | 389 S_00B128_VGPR_COMP_CNT(vgpr_comp_cnt) | 390 S_00B848_DX10_CLAMP(1) | 391 S_00B848_FLOAT_MODE(variant->config.float_mode); 392 393 variant->bo = device->ws->buffer_create(device->ws, binary->code_size, 256, 394 RADEON_DOMAIN_GTT, RADEON_FLAG_CPU_ACCESS); 395 396 void *ptr = device->ws->buffer_map(variant->bo); 397 memcpy(ptr, binary->code, binary->code_size); 398 device->ws->buffer_unmap(variant->bo); 399 400 401 } 402 403 static struct radv_shader_variant *radv_shader_variant_create(struct radv_device *device, 404 struct nir_shader *shader, 405 struct radv_pipeline_layout *layout, 406 const union ac_shader_variant_key *key, 407 void** code_out, 408 unsigned *code_size_out, 409 bool dump) 410 { 411 struct radv_shader_variant *variant = calloc(1, sizeof(struct radv_shader_variant)); 412 enum radeon_family chip_family = device->physical_device->rad_info.family; 413 LLVMTargetMachineRef tm; 414 if (!variant) 415 return NULL; 416 417 struct ac_nir_compiler_options options = {0}; 418 options.layout = layout; 419 if (key) 420 options.key = *key; 421 422 struct ac_shader_binary binary; 423 424 options.unsafe_math = !!(device->debug_flags & RADV_DEBUG_UNSAFE_MATH); 425 options.family = chip_family; 426 options.chip_class = device->physical_device->rad_info.chip_class; 427 tm = ac_create_target_machine(chip_family); 428 ac_compile_nir_shader(tm, &binary, &variant->config, 429 &variant->info, shader, &options, dump); 430 LLVMDisposeTargetMachine(tm); 431 432 radv_fill_shader_variant(device, variant, &binary, shader->stage); 433 434 if (code_out) { 435 *code_out = binary.code; 436 *code_size_out = binary.code_size; 437 } else 438 free(binary.code); 439 free(binary.config); 440 free(binary.rodata); 441 free(binary.global_symbol_offsets); 442 free(binary.relocs); 443 free(binary.disasm_string); 444 variant->ref_count = 1; 445 return variant; 446 } 447 448 449 static struct radv_shader_variant * 450 radv_pipeline_compile(struct radv_pipeline *pipeline, 451 struct radv_pipeline_cache *cache, 452 struct radv_shader_module *module, 453 const char *entrypoint, 454 gl_shader_stage stage, 455 const VkSpecializationInfo *spec_info, 456 struct radv_pipeline_layout *layout, 457 const union ac_shader_variant_key *key) 458 { 459 unsigned char sha1[20]; 460 struct radv_shader_variant *variant; 461 nir_shader *nir; 462 void *code = NULL; 463 unsigned code_size = 0; 464 bool dump = (pipeline->device->debug_flags & RADV_DEBUG_DUMP_SHADERS); 465 466 if (module->nir) 467 _mesa_sha1_compute(module->nir->info->name, 468 strlen(module->nir->info->name), 469 module->sha1); 470 471 radv_hash_shader(sha1, module, entrypoint, spec_info, layout, key); 472 473 if (cache) { 474 variant = radv_create_shader_variant_from_pipeline_cache(pipeline->device, 475 cache, 476 sha1); 477 if (variant) 478 return variant; 479 } 480 481 nir = radv_shader_compile_to_nir(pipeline->device, 482 module, entrypoint, stage, 483 spec_info, dump); 484 if (nir == NULL) 485 return NULL; 486 487 variant = radv_shader_variant_create(pipeline->device, nir, layout, key, 488 &code, &code_size, dump); 489 if (!module->nir) 490 ralloc_free(nir); 491 492 if (variant && cache) 493 variant = radv_pipeline_cache_insert_shader(cache, sha1, variant, 494 code, code_size); 495 496 if (code) 497 free(code); 498 return variant; 499 } 500 501 static uint32_t si_translate_blend_function(VkBlendOp op) 502 { 503 switch (op) { 504 case VK_BLEND_OP_ADD: 505 return V_028780_COMB_DST_PLUS_SRC; 506 case VK_BLEND_OP_SUBTRACT: 507 return V_028780_COMB_SRC_MINUS_DST; 508 case VK_BLEND_OP_REVERSE_SUBTRACT: 509 return V_028780_COMB_DST_MINUS_SRC; 510 case VK_BLEND_OP_MIN: 511 return V_028780_COMB_MIN_DST_SRC; 512 case VK_BLEND_OP_MAX: 513 return V_028780_COMB_MAX_DST_SRC; 514 default: 515 return 0; 516 } 517 } 518 519 static uint32_t si_translate_blend_factor(VkBlendFactor factor) 520 { 521 switch (factor) { 522 case VK_BLEND_FACTOR_ZERO: 523 return V_028780_BLEND_ZERO; 524 case VK_BLEND_FACTOR_ONE: 525 return V_028780_BLEND_ONE; 526 case VK_BLEND_FACTOR_SRC_COLOR: 527 return V_028780_BLEND_SRC_COLOR; 528 case VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR: 529 return V_028780_BLEND_ONE_MINUS_SRC_COLOR; 530 case VK_BLEND_FACTOR_DST_COLOR: 531 return V_028780_BLEND_DST_COLOR; 532 case VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR: 533 return V_028780_BLEND_ONE_MINUS_DST_COLOR; 534 case VK_BLEND_FACTOR_SRC_ALPHA: 535 return V_028780_BLEND_SRC_ALPHA; 536 case VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: 537 return V_028780_BLEND_ONE_MINUS_SRC_ALPHA; 538 case VK_BLEND_FACTOR_DST_ALPHA: 539 return V_028780_BLEND_DST_ALPHA; 540 case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: 541 return V_028780_BLEND_ONE_MINUS_DST_ALPHA; 542 case VK_BLEND_FACTOR_CONSTANT_COLOR: 543 return V_028780_BLEND_CONSTANT_COLOR; 544 case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR: 545 return V_028780_BLEND_ONE_MINUS_CONSTANT_COLOR; 546 case VK_BLEND_FACTOR_CONSTANT_ALPHA: 547 return V_028780_BLEND_CONSTANT_ALPHA; 548 case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA: 549 return V_028780_BLEND_ONE_MINUS_CONSTANT_ALPHA; 550 case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE: 551 return V_028780_BLEND_SRC_ALPHA_SATURATE; 552 case VK_BLEND_FACTOR_SRC1_COLOR: 553 return V_028780_BLEND_SRC1_COLOR; 554 case VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR: 555 return V_028780_BLEND_INV_SRC1_COLOR; 556 case VK_BLEND_FACTOR_SRC1_ALPHA: 557 return V_028780_BLEND_SRC1_ALPHA; 558 case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA: 559 return V_028780_BLEND_INV_SRC1_ALPHA; 560 default: 561 return 0; 562 } 563 } 564 565 static bool is_dual_src(VkBlendFactor factor) 566 { 567 switch (factor) { 568 case VK_BLEND_FACTOR_SRC1_COLOR: 569 case VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR: 570 case VK_BLEND_FACTOR_SRC1_ALPHA: 571 case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA: 572 return true; 573 default: 574 return false; 575 } 576 } 577 578 static unsigned si_choose_spi_color_format(VkFormat vk_format, 579 bool blend_enable, 580 bool blend_need_alpha) 581 { 582 const struct vk_format_description *desc = vk_format_description(vk_format); 583 unsigned format, ntype, swap; 584 585 /* Alpha is needed for alpha-to-coverage. 586 * Blending may be with or without alpha. 587 */ 588 unsigned normal = 0; /* most optimal, may not support blending or export alpha */ 589 unsigned alpha = 0; /* exports alpha, but may not support blending */ 590 unsigned blend = 0; /* supports blending, but may not export alpha */ 591 unsigned blend_alpha = 0; /* least optimal, supports blending and exports alpha */ 592 593 format = radv_translate_colorformat(vk_format); 594 ntype = radv_translate_color_numformat(vk_format, desc, 595 vk_format_get_first_non_void_channel(vk_format)); 596 swap = radv_translate_colorswap(vk_format, false); 597 598 /* Choose the SPI color formats. These are required values for Stoney/RB+. 599 * Other chips have multiple choices, though they are not necessarily better. 600 */ 601 switch (format) { 602 case V_028C70_COLOR_5_6_5: 603 case V_028C70_COLOR_1_5_5_5: 604 case V_028C70_COLOR_5_5_5_1: 605 case V_028C70_COLOR_4_4_4_4: 606 case V_028C70_COLOR_10_11_11: 607 case V_028C70_COLOR_11_11_10: 608 case V_028C70_COLOR_8: 609 case V_028C70_COLOR_8_8: 610 case V_028C70_COLOR_8_8_8_8: 611 case V_028C70_COLOR_10_10_10_2: 612 case V_028C70_COLOR_2_10_10_10: 613 if (ntype == V_028C70_NUMBER_UINT) 614 alpha = blend = blend_alpha = normal = V_028714_SPI_SHADER_UINT16_ABGR; 615 else if (ntype == V_028C70_NUMBER_SINT) 616 alpha = blend = blend_alpha = normal = V_028714_SPI_SHADER_SINT16_ABGR; 617 else 618 alpha = blend = blend_alpha = normal = V_028714_SPI_SHADER_FP16_ABGR; 619 break; 620 621 case V_028C70_COLOR_16: 622 case V_028C70_COLOR_16_16: 623 case V_028C70_COLOR_16_16_16_16: 624 if (ntype == V_028C70_NUMBER_UNORM || 625 ntype == V_028C70_NUMBER_SNORM) { 626 /* UNORM16 and SNORM16 don't support blending */ 627 if (ntype == V_028C70_NUMBER_UNORM) 628 normal = alpha = V_028714_SPI_SHADER_UNORM16_ABGR; 629 else 630 normal = alpha = V_028714_SPI_SHADER_SNORM16_ABGR; 631 632 /* Use 32 bits per channel for blending. */ 633 if (format == V_028C70_COLOR_16) { 634 if (swap == V_028C70_SWAP_STD) { /* R */ 635 blend = V_028714_SPI_SHADER_32_R; 636 blend_alpha = V_028714_SPI_SHADER_32_AR; 637 } else if (swap == V_028C70_SWAP_ALT_REV) /* A */ 638 blend = blend_alpha = V_028714_SPI_SHADER_32_AR; 639 else 640 assert(0); 641 } else if (format == V_028C70_COLOR_16_16) { 642 if (swap == V_028C70_SWAP_STD) { /* RG */ 643 blend = V_028714_SPI_SHADER_32_GR; 644 blend_alpha = V_028714_SPI_SHADER_32_ABGR; 645 } else if (swap == V_028C70_SWAP_ALT) /* RA */ 646 blend = blend_alpha = V_028714_SPI_SHADER_32_AR; 647 else 648 assert(0); 649 } else /* 16_16_16_16 */ 650 blend = blend_alpha = V_028714_SPI_SHADER_32_ABGR; 651 } else if (ntype == V_028C70_NUMBER_UINT) 652 alpha = blend = blend_alpha = normal = V_028714_SPI_SHADER_UINT16_ABGR; 653 else if (ntype == V_028C70_NUMBER_SINT) 654 alpha = blend = blend_alpha = normal = V_028714_SPI_SHADER_SINT16_ABGR; 655 else if (ntype == V_028C70_NUMBER_FLOAT) 656 alpha = blend = blend_alpha = normal = V_028714_SPI_SHADER_FP16_ABGR; 657 else 658 assert(0); 659 break; 660 661 case V_028C70_COLOR_32: 662 if (swap == V_028C70_SWAP_STD) { /* R */ 663 blend = normal = V_028714_SPI_SHADER_32_R; 664 alpha = blend_alpha = V_028714_SPI_SHADER_32_AR; 665 } else if (swap == V_028C70_SWAP_ALT_REV) /* A */ 666 alpha = blend = blend_alpha = normal = V_028714_SPI_SHADER_32_AR; 667 else 668 assert(0); 669 break; 670 671 case V_028C70_COLOR_32_32: 672 if (swap == V_028C70_SWAP_STD) { /* RG */ 673 blend = normal = V_028714_SPI_SHADER_32_GR; 674 alpha = blend_alpha = V_028714_SPI_SHADER_32_ABGR; 675 } else if (swap == V_028C70_SWAP_ALT) /* RA */ 676 alpha = blend = blend_alpha = normal = V_028714_SPI_SHADER_32_AR; 677 else 678 assert(0); 679 break; 680 681 case V_028C70_COLOR_32_32_32_32: 682 case V_028C70_COLOR_8_24: 683 case V_028C70_COLOR_24_8: 684 case V_028C70_COLOR_X24_8_32_FLOAT: 685 alpha = blend = blend_alpha = normal = V_028714_SPI_SHADER_32_ABGR; 686 break; 687 688 default: 689 unreachable("unhandled blend format"); 690 } 691 692 if (blend_enable && blend_need_alpha) 693 return blend_alpha; 694 else if(blend_need_alpha) 695 return alpha; 696 else if(blend_enable) 697 return blend; 698 else 699 return normal; 700 } 701 702 static unsigned si_get_cb_shader_mask(unsigned spi_shader_col_format) 703 { 704 unsigned i, cb_shader_mask = 0; 705 706 for (i = 0; i < 8; i++) { 707 switch ((spi_shader_col_format >> (i * 4)) & 0xf) { 708 case V_028714_SPI_SHADER_ZERO: 709 break; 710 case V_028714_SPI_SHADER_32_R: 711 cb_shader_mask |= 0x1 << (i * 4); 712 break; 713 case V_028714_SPI_SHADER_32_GR: 714 cb_shader_mask |= 0x3 << (i * 4); 715 break; 716 case V_028714_SPI_SHADER_32_AR: 717 cb_shader_mask |= 0x9 << (i * 4); 718 break; 719 case V_028714_SPI_SHADER_FP16_ABGR: 720 case V_028714_SPI_SHADER_UNORM16_ABGR: 721 case V_028714_SPI_SHADER_SNORM16_ABGR: 722 case V_028714_SPI_SHADER_UINT16_ABGR: 723 case V_028714_SPI_SHADER_SINT16_ABGR: 724 case V_028714_SPI_SHADER_32_ABGR: 725 cb_shader_mask |= 0xf << (i * 4); 726 break; 727 default: 728 assert(0); 729 } 730 } 731 return cb_shader_mask; 732 } 733 734 static void 735 radv_pipeline_compute_spi_color_formats(struct radv_pipeline *pipeline, 736 const VkGraphicsPipelineCreateInfo *pCreateInfo, 737 uint32_t blend_enable, 738 uint32_t blend_need_alpha, 739 bool single_cb_enable, 740 bool blend_mrt0_is_dual_src) 741 { 742 RADV_FROM_HANDLE(radv_render_pass, pass, pCreateInfo->renderPass); 743 struct radv_subpass *subpass = pass->subpasses + pCreateInfo->subpass; 744 struct radv_blend_state *blend = &pipeline->graphics.blend; 745 unsigned col_format = 0; 746 747 for (unsigned i = 0; i < (single_cb_enable ? 1 : subpass->color_count); ++i) { 748 struct radv_render_pass_attachment *attachment; 749 unsigned cf; 750 751 attachment = pass->attachments + subpass->color_attachments[i].attachment; 752 753 cf = si_choose_spi_color_format(attachment->format, 754 blend_enable & (1 << i), 755 blend_need_alpha & (1 << i)); 756 757 col_format |= cf << (4 * i); 758 } 759 760 blend->cb_shader_mask = si_get_cb_shader_mask(col_format); 761 762 if (blend_mrt0_is_dual_src) 763 col_format |= (col_format & 0xf) << 4; 764 if (!col_format) 765 col_format |= V_028714_SPI_SHADER_32_R; 766 blend->spi_shader_col_format = col_format; 767 } 768 769 static bool 770 format_is_int8(VkFormat format) 771 { 772 const struct vk_format_description *desc = vk_format_description(format); 773 int channel = vk_format_get_first_non_void_channel(format); 774 775 return channel >= 0 && desc->channel[channel].pure_integer && 776 desc->channel[channel].size == 8; 777 } 778 779 unsigned radv_format_meta_fs_key(VkFormat format) 780 { 781 unsigned col_format = si_choose_spi_color_format(format, false, false) - 1; 782 bool is_int8 = format_is_int8(format); 783 784 return col_format + (is_int8 ? 3 : 0); 785 } 786 787 static unsigned 788 radv_pipeline_compute_is_int8(const VkGraphicsPipelineCreateInfo *pCreateInfo) 789 { 790 RADV_FROM_HANDLE(radv_render_pass, pass, pCreateInfo->renderPass); 791 struct radv_subpass *subpass = pass->subpasses + pCreateInfo->subpass; 792 unsigned is_int8 = 0; 793 794 for (unsigned i = 0; i < subpass->color_count; ++i) { 795 struct radv_render_pass_attachment *attachment; 796 797 attachment = pass->attachments + subpass->color_attachments[i].attachment; 798 799 if (format_is_int8(attachment->format)) 800 is_int8 |= 1 << i; 801 } 802 803 return is_int8; 804 } 805 806 static void 807 radv_pipeline_init_blend_state(struct radv_pipeline *pipeline, 808 const VkGraphicsPipelineCreateInfo *pCreateInfo, 809 const struct radv_graphics_pipeline_create_info *extra) 810 { 811 const VkPipelineColorBlendStateCreateInfo *vkblend = pCreateInfo->pColorBlendState; 812 struct radv_blend_state *blend = &pipeline->graphics.blend; 813 unsigned mode = V_028808_CB_NORMAL; 814 uint32_t blend_enable = 0, blend_need_alpha = 0; 815 bool blend_mrt0_is_dual_src = false; 816 int i; 817 bool single_cb_enable = false; 818 819 if (!vkblend) 820 return; 821 822 if (extra && extra->custom_blend_mode) { 823 single_cb_enable = true; 824 mode = extra->custom_blend_mode; 825 } 826 blend->cb_color_control = 0; 827 if (vkblend->logicOpEnable) 828 blend->cb_color_control |= S_028808_ROP3(vkblend->logicOp | (vkblend->logicOp << 4)); 829 else 830 blend->cb_color_control |= S_028808_ROP3(0xcc); 831 832 blend->db_alpha_to_mask = S_028B70_ALPHA_TO_MASK_OFFSET0(2) | 833 S_028B70_ALPHA_TO_MASK_OFFSET1(2) | 834 S_028B70_ALPHA_TO_MASK_OFFSET2(2) | 835 S_028B70_ALPHA_TO_MASK_OFFSET3(2); 836 837 blend->cb_target_mask = 0; 838 for (i = 0; i < vkblend->attachmentCount; i++) { 839 const VkPipelineColorBlendAttachmentState *att = &vkblend->pAttachments[i]; 840 unsigned blend_cntl = 0; 841 VkBlendOp eqRGB = att->colorBlendOp; 842 VkBlendFactor srcRGB = att->srcColorBlendFactor; 843 VkBlendFactor dstRGB = att->dstColorBlendFactor; 844 VkBlendOp eqA = att->alphaBlendOp; 845 VkBlendFactor srcA = att->srcAlphaBlendFactor; 846 VkBlendFactor dstA = att->dstAlphaBlendFactor; 847 848 blend->sx_mrt0_blend_opt[i] = S_028760_COLOR_COMB_FCN(V_028760_OPT_COMB_BLEND_DISABLED) | S_028760_ALPHA_COMB_FCN(V_028760_OPT_COMB_BLEND_DISABLED); 849 850 if (!att->colorWriteMask) 851 continue; 852 853 blend->cb_target_mask |= (unsigned)att->colorWriteMask << (4 * i); 854 if (!att->blendEnable) { 855 blend->cb_blend_control[i] = blend_cntl; 856 continue; 857 } 858 859 if (is_dual_src(srcRGB) || is_dual_src(dstRGB) || is_dual_src(srcA) || is_dual_src(dstA)) 860 if (i == 0) 861 blend_mrt0_is_dual_src = true; 862 863 if (eqRGB == VK_BLEND_OP_MIN || eqRGB == VK_BLEND_OP_MAX) { 864 srcRGB = VK_BLEND_FACTOR_ONE; 865 dstRGB = VK_BLEND_FACTOR_ONE; 866 } 867 if (eqA == VK_BLEND_OP_MIN || eqA == VK_BLEND_OP_MAX) { 868 srcA = VK_BLEND_FACTOR_ONE; 869 dstA = VK_BLEND_FACTOR_ONE; 870 } 871 872 blend_cntl |= S_028780_ENABLE(1); 873 874 blend_cntl |= S_028780_COLOR_COMB_FCN(si_translate_blend_function(eqRGB)); 875 blend_cntl |= S_028780_COLOR_SRCBLEND(si_translate_blend_factor(srcRGB)); 876 blend_cntl |= S_028780_COLOR_DESTBLEND(si_translate_blend_factor(dstRGB)); 877 if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) { 878 blend_cntl |= S_028780_SEPARATE_ALPHA_BLEND(1); 879 blend_cntl |= S_028780_ALPHA_COMB_FCN(si_translate_blend_function(eqA)); 880 blend_cntl |= S_028780_ALPHA_SRCBLEND(si_translate_blend_factor(srcA)); 881 blend_cntl |= S_028780_ALPHA_DESTBLEND(si_translate_blend_factor(dstA)); 882 } 883 blend->cb_blend_control[i] = blend_cntl; 884 885 blend_enable |= 1 << i; 886 887 if (srcRGB == VK_BLEND_FACTOR_SRC_ALPHA || 888 dstRGB == VK_BLEND_FACTOR_SRC_ALPHA || 889 srcRGB == VK_BLEND_FACTOR_SRC_ALPHA_SATURATE || 890 dstRGB == VK_BLEND_FACTOR_SRC_ALPHA_SATURATE || 891 srcRGB == VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA || 892 dstRGB == VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA) 893 blend_need_alpha |= 1 << i; 894 } 895 for (i = vkblend->attachmentCount; i < 8; i++) 896 blend->cb_blend_control[i] = 0; 897 898 if (blend->cb_target_mask) 899 blend->cb_color_control |= S_028808_MODE(mode); 900 else 901 blend->cb_color_control |= S_028808_MODE(V_028808_CB_DISABLE); 902 903 radv_pipeline_compute_spi_color_formats(pipeline, pCreateInfo, 904 blend_enable, blend_need_alpha, single_cb_enable, blend_mrt0_is_dual_src); 905 } 906 907 static uint32_t si_translate_stencil_op(enum VkStencilOp op) 908 { 909 switch (op) { 910 case VK_STENCIL_OP_KEEP: 911 return V_02842C_STENCIL_KEEP; 912 case VK_STENCIL_OP_ZERO: 913 return V_02842C_STENCIL_ZERO; 914 case VK_STENCIL_OP_REPLACE: 915 return V_02842C_STENCIL_REPLACE_TEST; 916 case VK_STENCIL_OP_INCREMENT_AND_CLAMP: 917 return V_02842C_STENCIL_ADD_CLAMP; 918 case VK_STENCIL_OP_DECREMENT_AND_CLAMP: 919 return V_02842C_STENCIL_SUB_CLAMP; 920 case VK_STENCIL_OP_INVERT: 921 return V_02842C_STENCIL_INVERT; 922 case VK_STENCIL_OP_INCREMENT_AND_WRAP: 923 return V_02842C_STENCIL_ADD_WRAP; 924 case VK_STENCIL_OP_DECREMENT_AND_WRAP: 925 return V_02842C_STENCIL_SUB_WRAP; 926 default: 927 return 0; 928 } 929 } 930 static void 931 radv_pipeline_init_depth_stencil_state(struct radv_pipeline *pipeline, 932 const VkGraphicsPipelineCreateInfo *pCreateInfo, 933 const struct radv_graphics_pipeline_create_info *extra) 934 { 935 const VkPipelineDepthStencilStateCreateInfo *vkds = pCreateInfo->pDepthStencilState; 936 struct radv_depth_stencil_state *ds = &pipeline->graphics.ds; 937 938 memset(ds, 0, sizeof(*ds)); 939 if (!vkds) 940 return; 941 ds->db_depth_control = S_028800_Z_ENABLE(vkds->depthTestEnable ? 1 : 0) | 942 S_028800_Z_WRITE_ENABLE(vkds->depthWriteEnable ? 1 : 0) | 943 S_028800_ZFUNC(vkds->depthCompareOp) | 944 S_028800_DEPTH_BOUNDS_ENABLE(vkds->depthBoundsTestEnable ? 1 : 0); 945 946 if (vkds->stencilTestEnable) { 947 ds->db_depth_control |= S_028800_STENCIL_ENABLE(1) | S_028800_BACKFACE_ENABLE(1); 948 ds->db_depth_control |= S_028800_STENCILFUNC(vkds->front.compareOp); 949 ds->db_stencil_control |= S_02842C_STENCILFAIL(si_translate_stencil_op(vkds->front.failOp)); 950 ds->db_stencil_control |= S_02842C_STENCILZPASS(si_translate_stencil_op(vkds->front.passOp)); 951 ds->db_stencil_control |= S_02842C_STENCILZFAIL(si_translate_stencil_op(vkds->front.depthFailOp)); 952 953 ds->db_depth_control |= S_028800_STENCILFUNC_BF(vkds->back.compareOp); 954 ds->db_stencil_control |= S_02842C_STENCILFAIL_BF(si_translate_stencil_op(vkds->back.failOp)); 955 ds->db_stencil_control |= S_02842C_STENCILZPASS_BF(si_translate_stencil_op(vkds->back.passOp)); 956 ds->db_stencil_control |= S_02842C_STENCILZFAIL_BF(si_translate_stencil_op(vkds->back.depthFailOp)); 957 } 958 959 if (extra) { 960 961 ds->db_render_control |= S_028000_DEPTH_CLEAR_ENABLE(extra->db_depth_clear); 962 ds->db_render_control |= S_028000_STENCIL_CLEAR_ENABLE(extra->db_stencil_clear); 963 964 ds->db_render_control |= S_028000_RESUMMARIZE_ENABLE(extra->db_resummarize); 965 ds->db_render_control |= S_028000_DEPTH_COMPRESS_DISABLE(extra->db_flush_depth_inplace); 966 ds->db_render_control |= S_028000_STENCIL_COMPRESS_DISABLE(extra->db_flush_stencil_inplace); 967 ds->db_render_override2 |= S_028010_DISABLE_ZMASK_EXPCLEAR_OPTIMIZATION(extra->db_depth_disable_expclear); 968 ds->db_render_override2 |= S_028010_DISABLE_SMEM_EXPCLEAR_OPTIMIZATION(extra->db_stencil_disable_expclear); 969 } 970 } 971 972 static uint32_t si_translate_fill(VkPolygonMode func) 973 { 974 switch(func) { 975 case VK_POLYGON_MODE_FILL: 976 return V_028814_X_DRAW_TRIANGLES; 977 case VK_POLYGON_MODE_LINE: 978 return V_028814_X_DRAW_LINES; 979 case VK_POLYGON_MODE_POINT: 980 return V_028814_X_DRAW_POINTS; 981 default: 982 assert(0); 983 return V_028814_X_DRAW_POINTS; 984 } 985 } 986 static void 987 radv_pipeline_init_raster_state(struct radv_pipeline *pipeline, 988 const VkGraphicsPipelineCreateInfo *pCreateInfo) 989 { 990 const VkPipelineRasterizationStateCreateInfo *vkraster = pCreateInfo->pRasterizationState; 991 struct radv_raster_state *raster = &pipeline->graphics.raster; 992 993 memset(raster, 0, sizeof(*raster)); 994 995 raster->spi_interp_control = 996 S_0286D4_FLAT_SHADE_ENA(1) | 997 S_0286D4_PNT_SPRITE_ENA(1) | 998 S_0286D4_PNT_SPRITE_OVRD_X(V_0286D4_SPI_PNT_SPRITE_SEL_S) | 999 S_0286D4_PNT_SPRITE_OVRD_Y(V_0286D4_SPI_PNT_SPRITE_SEL_T) | 1000 S_0286D4_PNT_SPRITE_OVRD_Z(V_0286D4_SPI_PNT_SPRITE_SEL_0) | 1001 S_0286D4_PNT_SPRITE_OVRD_W(V_0286D4_SPI_PNT_SPRITE_SEL_1) | 1002 S_0286D4_PNT_SPRITE_TOP_1(0); // vulkan is top to bottom - 1.0 at bottom 1003 1004 raster->pa_cl_vs_out_cntl = S_02881C_VS_OUT_MISC_SIDE_BUS_ENA(1); 1005 raster->pa_cl_clip_cntl = S_028810_PS_UCP_MODE(3) | 1006 S_028810_DX_CLIP_SPACE_DEF(1) | // vulkan uses DX conventions. 1007 S_028810_ZCLIP_NEAR_DISABLE(vkraster->depthClampEnable ? 1 : 0) | 1008 S_028810_ZCLIP_FAR_DISABLE(vkraster->depthClampEnable ? 1 : 0) | 1009 S_028810_DX_RASTERIZATION_KILL(vkraster->rasterizerDiscardEnable ? 1 : 0) | 1010 S_028810_DX_LINEAR_ATTR_CLIP_ENA(1); 1011 1012 raster->pa_su_vtx_cntl = 1013 S_028BE4_PIX_CENTER(1) | // TODO verify 1014 S_028BE4_ROUND_MODE(V_028BE4_X_ROUND_TO_EVEN) | 1015 S_028BE4_QUANT_MODE(V_028BE4_X_16_8_FIXED_POINT_1_256TH); 1016 1017 raster->pa_su_sc_mode_cntl = 1018 S_028814_FACE(vkraster->frontFace) | 1019 S_028814_CULL_FRONT(!!(vkraster->cullMode & VK_CULL_MODE_FRONT_BIT)) | 1020 S_028814_CULL_BACK(!!(vkraster->cullMode & VK_CULL_MODE_BACK_BIT)) | 1021 S_028814_POLY_MODE(vkraster->polygonMode != VK_POLYGON_MODE_FILL) | 1022 S_028814_POLYMODE_FRONT_PTYPE(si_translate_fill(vkraster->polygonMode)) | 1023 S_028814_POLYMODE_BACK_PTYPE(si_translate_fill(vkraster->polygonMode)) | 1024 S_028814_POLY_OFFSET_FRONT_ENABLE(vkraster->depthBiasEnable ? 1 : 0) | 1025 S_028814_POLY_OFFSET_BACK_ENABLE(vkraster->depthBiasEnable ? 1 : 0) | 1026 S_028814_POLY_OFFSET_PARA_ENABLE(vkraster->depthBiasEnable ? 1 : 0); 1027 1028 } 1029 1030 static void 1031 radv_pipeline_init_multisample_state(struct radv_pipeline *pipeline, 1032 const VkGraphicsPipelineCreateInfo *pCreateInfo) 1033 { 1034 const VkPipelineMultisampleStateCreateInfo *vkms = pCreateInfo->pMultisampleState; 1035 struct radv_blend_state *blend = &pipeline->graphics.blend; 1036 struct radv_multisample_state *ms = &pipeline->graphics.ms; 1037 unsigned num_tile_pipes = pipeline->device->physical_device->rad_info.num_tile_pipes; 1038 int ps_iter_samples = 1; 1039 uint32_t mask = 0xffff; 1040 1041 ms->num_samples = vkms->rasterizationSamples; 1042 1043 if (pipeline->shaders[MESA_SHADER_FRAGMENT]->info.fs.force_persample) { 1044 ps_iter_samples = vkms->rasterizationSamples; 1045 } 1046 1047 ms->pa_sc_line_cntl = S_028BDC_DX10_DIAMOND_TEST_ENA(1); 1048 ms->pa_sc_aa_config = 0; 1049 ms->db_eqaa = S_028804_HIGH_QUALITY_INTERSECTIONS(1) | 1050 S_028804_STATIC_ANCHOR_ASSOCIATIONS(1); 1051 ms->pa_sc_mode_cntl_1 = 1052 S_028A4C_WALK_FENCE_ENABLE(1) | //TODO linear dst fixes 1053 S_028A4C_WALK_FENCE_SIZE(num_tile_pipes == 2 ? 2 : 3) | 1054 /* always 1: */ 1055 S_028A4C_WALK_ALIGN8_PRIM_FITS_ST(1) | 1056 S_028A4C_SUPERTILE_WALK_ORDER_ENABLE(1) | 1057 S_028A4C_TILE_WALK_ORDER_ENABLE(1) | 1058 S_028A4C_MULTI_SHADER_ENGINE_PRIM_DISCARD_ENABLE(1) | 1059 EG_S_028A4C_FORCE_EOV_CNTDWN_ENABLE(1) | 1060 EG_S_028A4C_FORCE_EOV_REZ_ENABLE(1); 1061 1062 if (vkms->rasterizationSamples > 1) { 1063 unsigned log_samples = util_logbase2(vkms->rasterizationSamples); 1064 unsigned log_ps_iter_samples = util_logbase2(util_next_power_of_two(ps_iter_samples)); 1065 ms->pa_sc_mode_cntl_0 = S_028A48_MSAA_ENABLE(1); 1066 ms->pa_sc_line_cntl |= S_028BDC_EXPAND_LINE_WIDTH(1); /* CM_R_028BDC_PA_SC_LINE_CNTL */ 1067 ms->db_eqaa |= S_028804_MAX_ANCHOR_SAMPLES(log_samples) | 1068 S_028804_PS_ITER_SAMPLES(log_ps_iter_samples) | 1069 S_028804_MASK_EXPORT_NUM_SAMPLES(log_samples) | 1070 S_028804_ALPHA_TO_MASK_NUM_SAMPLES(log_samples); 1071 ms->pa_sc_aa_config |= S_028BE0_MSAA_NUM_SAMPLES(log_samples) | 1072 S_028BE0_MAX_SAMPLE_DIST(radv_cayman_get_maxdist(log_samples)) | 1073 S_028BE0_MSAA_EXPOSED_SAMPLES(log_samples); /* CM_R_028BE0_PA_SC_AA_CONFIG */ 1074 ms->pa_sc_mode_cntl_1 |= EG_S_028A4C_PS_ITER_SAMPLE(ps_iter_samples > 1); 1075 } 1076 1077 if (vkms->alphaToCoverageEnable) 1078 blend->db_alpha_to_mask |= S_028B70_ALPHA_TO_MASK_ENABLE(1); 1079 1080 if (vkms->pSampleMask) { 1081 mask = vkms->pSampleMask[0] & 0xffff; 1082 } 1083 1084 ms->pa_sc_aa_mask[0] = mask | (mask << 16); 1085 ms->pa_sc_aa_mask[1] = mask | (mask << 16); 1086 } 1087 1088 static uint32_t 1089 si_translate_prim(enum VkPrimitiveTopology topology) 1090 { 1091 switch (topology) { 1092 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: 1093 return V_008958_DI_PT_POINTLIST; 1094 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: 1095 return V_008958_DI_PT_LINELIST; 1096 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: 1097 return V_008958_DI_PT_LINESTRIP; 1098 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: 1099 return V_008958_DI_PT_TRILIST; 1100 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: 1101 return V_008958_DI_PT_TRISTRIP; 1102 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: 1103 return V_008958_DI_PT_TRIFAN; 1104 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: 1105 return V_008958_DI_PT_LINELIST_ADJ; 1106 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: 1107 return V_008958_DI_PT_LINESTRIP_ADJ; 1108 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: 1109 return V_008958_DI_PT_TRILIST_ADJ; 1110 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: 1111 return V_008958_DI_PT_TRISTRIP_ADJ; 1112 case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: 1113 return V_008958_DI_PT_PATCH; 1114 default: 1115 assert(0); 1116 return 0; 1117 } 1118 } 1119 1120 static uint32_t 1121 si_conv_prim_to_gs_out(enum VkPrimitiveTopology topology) 1122 { 1123 switch (topology) { 1124 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: 1125 case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: 1126 return V_028A6C_OUTPRIM_TYPE_POINTLIST; 1127 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: 1128 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: 1129 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: 1130 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: 1131 return V_028A6C_OUTPRIM_TYPE_LINESTRIP; 1132 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: 1133 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: 1134 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: 1135 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: 1136 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: 1137 return V_028A6C_OUTPRIM_TYPE_TRISTRIP; 1138 default: 1139 assert(0); 1140 return 0; 1141 } 1142 } 1143 1144 static unsigned si_map_swizzle(unsigned swizzle) 1145 { 1146 switch (swizzle) { 1147 case VK_SWIZZLE_Y: 1148 return V_008F0C_SQ_SEL_Y; 1149 case VK_SWIZZLE_Z: 1150 return V_008F0C_SQ_SEL_Z; 1151 case VK_SWIZZLE_W: 1152 return V_008F0C_SQ_SEL_W; 1153 case VK_SWIZZLE_0: 1154 return V_008F0C_SQ_SEL_0; 1155 case VK_SWIZZLE_1: 1156 return V_008F0C_SQ_SEL_1; 1157 default: /* VK_SWIZZLE_X */ 1158 return V_008F0C_SQ_SEL_X; 1159 } 1160 } 1161 1162 static void 1163 radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline, 1164 const VkGraphicsPipelineCreateInfo *pCreateInfo) 1165 { 1166 radv_cmd_dirty_mask_t states = RADV_CMD_DIRTY_DYNAMIC_ALL; 1167 RADV_FROM_HANDLE(radv_render_pass, pass, pCreateInfo->renderPass); 1168 struct radv_subpass *subpass = &pass->subpasses[pCreateInfo->subpass]; 1169 1170 pipeline->dynamic_state = default_dynamic_state; 1171 1172 if (pCreateInfo->pDynamicState) { 1173 /* Remove all of the states that are marked as dynamic */ 1174 uint32_t count = pCreateInfo->pDynamicState->dynamicStateCount; 1175 for (uint32_t s = 0; s < count; s++) 1176 states &= ~(1 << pCreateInfo->pDynamicState->pDynamicStates[s]); 1177 } 1178 1179 struct radv_dynamic_state *dynamic = &pipeline->dynamic_state; 1180 1181 /* Section 9.2 of the Vulkan 1.0.15 spec says: 1182 * 1183 * pViewportState is [...] NULL if the pipeline 1184 * has rasterization disabled. 1185 */ 1186 if (!pCreateInfo->pRasterizationState->rasterizerDiscardEnable) { 1187 assert(pCreateInfo->pViewportState); 1188 1189 dynamic->viewport.count = pCreateInfo->pViewportState->viewportCount; 1190 if (states & (1 << VK_DYNAMIC_STATE_VIEWPORT)) { 1191 typed_memcpy(dynamic->viewport.viewports, 1192 pCreateInfo->pViewportState->pViewports, 1193 pCreateInfo->pViewportState->viewportCount); 1194 } 1195 1196 dynamic->scissor.count = pCreateInfo->pViewportState->scissorCount; 1197 if (states & (1 << VK_DYNAMIC_STATE_SCISSOR)) { 1198 typed_memcpy(dynamic->scissor.scissors, 1199 pCreateInfo->pViewportState->pScissors, 1200 pCreateInfo->pViewportState->scissorCount); 1201 } 1202 } 1203 1204 if (states & (1 << VK_DYNAMIC_STATE_LINE_WIDTH)) { 1205 assert(pCreateInfo->pRasterizationState); 1206 dynamic->line_width = pCreateInfo->pRasterizationState->lineWidth; 1207 } 1208 1209 if (states & (1 << VK_DYNAMIC_STATE_DEPTH_BIAS)) { 1210 assert(pCreateInfo->pRasterizationState); 1211 dynamic->depth_bias.bias = 1212 pCreateInfo->pRasterizationState->depthBiasConstantFactor; 1213 dynamic->depth_bias.clamp = 1214 pCreateInfo->pRasterizationState->depthBiasClamp; 1215 dynamic->depth_bias.slope = 1216 pCreateInfo->pRasterizationState->depthBiasSlopeFactor; 1217 } 1218 1219 /* Section 9.2 of the Vulkan 1.0.15 spec says: 1220 * 1221 * pColorBlendState is [...] NULL if the pipeline has rasterization 1222 * disabled or if the subpass of the render pass the pipeline is 1223 * created against does not use any color attachments. 1224 */ 1225 bool uses_color_att = false; 1226 for (unsigned i = 0; i < subpass->color_count; ++i) { 1227 if (subpass->color_attachments[i].attachment != VK_ATTACHMENT_UNUSED) { 1228 uses_color_att = true; 1229 break; 1230 } 1231 } 1232 1233 if (uses_color_att && states & (1 << VK_DYNAMIC_STATE_BLEND_CONSTANTS)) { 1234 assert(pCreateInfo->pColorBlendState); 1235 typed_memcpy(dynamic->blend_constants, 1236 pCreateInfo->pColorBlendState->blendConstants, 4); 1237 } 1238 1239 /* If there is no depthstencil attachment, then don't read 1240 * pDepthStencilState. The Vulkan spec states that pDepthStencilState may 1241 * be NULL in this case. Even if pDepthStencilState is non-NULL, there is 1242 * no need to override the depthstencil defaults in 1243 * radv_pipeline::dynamic_state when there is no depthstencil attachment. 1244 * 1245 * Section 9.2 of the Vulkan 1.0.15 spec says: 1246 * 1247 * pDepthStencilState is [...] NULL if the pipeline has rasterization 1248 * disabled or if the subpass of the render pass the pipeline is created 1249 * against does not use a depth/stencil attachment. 1250 */ 1251 if (!pCreateInfo->pRasterizationState->rasterizerDiscardEnable && 1252 subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) { 1253 assert(pCreateInfo->pDepthStencilState); 1254 1255 if (states & (1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS)) { 1256 dynamic->depth_bounds.min = 1257 pCreateInfo->pDepthStencilState->minDepthBounds; 1258 dynamic->depth_bounds.max = 1259 pCreateInfo->pDepthStencilState->maxDepthBounds; 1260 } 1261 1262 if (states & (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK)) { 1263 dynamic->stencil_compare_mask.front = 1264 pCreateInfo->pDepthStencilState->front.compareMask; 1265 dynamic->stencil_compare_mask.back = 1266 pCreateInfo->pDepthStencilState->back.compareMask; 1267 } 1268 1269 if (states & (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) { 1270 dynamic->stencil_write_mask.front = 1271 pCreateInfo->pDepthStencilState->front.writeMask; 1272 dynamic->stencil_write_mask.back = 1273 pCreateInfo->pDepthStencilState->back.writeMask; 1274 } 1275 1276 if (states & (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE)) { 1277 dynamic->stencil_reference.front = 1278 pCreateInfo->pDepthStencilState->front.reference; 1279 dynamic->stencil_reference.back = 1280 pCreateInfo->pDepthStencilState->back.reference; 1281 } 1282 } 1283 1284 pipeline->dynamic_state_mask = states; 1285 } 1286 1287 static union ac_shader_variant_key 1288 radv_compute_vs_key(const VkGraphicsPipelineCreateInfo *pCreateInfo) 1289 { 1290 union ac_shader_variant_key key; 1291 const VkPipelineVertexInputStateCreateInfo *input_state = 1292 pCreateInfo->pVertexInputState; 1293 1294 memset(&key, 0, sizeof(key)); 1295 key.vs.instance_rate_inputs = 0; 1296 1297 for (unsigned i = 0; i < input_state->vertexAttributeDescriptionCount; ++i) { 1298 unsigned binding; 1299 binding = input_state->pVertexAttributeDescriptions[i].binding; 1300 if (input_state->pVertexBindingDescriptions[binding].inputRate) 1301 key.vs.instance_rate_inputs |= 1u << input_state->pVertexAttributeDescriptions[i].location; 1302 } 1303 return key; 1304 } 1305 1306 VkResult 1307 radv_pipeline_init(struct radv_pipeline *pipeline, 1308 struct radv_device *device, 1309 struct radv_pipeline_cache *cache, 1310 const VkGraphicsPipelineCreateInfo *pCreateInfo, 1311 const struct radv_graphics_pipeline_create_info *extra, 1312 const VkAllocationCallbacks *alloc) 1313 { 1314 struct radv_shader_module fs_m = {0}; 1315 1316 if (alloc == NULL) 1317 alloc = &device->alloc; 1318 1319 pipeline->device = device; 1320 pipeline->layout = radv_pipeline_layout_from_handle(pCreateInfo->layout); 1321 1322 radv_pipeline_init_dynamic_state(pipeline, pCreateInfo); 1323 const VkPipelineShaderStageCreateInfo *pStages[MESA_SHADER_STAGES] = { 0, }; 1324 struct radv_shader_module *modules[MESA_SHADER_STAGES] = { 0, }; 1325 for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) { 1326 gl_shader_stage stage = ffs(pCreateInfo->pStages[i].stage) - 1; 1327 pStages[stage] = &pCreateInfo->pStages[i]; 1328 modules[stage] = radv_shader_module_from_handle(pStages[stage]->module); 1329 } 1330 1331 radv_pipeline_init_blend_state(pipeline, pCreateInfo, extra); 1332 1333 /* */ 1334 if (modules[MESA_SHADER_VERTEX]) { 1335 union ac_shader_variant_key key = radv_compute_vs_key(pCreateInfo); 1336 1337 pipeline->shaders[MESA_SHADER_VERTEX] = 1338 radv_pipeline_compile(pipeline, cache, modules[MESA_SHADER_VERTEX], 1339 pStages[MESA_SHADER_VERTEX]->pName, 1340 MESA_SHADER_VERTEX, 1341 pStages[MESA_SHADER_VERTEX]->pSpecializationInfo, 1342 pipeline->layout, &key); 1343 1344 pipeline->active_stages |= mesa_to_vk_shader_stage(MESA_SHADER_VERTEX); 1345 } 1346 1347 if (!modules[MESA_SHADER_FRAGMENT]) { 1348 nir_builder fs_b; 1349 nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, NULL); 1350 fs_b.shader->info->name = ralloc_strdup(fs_b.shader, "noop_fs"); 1351 fs_m.nir = fs_b.shader; 1352 modules[MESA_SHADER_FRAGMENT] = &fs_m; 1353 } 1354 1355 if (modules[MESA_SHADER_FRAGMENT]) { 1356 union ac_shader_variant_key key; 1357 key.fs.col_format = pipeline->graphics.blend.spi_shader_col_format; 1358 key.fs.is_int8 = radv_pipeline_compute_is_int8(pCreateInfo); 1359 1360 const VkPipelineShaderStageCreateInfo *stage = pStages[MESA_SHADER_FRAGMENT]; 1361 1362 pipeline->shaders[MESA_SHADER_FRAGMENT] = 1363 radv_pipeline_compile(pipeline, cache, modules[MESA_SHADER_FRAGMENT], 1364 stage ? stage->pName : "main", 1365 MESA_SHADER_FRAGMENT, 1366 stage ? stage->pSpecializationInfo : NULL, 1367 pipeline->layout, &key); 1368 pipeline->active_stages |= mesa_to_vk_shader_stage(MESA_SHADER_FRAGMENT); 1369 } 1370 1371 if (fs_m.nir) 1372 ralloc_free(fs_m.nir); 1373 1374 radv_pipeline_init_depth_stencil_state(pipeline, pCreateInfo, extra); 1375 radv_pipeline_init_raster_state(pipeline, pCreateInfo); 1376 radv_pipeline_init_multisample_state(pipeline, pCreateInfo); 1377 pipeline->graphics.prim = si_translate_prim(pCreateInfo->pInputAssemblyState->topology); 1378 pipeline->graphics.gs_out = si_conv_prim_to_gs_out(pCreateInfo->pInputAssemblyState->topology); 1379 if (extra && extra->use_rectlist) { 1380 pipeline->graphics.prim = V_008958_DI_PT_RECTLIST; 1381 pipeline->graphics.gs_out = V_028A6C_OUTPRIM_TYPE_TRISTRIP; 1382 } 1383 pipeline->graphics.prim_restart_enable = !!pCreateInfo->pInputAssemblyState->primitiveRestartEnable; 1384 1385 const VkPipelineVertexInputStateCreateInfo *vi_info = 1386 pCreateInfo->pVertexInputState; 1387 for (uint32_t i = 0; i < vi_info->vertexAttributeDescriptionCount; i++) { 1388 const VkVertexInputAttributeDescription *desc = 1389 &vi_info->pVertexAttributeDescriptions[i]; 1390 unsigned loc = desc->location; 1391 const struct vk_format_description *format_desc; 1392 int first_non_void; 1393 uint32_t num_format, data_format; 1394 format_desc = vk_format_description(desc->format); 1395 first_non_void = vk_format_get_first_non_void_channel(desc->format); 1396 1397 num_format = radv_translate_buffer_numformat(format_desc, first_non_void); 1398 data_format = radv_translate_buffer_dataformat(format_desc, first_non_void); 1399 1400 pipeline->va_rsrc_word3[loc] = S_008F0C_DST_SEL_X(si_map_swizzle(format_desc->swizzle[0])) | 1401 S_008F0C_DST_SEL_Y(si_map_swizzle(format_desc->swizzle[1])) | 1402 S_008F0C_DST_SEL_Z(si_map_swizzle(format_desc->swizzle[2])) | 1403 S_008F0C_DST_SEL_W(si_map_swizzle(format_desc->swizzle[3])) | 1404 S_008F0C_NUM_FORMAT(num_format) | 1405 S_008F0C_DATA_FORMAT(data_format); 1406 pipeline->va_format_size[loc] = format_desc->block.bits / 8; 1407 pipeline->va_offset[loc] = desc->offset; 1408 pipeline->va_binding[loc] = desc->binding; 1409 pipeline->num_vertex_attribs = MAX2(pipeline->num_vertex_attribs, loc + 1); 1410 } 1411 1412 for (uint32_t i = 0; i < vi_info->vertexBindingDescriptionCount; i++) { 1413 const VkVertexInputBindingDescription *desc = 1414 &vi_info->pVertexBindingDescriptions[i]; 1415 1416 pipeline->binding_stride[desc->binding] = desc->stride; 1417 } 1418 1419 if (device->debug_flags & RADV_DEBUG_DUMP_SHADER_STATS) { 1420 radv_dump_pipeline_stats(device, pipeline); 1421 } 1422 1423 return VK_SUCCESS; 1424 } 1425 1426 VkResult 1427 radv_graphics_pipeline_create( 1428 VkDevice _device, 1429 VkPipelineCache _cache, 1430 const VkGraphicsPipelineCreateInfo *pCreateInfo, 1431 const struct radv_graphics_pipeline_create_info *extra, 1432 const VkAllocationCallbacks *pAllocator, 1433 VkPipeline *pPipeline) 1434 { 1435 RADV_FROM_HANDLE(radv_device, device, _device); 1436 RADV_FROM_HANDLE(radv_pipeline_cache, cache, _cache); 1437 struct radv_pipeline *pipeline; 1438 VkResult result; 1439 1440 pipeline = vk_alloc2(&device->alloc, pAllocator, sizeof(*pipeline), 8, 1441 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 1442 if (pipeline == NULL) 1443 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 1444 1445 memset(pipeline, 0, sizeof(*pipeline)); 1446 result = radv_pipeline_init(pipeline, device, cache, 1447 pCreateInfo, extra, pAllocator); 1448 if (result != VK_SUCCESS) { 1449 vk_free2(&device->alloc, pAllocator, pipeline); 1450 return result; 1451 } 1452 1453 *pPipeline = radv_pipeline_to_handle(pipeline); 1454 1455 return VK_SUCCESS; 1456 } 1457 1458 VkResult radv_CreateGraphicsPipelines( 1459 VkDevice _device, 1460 VkPipelineCache pipelineCache, 1461 uint32_t count, 1462 const VkGraphicsPipelineCreateInfo* pCreateInfos, 1463 const VkAllocationCallbacks* pAllocator, 1464 VkPipeline* pPipelines) 1465 { 1466 VkResult result = VK_SUCCESS; 1467 unsigned i = 0; 1468 1469 for (; i < count; i++) { 1470 VkResult r; 1471 r = radv_graphics_pipeline_create(_device, 1472 pipelineCache, 1473 &pCreateInfos[i], 1474 NULL, pAllocator, &pPipelines[i]); 1475 if (r != VK_SUCCESS) { 1476 result = r; 1477 pPipelines[i] = VK_NULL_HANDLE; 1478 } 1479 } 1480 1481 return result; 1482 } 1483 1484 static VkResult radv_compute_pipeline_create( 1485 VkDevice _device, 1486 VkPipelineCache _cache, 1487 const VkComputePipelineCreateInfo* pCreateInfo, 1488 const VkAllocationCallbacks* pAllocator, 1489 VkPipeline* pPipeline) 1490 { 1491 RADV_FROM_HANDLE(radv_device, device, _device); 1492 RADV_FROM_HANDLE(radv_pipeline_cache, cache, _cache); 1493 RADV_FROM_HANDLE(radv_shader_module, module, pCreateInfo->stage.module); 1494 struct radv_pipeline *pipeline; 1495 1496 pipeline = vk_alloc2(&device->alloc, pAllocator, sizeof(*pipeline), 8, 1497 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 1498 if (pipeline == NULL) 1499 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 1500 1501 memset(pipeline, 0, sizeof(*pipeline)); 1502 pipeline->device = device; 1503 pipeline->layout = radv_pipeline_layout_from_handle(pCreateInfo->layout); 1504 1505 pipeline->shaders[MESA_SHADER_COMPUTE] = 1506 radv_pipeline_compile(pipeline, cache, module, 1507 pCreateInfo->stage.pName, 1508 MESA_SHADER_COMPUTE, 1509 pCreateInfo->stage.pSpecializationInfo, 1510 pipeline->layout, NULL); 1511 1512 *pPipeline = radv_pipeline_to_handle(pipeline); 1513 1514 if (device->debug_flags & RADV_DEBUG_DUMP_SHADER_STATS) { 1515 radv_dump_pipeline_stats(device, pipeline); 1516 } 1517 return VK_SUCCESS; 1518 } 1519 VkResult radv_CreateComputePipelines( 1520 VkDevice _device, 1521 VkPipelineCache pipelineCache, 1522 uint32_t count, 1523 const VkComputePipelineCreateInfo* pCreateInfos, 1524 const VkAllocationCallbacks* pAllocator, 1525 VkPipeline* pPipelines) 1526 { 1527 VkResult result = VK_SUCCESS; 1528 1529 unsigned i = 0; 1530 for (; i < count; i++) { 1531 VkResult r; 1532 r = radv_compute_pipeline_create(_device, pipelineCache, 1533 &pCreateInfos[i], 1534 pAllocator, &pPipelines[i]); 1535 if (r != VK_SUCCESS) { 1536 result = r; 1537 pPipelines[i] = VK_NULL_HANDLE; 1538 } 1539 } 1540 1541 return result; 1542 } 1543