1/* 2 * Copyright © 2022 Imagination Technologies Ltd. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a copy 5 * of this software and associated documentation files (the "Software"), to deal 6 * in the Software without restriction, including without limitation the rights 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 * copies of the Software, and to permit persons to whom the Software is 9 * furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 */ 23 24#include <assert.h> 25#include <limits.h> 26#include <stdint.h> 27#include <stdlib.h> 28#include <string.h> 29#include <vulkan/vulkan.h> 30 31#include "hwdef/rogue_hw_utils.h" 32#include "pvr_bo.h" 33#include "pvr_private.h" 34#include "pvr_types.h" 35#include "util/compiler.h" 36#include "util/list.h" 37#include "util/log.h" 38#include "util/macros.h" 39#include "vk_alloc.h" 40#include "vk_format.h" 41#include "vk_log.h" 42#include "vk_object.h" 43#include "vk_util.h" 44 45#if defined(DEBUG) 46static const struct { 47 const char *raw; 48 const char *primary; 49 const char *secondary; 50 const char *primary_dynamic; 51 const char *secondary_dynamic; 52} stage_names[] = { 53 { "Vertex", 54 "Vertex Primary", 55 "Vertex Secondary", 56 "Vertex Dynamic Primary", 57 "Vertex Dynamic Secondary" }, 58 { "Fragment", 59 "Fragment Primary", 60 "Fragment Secondary", 61 "Fragment Dynamic Primary", 62 "Fragment Dynamic Secondary" }, 63 { "Compute", 64 "Compute Primary", 65 "Compute Secondary", 66 "Compute Dynamic Primary", 67 "Compute Dynamic Secondary" }, 68}; 69 70static const char *descriptor_names[] = { "VK SAMPLER", 71 "VK COMBINED_IMAGE_SAMPLER", 72 "VK SAMPLED_IMAGE", 73 "VK STORAGE_IMAGE", 74 "VK UNIFORM_TEXEL_BUFFER", 75 "VK STORAGE_TEXEL_BUFFER", 76 "VK UNIFORM_BUFFER", 77 "VK STORAGE_BUFFER", 78 "VK UNIFORM_BUFFER_DYNAMIC", 79 "VK STORAGE_BUFFER_DYNAMIC", 80 "VK INPUT_ATTACHMENT" }; 81#endif 82 83#define PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYBASE 0U 84#define PVR_DESC_IMAGE_SECONDARY_SIZE_ARRAYBASE 2U 85#define PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYSTRIDE \ 86 (PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYBASE + \ 87 PVR_DESC_IMAGE_SECONDARY_SIZE_ARRAYBASE) 88#define PVR_DESC_IMAGE_SECONDARY_SIZE_ARRAYSTRIDE 1U 89 90#define PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYMAXINDEX(dev_info) \ 91 (PVR_HAS_FEATURE(dev_info, tpu_array_textures) \ 92 ? (0) \ 93 : PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYSTRIDE + \ 94 PVR_DESC_IMAGE_SECONDARY_SIZE_ARRAYSTRIDE) 95 96#define PVR_DESC_IMAGE_SECONDARY_SIZE_ARRAYMAXINDEX 1U 97#define PVR_DESC_IMAGE_SECONDARY_OFFSET_WIDTH(dev_info) \ 98 (PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYMAXINDEX(dev_info) + \ 99 PVR_DESC_IMAGE_SECONDARY_SIZE_ARRAYMAXINDEX) 100#define PVR_DESC_IMAGE_SECONDARY_SIZE_WIDTH 1U 101#define PVR_DESC_IMAGE_SECONDARY_OFFSET_HEIGHT(dev_info) \ 102 (PVR_DESC_IMAGE_SECONDARY_OFFSET_WIDTH(dev_info) + \ 103 PVR_DESC_IMAGE_SECONDARY_SIZE_WIDTH) 104#define PVR_DESC_IMAGE_SECONDARY_SIZE_HEIGHT 1U 105#define PVR_DESC_IMAGE_SECONDARY_OFFSET_DEPTH(dev_info) \ 106 (PVR_DESC_IMAGE_SECONDARY_OFFSET_HEIGHT(dev_info) + \ 107 PVR_DESC_IMAGE_SECONDARY_SIZE_HEIGHT) 108#define PVR_DESC_IMAGE_SECONDARY_SIZE_DEPTH 1U 109#define PVR_DESC_IMAGE_SECONDARY_TOTAL_SIZE(dev_info) \ 110 (PVR_DESC_IMAGE_SECONDARY_OFFSET_DEPTH(dev_info) + \ 111 PVR_DESC_IMAGE_SECONDARY_SIZE_DEPTH) 112 113static void pvr_descriptor_size_info_init( 114 const struct pvr_device *device, 115 VkDescriptorType type, 116 struct pvr_descriptor_size_info *const size_info_out) 117{ 118 /* UINT_MAX is a place holder. These values will be filled by calling the 119 * init function, and set appropriately based on device features. 120 */ 121 static const struct pvr_descriptor_size_info template_size_infos[] = { 122 /* VK_DESCRIPTOR_TYPE_SAMPLER */ 123 { PVR_SAMPLER_DESCRIPTOR_SIZE, 0, 4 }, 124 /* VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER */ 125 { PVR_IMAGE_DESCRIPTOR_SIZE + PVR_SAMPLER_DESCRIPTOR_SIZE, UINT_MAX, 4 }, 126 /* VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE */ 127 { 4, UINT_MAX, 4 }, 128 /* VK_DESCRIPTOR_TYPE_STORAGE_IMAGE */ 129 { 4, UINT_MAX, 4 }, 130 /* VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER */ 131 { 4, UINT_MAX, 4 }, 132 /* VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER */ 133 { 4, UINT_MAX, 4 }, 134 /* VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER */ 135 { 2, UINT_MAX, 2 }, 136 /* VK_DESCRIPTOR_TYPE_STORAGE_BUFFER */ 137 { 2, 1, 2 }, 138 /* VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC */ 139 { 2, UINT_MAX, 2 }, 140 /* VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC */ 141 { 2, 1, 2 }, 142 /* VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT */ 143 { 8, UINT_MAX, 4 } 144 }; 145 146 *size_info_out = template_size_infos[type]; 147 148 switch (type) { 149 case VK_DESCRIPTOR_TYPE_SAMPLER: 150 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 151 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 152 break; 153 154 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 155 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 156 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 157 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 158 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 159 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 160 size_info_out->secondary = 161 PVR_DESC_IMAGE_SECONDARY_TOTAL_SIZE(&device->pdevice->dev_info); 162 break; 163 164 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 165 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 166 size_info_out->secondary = (uint32_t)device->features.robustBufferAccess; 167 break; 168 169 default: 170 unreachable("Unknown descriptor type"); 171 } 172} 173 174static bool pvr_stage_matches_vk_flags(enum pvr_stage_allocation pvr_stage, 175 VkShaderStageFlags flags) 176{ 177 VkShaderStageFlags flags_per_stage; 178 179 switch (pvr_stage) { 180 case PVR_STAGE_ALLOCATION_VERTEX_GEOMETRY: 181 flags_per_stage = VK_SHADER_STAGE_VERTEX_BIT | 182 VK_SHADER_STAGE_GEOMETRY_BIT; 183 break; 184 case PVR_STAGE_ALLOCATION_FRAGMENT: 185 flags_per_stage = VK_SHADER_STAGE_FRAGMENT_BIT; 186 break; 187 case PVR_STAGE_ALLOCATION_COMPUTE: 188 flags_per_stage = VK_SHADER_STAGE_COMPUTE_BIT; 189 break; 190 default: 191 unreachable("Unrecognized allocation stage."); 192 } 193 194 return !!(flags_per_stage & flags); 195} 196 197/* If allocator == NULL, the internal one will be used. */ 198static struct pvr_descriptor_set_layout * 199pvr_descriptor_set_layout_allocate(struct pvr_device *device, 200 const VkAllocationCallbacks *allocator, 201 uint32_t binding_count, 202 uint32_t immutable_sampler_count, 203 uint32_t supported_descriptors_count) 204{ 205 struct pvr_descriptor_set_layout_binding *bindings; 206 struct pvr_descriptor_set_layout *layout; 207 __typeof__(layout->per_stage_descriptor_count) counts; 208 const struct pvr_sampler **immutable_samplers; 209 210 VK_MULTIALLOC(ma); 211 vk_multialloc_add(&ma, &layout, __typeof__(*layout), 1); 212 vk_multialloc_add(&ma, &bindings, __typeof__(*bindings), binding_count); 213 vk_multialloc_add(&ma, 214 &immutable_samplers, 215 __typeof__(*immutable_samplers), 216 immutable_sampler_count); 217 218 for (uint32_t stage = 0; stage < ARRAY_SIZE(counts); stage++) { 219 vk_multialloc_add(&ma, 220 &counts[stage], 221 __typeof__(*counts[0]), 222 supported_descriptors_count); 223 } 224 225 /* pvr_CreateDescriptorSetLayout() relies on this being zero allocated. */ 226 if (!vk_multialloc_zalloc2(&ma, 227 &device->vk.alloc, 228 allocator, 229 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)) { 230 return NULL; 231 } 232 233 layout->bindings = bindings; 234 layout->immutable_samplers = immutable_samplers; 235 236 memcpy(&layout->per_stage_descriptor_count, &counts, sizeof(counts)); 237 238 vk_object_base_init(&device->vk, 239 &layout->base, 240 VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT); 241 242 return layout; 243} 244 245/* If allocator == NULL, the internal one will be used. */ 246static void 247pvr_descriptor_set_layout_free(struct pvr_device *device, 248 const VkAllocationCallbacks *allocator, 249 struct pvr_descriptor_set_layout *layout) 250{ 251 vk_object_base_finish(&layout->base); 252 vk_free2(&device->vk.alloc, allocator, layout); 253} 254 255static int pvr_binding_compare(const void *a, const void *b) 256{ 257 uint32_t binding_a = ((VkDescriptorSetLayoutBinding *)a)->binding; 258 uint32_t binding_b = ((VkDescriptorSetLayoutBinding *)b)->binding; 259 260 if (binding_a < binding_b) 261 return -1; 262 263 if (binding_a > binding_b) 264 return 1; 265 266 return 0; 267} 268 269/* If allocator == NULL, the internal one will be used. */ 270static VkDescriptorSetLayoutBinding * 271pvr_create_sorted_bindings(struct pvr_device *device, 272 const VkAllocationCallbacks *allocator, 273 const VkDescriptorSetLayoutBinding *bindings, 274 uint32_t binding_count) 275{ 276 VkDescriptorSetLayoutBinding *sorted_bindings = 277 vk_alloc2(&device->vk.alloc, 278 allocator, 279 binding_count * sizeof(*sorted_bindings), 280 8, 281 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 282 if (!sorted_bindings) 283 return NULL; 284 285 memcpy(sorted_bindings, bindings, binding_count * sizeof(*sorted_bindings)); 286 287 qsort(sorted_bindings, 288 binding_count, 289 sizeof(*sorted_bindings), 290 pvr_binding_compare); 291 292 return sorted_bindings; 293} 294 295struct pvr_register_usage { 296 uint32_t primary; 297 uint32_t primary_dynamic; 298 uint32_t secondary; 299 uint32_t secondary_dynamic; 300}; 301 302static void pvr_setup_in_memory_layout_sizes( 303 struct pvr_descriptor_set_layout *layout, 304 const struct pvr_register_usage reg_usage[PVR_STAGE_ALLOCATION_COUNT]) 305{ 306 for (uint32_t stage = 0; 307 stage < ARRAY_SIZE(layout->memory_layout_in_dwords_per_stage); 308 stage++) { 309 layout->total_size_in_dwords = ALIGN_POT(layout->total_size_in_dwords, 4); 310 311 layout->memory_layout_in_dwords_per_stage[stage].primary_offset = 312 layout->total_size_in_dwords; 313 layout->memory_layout_in_dwords_per_stage[stage].primary_size = 314 reg_usage[stage].primary; 315 316 layout->total_size_in_dwords += reg_usage[stage].primary; 317 layout->total_size_in_dwords = ALIGN_POT(layout->total_size_in_dwords, 4); 318 319 layout->memory_layout_in_dwords_per_stage[stage].secondary_offset = 320 layout->total_size_in_dwords; 321 layout->memory_layout_in_dwords_per_stage[stage].secondary_size = 322 reg_usage[stage].secondary; 323 324 layout->total_size_in_dwords += reg_usage[stage].secondary; 325 326 layout->memory_layout_in_dwords_per_stage[stage].primary_dynamic_size = 327 reg_usage[stage].primary_dynamic; 328 layout->memory_layout_in_dwords_per_stage[stage].secondary_dynamic_size = 329 reg_usage[stage].secondary_dynamic; 330 } 331} 332 333#if defined(DEBUG) 334static void 335pvr_dump_in_memory_layout_sizes(const struct pvr_descriptor_set_layout *layout) 336{ 337 mesa_logd("=== SET LAYOUT ==="); 338 mesa_logd("----------------------------------------------"); 339 mesa_logd(" in memory:"); 340 mesa_logd("----------------------------------------------"); 341 342 for (uint32_t stage = 0; 343 stage < ARRAY_SIZE(layout->memory_layout_in_dwords_per_stage); 344 stage++) { 345 mesa_logd( 346 "| %-18s @ %04u |", 347 stage_names[stage].primary, 348 layout->memory_layout_in_dwords_per_stage[stage].primary_offset); 349 mesa_logd("----------------------------------------------"); 350 351 /* Print primaries. */ 352 for (uint32_t i = 0; i < layout->binding_count; i++) { 353 const struct pvr_descriptor_set_layout_binding *const binding = 354 &layout->bindings[i]; 355 356 if (binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || 357 binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) 358 continue; 359 360 mesa_logd("| %s %04u | %-26s[%3u] |", 361 (binding->shader_stage_mask & (1U << stage)) ? " " : "X", 362 binding->per_stage_offset_in_dwords[stage].primary, 363 descriptor_names[binding->type], 364 binding->descriptor_count); 365 } 366 367 /* Print dynamic primaries. */ 368 for (uint32_t i = 0; i < layout->binding_count; i++) { 369 const struct pvr_descriptor_set_layout_binding *const binding = 370 &layout->bindings[i]; 371 372 if (binding->type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC && 373 binding->type != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) 374 continue; 375 376 mesa_logd("| * %s %04u | %-26s[%3u] |", 377 (binding->shader_stage_mask & (1U << stage)) ? " " : "X", 378 binding->per_stage_offset_in_dwords[stage].primary, 379 descriptor_names[binding->type], 380 binding->descriptor_count); 381 } 382 383 mesa_logd("----------------------------------------------"); 384 mesa_logd( 385 "| %-18s @ %04u |", 386 stage_names[stage].secondary, 387 layout->memory_layout_in_dwords_per_stage[stage].secondary_offset); 388 mesa_logd("----------------------------------------------"); 389 390 /* Print secondaries. */ 391 for (uint32_t i = 0; i < layout->binding_count; i++) { 392 const struct pvr_descriptor_set_layout_binding *const binding = 393 &layout->bindings[i]; 394 395 if (binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || 396 binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) 397 continue; 398 399 mesa_logd("| %s %04u | %-26s[%3u] |", 400 (binding->shader_stage_mask & (1U << stage)) ? " " : "X", 401 binding->per_stage_offset_in_dwords[stage].secondary, 402 descriptor_names[binding->type], 403 binding->descriptor_count); 404 } 405 406 /* Print dynamic secondaries. */ 407 for (uint32_t i = 0; i < layout->binding_count; i++) { 408 const struct pvr_descriptor_set_layout_binding *const binding = 409 &layout->bindings[i]; 410 411 if (binding->type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC && 412 binding->type != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) 413 continue; 414 415 mesa_logd("| * %s %04u | %-26s[%3u] |", 416 (binding->shader_stage_mask & (1U << stage)) ? " " : "X", 417 binding->per_stage_offset_in_dwords[stage].secondary, 418 descriptor_names[binding->type], 419 binding->descriptor_count); 420 } 421 422 mesa_logd("=============================================="); 423 } 424} 425#endif 426 427VkResult pvr_CreateDescriptorSetLayout( 428 VkDevice _device, 429 const VkDescriptorSetLayoutCreateInfo *pCreateInfo, 430 const VkAllocationCallbacks *pAllocator, 431 VkDescriptorSetLayout *pSetLayout) 432{ 433 /* Used to accumulate sizes and set each descriptor's offsets per stage. */ 434 struct pvr_register_usage reg_usage[PVR_STAGE_ALLOCATION_COUNT] = { 0 }; 435 PVR_FROM_HANDLE(pvr_device, device, _device); 436 struct pvr_descriptor_set_layout *layout; 437 VkDescriptorSetLayoutBinding *bindings; 438 uint32_t immutable_sampler_count; 439 440 assert(pCreateInfo->sType == 441 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO); 442 443 vk_foreach_struct_const (ext, pCreateInfo->pNext) { 444 pvr_debug_ignored_stype(ext->sType); 445 } 446 447 /* TODO: Add support for push descriptors. */ 448 449 if (pCreateInfo->bindingCount == 0) { 450 layout = pvr_descriptor_set_layout_allocate(device, pAllocator, 0, 0, 0); 451 if (!layout) 452 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 453 454 *pSetLayout = pvr_descriptor_set_layout_to_handle(layout); 455 return VK_SUCCESS; 456 } 457 458 /* TODO: Instead of sorting, maybe do what anvil does? */ 459 bindings = pvr_create_sorted_bindings(device, 460 pAllocator, 461 pCreateInfo->pBindings, 462 pCreateInfo->bindingCount); 463 if (!bindings) 464 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 465 466 immutable_sampler_count = 0; 467 for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) { 468 /* From the Vulkan 1.1.97 spec for VkDescriptorSetLayoutBinding: 469 * 470 * "If descriptorType specifies a VK_DESCRIPTOR_TYPE_SAMPLER or 471 * VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER type descriptor, then 472 * pImmutableSamplers can be used to initialize a set of immutable 473 * samplers. [...] If descriptorType is not one of these descriptor 474 * types, then pImmutableSamplers is ignored. 475 * 476 * We need to be careful here and only parse pImmutableSamplers if we 477 * have one of the right descriptor types. 478 */ 479 const VkDescriptorType descriptor_type = bindings[i].descriptorType; 480 if ((descriptor_type == VK_DESCRIPTOR_TYPE_SAMPLER || 481 descriptor_type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) && 482 bindings[i].pImmutableSamplers) 483 immutable_sampler_count += bindings[i].descriptorCount; 484 } 485 486 /* From the Vulkan 1.2.190 spec for VkDescriptorSetLayoutCreateInfo: 487 * 488 * "The VkDescriptorSetLayoutBinding::binding members of the elements 489 * of the pBindings array must each have different values." 490 * 491 * So we don't worry about duplicates and just allocate for bindingCount 492 * amount of bindings. 493 */ 494 layout = pvr_descriptor_set_layout_allocate( 495 device, 496 pAllocator, 497 pCreateInfo->bindingCount, 498 immutable_sampler_count, 499 PVR_PIPELINE_LAYOUT_SUPPORTED_DESCRIPTOR_TYPE_COUNT); 500 if (!layout) { 501 vk_free2(&device->vk.alloc, pAllocator, bindings); 502 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 503 } 504 505 layout->binding_count = pCreateInfo->bindingCount; 506 507 for (uint32_t bind_num = 0; bind_num < layout->binding_count; bind_num++) { 508 const VkDescriptorSetLayoutBinding *const binding = &bindings[bind_num]; 509 struct pvr_descriptor_set_layout_binding *const internal_binding = 510 &layout->bindings[bind_num]; 511 VkShaderStageFlags shader_stages = 0; 512 513 internal_binding->type = binding->descriptorType; 514 /* The binding_numbers can be non-contiguous so we ignore the user 515 * specified binding numbers and make them contiguous ourselves. 516 */ 517 internal_binding->binding_number = bind_num; 518 519 /* From Vulkan spec 1.2.189: 520 * 521 * "If descriptorCount is zero this binding entry is reserved and the 522 * resource must not be accessed from any stage via this binding" 523 * 524 * So do not use bindings->stageFlags, use shader_stages instead. 525 */ 526 if (binding->descriptorCount) { 527 shader_stages = binding->stageFlags; 528 529 internal_binding->descriptor_count = binding->descriptorCount; 530 internal_binding->descriptor_index = layout->descriptor_count; 531 layout->descriptor_count += binding->descriptorCount; 532 } 533 534 switch (binding->descriptorType) { 535 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 536 case VK_DESCRIPTOR_TYPE_SAMPLER: 537 if (binding->pImmutableSamplers && binding->descriptorCount > 0) { 538 internal_binding->has_immutable_samplers = true; 539 internal_binding->immutable_samplers_index = 540 layout->immutable_sampler_count; 541 542 for (uint32_t j = 0; j < binding->descriptorCount; j++) { 543 PVR_FROM_HANDLE(pvr_sampler, 544 sampler, 545 bindings->pImmutableSamplers[j]); 546 const uint32_t next = j + layout->immutable_sampler_count; 547 548 layout->immutable_samplers[next] = sampler; 549 } 550 551 layout->immutable_sampler_count += binding->descriptorCount; 552 } 553 break; 554 555 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 556 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 557 layout->dynamic_buffer_count += binding->descriptorCount; 558 break; 559 560 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 561 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 562 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 563 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 564 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 565 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 566 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 567 break; 568 569 default: 570 unreachable("Unknown descriptor type"); 571 break; 572 } 573 574 if (!shader_stages) 575 continue; 576 577 internal_binding->shader_stages = shader_stages; 578 layout->shader_stages |= shader_stages; 579 580 for (uint32_t stage = 0; 581 stage < ARRAY_SIZE(layout->bindings[0].per_stage_offset_in_dwords); 582 stage++) { 583 const VkDescriptorType descriptor_type = binding->descriptorType; 584 585 if (!pvr_stage_matches_vk_flags(stage, shader_stages)) 586 continue; 587 588 internal_binding->shader_stage_mask |= (1U << stage); 589 590 /* TODO: Do we have to allocate them at the end? We could speed it 591 * by allocating them here if not. */ 592 /* We allocate dynamics primary and secondaries at the end. */ 593 if (descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC && 594 descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) { 595 struct pvr_descriptor_size_info size_info; 596 597 pvr_descriptor_size_info_init(device, descriptor_type, &size_info); 598 599 STATIC_ASSERT( 600 ARRAY_SIZE(reg_usage) == 601 ARRAY_SIZE(layout->bindings[0].per_stage_offset_in_dwords)); 602 603 reg_usage[stage].primary = 604 ALIGN_POT(reg_usage[stage].primary, size_info.alignment); 605 606 internal_binding->per_stage_offset_in_dwords[stage].primary = 607 reg_usage[stage].primary; 608 reg_usage[stage].primary += 609 size_info.primary * internal_binding->descriptor_count; 610 611 internal_binding->per_stage_offset_in_dwords[stage].secondary = 612 reg_usage[stage].secondary; 613 reg_usage[stage].secondary += 614 size_info.secondary * internal_binding->descriptor_count; 615 } 616 617 STATIC_ASSERT( 618 ARRAY_SIZE(layout->per_stage_descriptor_count) == 619 ARRAY_SIZE(layout->bindings[0].per_stage_offset_in_dwords)); 620 621 layout->per_stage_descriptor_count[stage][descriptor_type] += 622 internal_binding->descriptor_count; 623 } 624 } 625 626 for (uint32_t bind_num = 0; bind_num < layout->binding_count; bind_num++) { 627 struct pvr_descriptor_set_layout_binding *const internal_binding = 628 &layout->bindings[bind_num]; 629 const VkDescriptorType descriptor_type = internal_binding->type; 630 631 if (descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC && 632 descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) 633 continue; 634 635 for (uint32_t stage = 0; 636 stage < ARRAY_SIZE(layout->bindings[0].per_stage_offset_in_dwords); 637 stage++) { 638 struct pvr_descriptor_size_info size_info; 639 const VkShaderStageFlags shader_stages = 640 internal_binding->shader_stages; 641 642 if (!pvr_stage_matches_vk_flags(stage, shader_stages)) 643 continue; 644 645 pvr_descriptor_size_info_init(device, descriptor_type, &size_info); 646 647 /* TODO: align primary like we did with other descriptors? */ 648 internal_binding->per_stage_offset_in_dwords[stage].primary = 649 reg_usage[stage].primary_dynamic; 650 reg_usage[stage].primary_dynamic += 651 size_info.primary * internal_binding->descriptor_count; 652 653 internal_binding->per_stage_offset_in_dwords[stage].secondary = 654 reg_usage[stage].secondary_dynamic; 655 reg_usage[stage].secondary_dynamic += 656 size_info.secondary * internal_binding->descriptor_count; 657 } 658 } 659 660 pvr_setup_in_memory_layout_sizes(layout, reg_usage); 661 662#if defined(DEBUG) 663 pvr_dump_in_memory_layout_sizes(layout); 664#endif 665 666 vk_free2(&device->vk.alloc, pAllocator, bindings); 667 668 *pSetLayout = pvr_descriptor_set_layout_to_handle(layout); 669 670 return VK_SUCCESS; 671} 672 673void pvr_DestroyDescriptorSetLayout(VkDevice _device, 674 VkDescriptorSetLayout _set_layout, 675 const VkAllocationCallbacks *pAllocator) 676{ 677 PVR_FROM_HANDLE(pvr_descriptor_set_layout, layout, _set_layout); 678 PVR_FROM_HANDLE(pvr_device, device, _device); 679 680 pvr_descriptor_set_layout_free(device, pAllocator, layout); 681} 682 683#if defined(DEBUG) 684static void 685pvr_dump_in_register_layout_sizes(const struct pvr_device *device, 686 const struct pvr_pipeline_layout *layout) 687{ 688 mesa_logd("=== SET LAYOUT ==="); 689 mesa_logd("----------------------------------------------------"); 690 mesa_logd(" in registers:"); 691 mesa_logd("----------------------------------------------------"); 692 693 for (uint32_t stage = 0; 694 stage < ARRAY_SIZE(layout->register_layout_in_dwords_per_stage); 695 stage++) { 696 uint32_t dynamic_offset = 0; 697 698 mesa_logd("| %-48s |", stage_names[stage].primary_dynamic); 699 mesa_logd("----------------------------------------------------"); 700 701 /* Print dynamic primaries. */ 702 for (uint32_t set_num = 0; set_num < layout->set_count; set_num++) { 703 const struct pvr_descriptor_set_layout *const set_layout = 704 layout->set_layout[set_num]; 705 706 for (uint32_t i = 0; i < set_layout->binding_count; i++) { 707 const struct pvr_descriptor_set_layout_binding *const binding = 708 &set_layout->bindings[i]; 709 bool valid = !!(binding->shader_stage_mask & (1U << stage)); 710 711 if (binding->type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC && 712 binding->type != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) 713 continue; 714 715 mesa_logd("| %s %04u | %u:%03u | %-26s[%3u] |", 716 (valid) ? " " : "X", 717 dynamic_offset, 718 set_num, 719 i, 720 descriptor_names[binding->type], 721 binding->descriptor_count); 722 723 if (valid) { 724 struct pvr_descriptor_size_info size_info; 725 726 pvr_descriptor_size_info_init(device, binding->type, &size_info); 727 728 dynamic_offset += size_info.primary; 729 } 730 } 731 } 732 733 mesa_logd("----------------------------------------------------"); 734 mesa_logd("| %-48s |", stage_names[stage].secondary_dynamic); 735 mesa_logd("----------------------------------------------------"); 736 737 /* Print dynamic secondaries. */ 738 for (uint32_t set_num = 0; set_num < layout->set_count; set_num++) { 739 const struct pvr_descriptor_set_layout *const set_layout = 740 layout->set_layout[set_num]; 741 742 for (uint32_t i = 0; i < set_layout->binding_count; i++) { 743 const struct pvr_descriptor_set_layout_binding *const binding = 744 &set_layout->bindings[i]; 745 bool valid = !!(binding->shader_stage_mask & (1U << stage)); 746 747 if (binding->type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC && 748 binding->type != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) 749 continue; 750 751 mesa_logd("| %s %04u | %u:%03u | %-26s[%3u] |", 752 (valid) ? " " : "X", 753 dynamic_offset, 754 set_num, 755 i, 756 descriptor_names[binding->type], 757 binding->descriptor_count); 758 759 if (valid) { 760 struct pvr_descriptor_size_info size_info; 761 762 pvr_descriptor_size_info_init(device, binding->type, &size_info); 763 764 dynamic_offset += size_info.secondary; 765 } 766 } 767 } 768 769 mesa_logd("----------------------------------------------------"); 770 mesa_logd("| %-48s |", stage_names[stage].primary); 771 mesa_logd("----------------------------------------------------"); 772 773 /* Print primaries. */ 774 for (uint32_t set_num = 0; set_num < layout->set_count; set_num++) { 775 const struct pvr_descriptor_set_layout *const set_layout = 776 layout->set_layout[set_num]; 777 const uint32_t base = 778 layout->register_layout_in_dwords_per_stage[stage][set_num] 779 .primary_offset; 780 781 for (uint32_t i = 0; i < set_layout->binding_count; i++) { 782 const struct pvr_descriptor_set_layout_binding *const binding = 783 &set_layout->bindings[i]; 784 785 if (binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || 786 binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) 787 continue; 788 789 mesa_logd("| %s %04u | %u:%03u | %-26s[%3u] |", 790 (binding->shader_stage_mask & (1U << stage)) ? " " : "X", 791 base + binding->per_stage_offset_in_dwords[stage].primary, 792 set_num, 793 i, 794 descriptor_names[binding->type], 795 binding->descriptor_count); 796 } 797 } 798 799 mesa_logd("----------------------------------------------------"); 800 mesa_logd("| %-48s |", stage_names[stage].secondary); 801 mesa_logd("----------------------------------------------------"); 802 803 /* Print secondaries. */ 804 for (uint32_t set_num = 0; set_num < layout->set_count; set_num++) { 805 const struct pvr_descriptor_set_layout *const set_layout = 806 layout->set_layout[set_num]; 807 const uint32_t base = 808 layout->register_layout_in_dwords_per_stage[stage][set_num] 809 .secondary_offset; 810 811 for (uint32_t i = 0; i < set_layout->binding_count; i++) { 812 const struct pvr_descriptor_set_layout_binding *const binding = 813 &set_layout->bindings[i]; 814 815 if (binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || 816 binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) 817 continue; 818 819 mesa_logd("| %s %04u | %u:%03u | %-26s[%3u] |", 820 (binding->shader_stage_mask & (1U << stage)) ? " " : "X", 821 base + 822 binding->per_stage_offset_in_dwords[stage].secondary, 823 set_num, 824 i, 825 descriptor_names[binding->type], 826 binding->descriptor_count); 827 } 828 } 829 830 mesa_logd("===================================================="); 831 } 832} 833#endif 834 835/* Pipeline layouts. These have nothing to do with the pipeline. They are 836 * just multiple descriptor set layouts pasted together. 837 */ 838VkResult pvr_CreatePipelineLayout(VkDevice _device, 839 const VkPipelineLayoutCreateInfo *pCreateInfo, 840 const VkAllocationCallbacks *pAllocator, 841 VkPipelineLayout *pPipelineLayout) 842{ 843 uint32_t next_free_reg[PVR_STAGE_ALLOCATION_COUNT]; 844 PVR_FROM_HANDLE(pvr_device, device, _device); 845 struct pvr_pipeline_layout *layout; 846 847 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO); 848 assert(pCreateInfo->setLayoutCount <= PVR_MAX_DESCRIPTOR_SETS); 849 850 layout = vk_object_alloc(&device->vk, 851 pAllocator, 852 sizeof(*layout), 853 VK_OBJECT_TYPE_PIPELINE_LAYOUT); 854 if (!layout) 855 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 856 857 layout->set_count = pCreateInfo->setLayoutCount; 858 layout->shader_stages = 0; 859 for (uint32_t stage = 0; stage < PVR_STAGE_ALLOCATION_COUNT; stage++) { 860 uint32_t descriptor_counts 861 [PVR_PIPELINE_LAYOUT_SUPPORTED_DESCRIPTOR_TYPE_COUNT] = { 0 }; 862 struct pvr_pipeline_layout_reg_info *const reg_info = 863 &layout->per_stage_reg_info[stage]; 864 865 *reg_info = (struct pvr_pipeline_layout_reg_info){ 0 }; 866 867 layout->per_stage_descriptor_masks[stage] = 0; 868 869 for (uint32_t set_num = 0; set_num < layout->set_count; set_num++) { 870 /* So we don't write these again and again. Just do it once. */ 871 if (stage == 0) { 872 PVR_FROM_HANDLE(pvr_descriptor_set_layout, 873 set_layout, 874 pCreateInfo->pSetLayouts[set_num]); 875 876 layout->set_layout[set_num] = set_layout; 877 layout->shader_stages |= set_layout->shader_stages; 878 } 879 880 const struct pvr_descriptor_set_layout_mem_layout *const mem_layout = 881 &layout->set_layout[set_num] 882 ->memory_layout_in_dwords_per_stage[stage]; 883 884 /* Allocate registers counts for dynamic descriptors. */ 885 reg_info->primary_dynamic_size_in_dwords += 886 mem_layout->primary_dynamic_size; 887 reg_info->secondary_dynamic_size_in_dwords += 888 mem_layout->secondary_dynamic_size; 889 890 for (VkDescriptorType type = 0; 891 type < PVR_PIPELINE_LAYOUT_SUPPORTED_DESCRIPTOR_TYPE_COUNT; 892 type++) { 893 uint32_t descriptor_count; 894 895 layout->descriptor_offsets[set_num][stage][type] = 896 descriptor_counts[type]; 897 898 descriptor_count = layout->set_layout[set_num] 899 ->per_stage_descriptor_count[stage][type]; 900 901 if (!descriptor_count) 902 continue; 903 904 switch (type) { 905 case VK_DESCRIPTOR_TYPE_SAMPLER: 906 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 907 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 908 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 909 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 910 layout->per_stage_descriptor_masks[stage] |= 1U << set_num; 911 descriptor_counts[type] += descriptor_count; 912 break; 913 914 /* We don't need to keep track of the counts or masks for other 915 * descriptor types so there is no assert() here since other 916 * types are not invalid or unsupported. 917 */ 918 /* TODO: Improve the comment above to specify why, when we find 919 * out. 920 */ 921 default: 922 break; 923 } 924 } 925 } 926 927 next_free_reg[stage] = reg_info->primary_dynamic_size_in_dwords + 928 reg_info->secondary_dynamic_size_in_dwords; 929 } 930 931 /* Allocate registers counts for primary and secondary descriptors. */ 932 for (uint32_t stage = 0; stage < PVR_STAGE_ALLOCATION_COUNT; stage++) { 933 for (uint32_t set_num = 0; set_num < layout->set_count; set_num++) { 934 const struct pvr_descriptor_set_layout_mem_layout *const mem_layout = 935 &layout->set_layout[set_num] 936 ->memory_layout_in_dwords_per_stage[stage]; 937 struct pvr_descriptor_set_layout_mem_layout *const reg_layout = 938 &layout->register_layout_in_dwords_per_stage[stage][set_num]; 939 940 next_free_reg[stage] = ALIGN_POT(next_free_reg[stage], 4); 941 942 reg_layout->primary_offset = next_free_reg[stage]; 943 reg_layout->primary_size = mem_layout->primary_size; 944 945 next_free_reg[stage] += reg_layout->primary_size; 946 } 947 948 /* To optimize the total shared layout allocation used by the shader, 949 * secondary descriptors come last since they're less likely to be used. 950 */ 951 for (uint32_t set_num = 0; set_num < layout->set_count; set_num++) { 952 const struct pvr_descriptor_set_layout_mem_layout *const mem_layout = 953 &layout->set_layout[set_num] 954 ->memory_layout_in_dwords_per_stage[stage]; 955 struct pvr_descriptor_set_layout_mem_layout *const reg_layout = 956 &layout->register_layout_in_dwords_per_stage[stage][set_num]; 957 958 /* Should we be aligning next_free_reg like it's done with the 959 * primary descriptors? 960 */ 961 962 reg_layout->secondary_offset = next_free_reg[stage]; 963 reg_layout->secondary_size = mem_layout->secondary_size; 964 965 next_free_reg[stage] += reg_layout->secondary_size; 966 } 967 } 968 969 layout->push_constants_shader_stages = 0; 970 for (uint32_t i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) { 971 const VkPushConstantRange *range = &pCreateInfo->pPushConstantRanges[i]; 972 973 layout->push_constants_shader_stages |= range->stageFlags; 974 } 975 976#if defined(DEBUG) 977 pvr_dump_in_register_layout_sizes(device, layout); 978#endif 979 980 *pPipelineLayout = pvr_pipeline_layout_to_handle(layout); 981 982 return VK_SUCCESS; 983} 984 985void pvr_DestroyPipelineLayout(VkDevice _device, 986 VkPipelineLayout _pipelineLayout, 987 const VkAllocationCallbacks *pAllocator) 988{ 989 PVR_FROM_HANDLE(pvr_device, device, _device); 990 PVR_FROM_HANDLE(pvr_pipeline_layout, layout, _pipelineLayout); 991 992 vk_object_free(&device->vk, pAllocator, layout); 993} 994 995VkResult pvr_CreateDescriptorPool(VkDevice _device, 996 const VkDescriptorPoolCreateInfo *pCreateInfo, 997 const VkAllocationCallbacks *pAllocator, 998 VkDescriptorPool *pDescriptorPool) 999{ 1000 PVR_FROM_HANDLE(pvr_device, device, _device); 1001 struct pvr_descriptor_pool *pool; 1002 1003 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO); 1004 1005 pool = vk_object_alloc(&device->vk, 1006 pAllocator, 1007 sizeof(*pool), 1008 VK_OBJECT_TYPE_DESCRIPTOR_POOL); 1009 if (!pool) 1010 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 1011 1012 if (pAllocator) 1013 pool->alloc = *pAllocator; 1014 else 1015 pool->alloc = device->vk.alloc; 1016 1017 pool->max_sets = pCreateInfo->maxSets; 1018 list_inithead(&pool->descriptor_sets); 1019 1020 pool->total_size_in_dwords = 0; 1021 for (uint32_t i = 0; i < pCreateInfo->poolSizeCount; i++) { 1022 struct pvr_descriptor_size_info size_info; 1023 const uint32_t descriptor_count = 1024 pCreateInfo->pPoolSizes[i].descriptorCount; 1025 1026 pvr_descriptor_size_info_init(device, 1027 pCreateInfo->pPoolSizes[i].type, 1028 &size_info); 1029 1030 const uint32_t secondary = ALIGN_POT(size_info.secondary, 4); 1031 const uint32_t primary = ALIGN_POT(size_info.primary, 4); 1032 1033 pool->total_size_in_dwords += descriptor_count * (primary + secondary); 1034 } 1035 pool->total_size_in_dwords *= PVR_STAGE_ALLOCATION_COUNT; 1036 pool->current_size_in_dwords = 0; 1037 1038 pvr_finishme("Entry tracker for allocations?"); 1039 1040 *pDescriptorPool = pvr_descriptor_pool_to_handle(pool); 1041 1042 return VK_SUCCESS; 1043} 1044 1045static void pvr_free_descriptor_set(struct pvr_device *device, 1046 struct pvr_descriptor_pool *pool, 1047 struct pvr_descriptor_set *set) 1048{ 1049 list_del(&set->link); 1050 pvr_bo_free(device, set->pvr_bo); 1051 vk_object_free(&device->vk, &pool->alloc, set); 1052} 1053 1054void pvr_DestroyDescriptorPool(VkDevice _device, 1055 VkDescriptorPool _pool, 1056 const VkAllocationCallbacks *pAllocator) 1057{ 1058 PVR_FROM_HANDLE(pvr_device, device, _device); 1059 PVR_FROM_HANDLE(pvr_descriptor_pool, pool, _pool); 1060 1061 if (!pool) 1062 return; 1063 1064 list_for_each_entry_safe (struct pvr_descriptor_set, 1065 set, 1066 &pool->descriptor_sets, 1067 link) { 1068 pvr_free_descriptor_set(device, pool, set); 1069 } 1070 1071 vk_object_free(&device->vk, pAllocator, pool); 1072} 1073 1074VkResult pvr_ResetDescriptorPool(VkDevice _device, 1075 VkDescriptorPool descriptorPool, 1076 VkDescriptorPoolResetFlags flags) 1077{ 1078 assert(!"Unimplemented"); 1079 return VK_SUCCESS; 1080} 1081 1082static uint16_t pvr_get_descriptor_primary_offset( 1083 const struct pvr_device *device, 1084 const struct pvr_descriptor_set_layout *layout, 1085 const struct pvr_descriptor_set_layout_binding *binding, 1086 const uint32_t stage, 1087 const uint32_t desc_idx) 1088{ 1089 struct pvr_descriptor_size_info size_info; 1090 uint32_t offset; 1091 1092 assert(stage < ARRAY_SIZE(layout->memory_layout_in_dwords_per_stage)); 1093 assert(desc_idx < binding->descriptor_count); 1094 1095 pvr_descriptor_size_info_init(device, binding->type, &size_info); 1096 1097 offset = layout->memory_layout_in_dwords_per_stage[stage].primary_offset; 1098 offset += binding->per_stage_offset_in_dwords[stage].primary; 1099 offset += (desc_idx * size_info.primary); 1100 1101 /* Offset must be less than 16bits. */ 1102 assert(offset < UINT16_MAX); 1103 1104 return (uint16_t)offset; 1105} 1106 1107static uint16_t pvr_get_descriptor_secondary_offset( 1108 const struct pvr_device *device, 1109 const struct pvr_descriptor_set_layout *layout, 1110 const struct pvr_descriptor_set_layout_binding *binding, 1111 const uint32_t stage, 1112 const uint32_t desc_idx) 1113{ 1114 struct pvr_descriptor_size_info size_info; 1115 uint32_t offset; 1116 1117 assert(stage < ARRAY_SIZE(layout->memory_layout_in_dwords_per_stage)); 1118 assert(desc_idx < binding->descriptor_count); 1119 1120 pvr_descriptor_size_info_init(device, binding->type, &size_info); 1121 1122 offset = layout->memory_layout_in_dwords_per_stage[stage].secondary_offset; 1123 offset += binding->per_stage_offset_in_dwords[stage].secondary; 1124 offset += (desc_idx * size_info.secondary); 1125 1126 /* Offset must be less than 16bits. */ 1127 assert(offset < UINT16_MAX); 1128 1129 return (uint16_t)offset; 1130} 1131 1132#define PVR_MAX_DESCRIPTOR_MEM_SIZE_IN_DWORDS (4 * 1024) 1133 1134static VkResult 1135pvr_descriptor_set_create(struct pvr_device *device, 1136 struct pvr_descriptor_pool *pool, 1137 const struct pvr_descriptor_set_layout *layout, 1138 struct pvr_descriptor_set **const descriptor_set_out) 1139{ 1140 struct pvr_descriptor_set *set; 1141 VkResult result; 1142 size_t size; 1143 void *map; 1144 1145 size = sizeof(*set) + sizeof(set->descriptors[0]) * layout->descriptor_count; 1146 1147 /* TODO: Add support to allocate descriptors from descriptor pool, also 1148 * check the required descriptors must not exceed max allowed descriptors. 1149 */ 1150 set = vk_object_zalloc(&device->vk, 1151 &pool->alloc, 1152 size, 1153 VK_OBJECT_TYPE_DESCRIPTOR_SET); 1154 if (!set) 1155 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 1156 1157 /* TODO: Add support to allocate device memory from a common pool. Look at 1158 * something like anv. Also we can allocate a whole chunk of device memory 1159 * for max descriptors supported by pool as done by v3dv. Also check the 1160 * possibility if this can be removed from here and done on need basis. 1161 */ 1162 1163 if (layout->binding_count > 0) { 1164 const uint32_t cache_line_size = 1165 rogue_get_slc_cache_line_size(&device->pdevice->dev_info); 1166 uint64_t bo_size = MIN2(pool->total_size_in_dwords, 1167 PVR_MAX_DESCRIPTOR_MEM_SIZE_IN_DWORDS) * 1168 sizeof(uint32_t); 1169 1170 result = pvr_bo_alloc(device, 1171 device->heaps.general_heap, 1172 bo_size, 1173 cache_line_size, 1174 PVR_BO_ALLOC_FLAG_CPU_MAPPED, 1175 &set->pvr_bo); 1176 if (result != VK_SUCCESS) 1177 goto err_free_descriptor_set; 1178 } 1179 1180 set->layout = layout; 1181 set->pool = pool; 1182 1183 map = set->pvr_bo->bo->map; 1184 for (uint32_t i = 0; i < layout->binding_count; i++) { 1185 const struct pvr_descriptor_set_layout_binding *binding = 1186 &layout->bindings[i]; 1187 1188 if (binding->descriptor_count == 0 || !binding->has_immutable_samplers) 1189 continue; 1190 1191 for (uint32_t stage = 0; 1192 stage < ARRAY_SIZE(binding->per_stage_offset_in_dwords); 1193 stage++) { 1194 if (!(binding->shader_stage_mask & (1U << stage))) 1195 continue; 1196 1197 for (uint32_t j = 0; j < binding->descriptor_count; j++) { 1198 uint32_t idx = binding->immutable_samplers_index + j; 1199 const struct pvr_sampler *sampler = layout->immutable_samplers[idx]; 1200 unsigned int offset_in_dwords = 1201 pvr_get_descriptor_primary_offset(device, 1202 layout, 1203 binding, 1204 stage, 1205 j); 1206 1207 if (binding->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 1208 offset_in_dwords += 4; 1209 1210 memcpy((uint8_t *)map + offset_in_dwords * sizeof(uint32_t), 1211 sampler->descriptor.words, 1212 sizeof(sampler->descriptor.words)); 1213 } 1214 } 1215 } 1216 1217 list_addtail(&set->link, &pool->descriptor_sets); 1218 1219 *descriptor_set_out = set; 1220 1221 return VK_SUCCESS; 1222 1223err_free_descriptor_set: 1224 vk_object_free(&device->vk, &pool->alloc, set); 1225 1226 return result; 1227} 1228 1229VkResult 1230pvr_AllocateDescriptorSets(VkDevice _device, 1231 const VkDescriptorSetAllocateInfo *pAllocateInfo, 1232 VkDescriptorSet *pDescriptorSets) 1233{ 1234 PVR_FROM_HANDLE(pvr_descriptor_pool, pool, pAllocateInfo->descriptorPool); 1235 PVR_FROM_HANDLE(pvr_device, device, _device); 1236 VkResult result; 1237 uint32_t i; 1238 1239 vk_foreach_struct_const (ext, pAllocateInfo->pNext) { 1240 pvr_debug_ignored_stype(ext->sType); 1241 } 1242 1243 for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) { 1244 PVR_FROM_HANDLE(pvr_descriptor_set_layout, 1245 layout, 1246 pAllocateInfo->pSetLayouts[i]); 1247 struct pvr_descriptor_set *set = NULL; 1248 1249 result = pvr_descriptor_set_create(device, pool, layout, &set); 1250 if (result != VK_SUCCESS) 1251 goto err_free_descriptor_sets; 1252 1253 pDescriptorSets[i] = pvr_descriptor_set_to_handle(set); 1254 } 1255 1256 return VK_SUCCESS; 1257 1258err_free_descriptor_sets: 1259 pvr_FreeDescriptorSets(_device, 1260 pAllocateInfo->descriptorPool, 1261 i, 1262 pDescriptorSets); 1263 1264 for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) 1265 pDescriptorSets[i] = VK_NULL_HANDLE; 1266 1267 return result; 1268} 1269 1270VkResult pvr_FreeDescriptorSets(VkDevice _device, 1271 VkDescriptorPool descriptorPool, 1272 uint32_t count, 1273 const VkDescriptorSet *pDescriptorSets) 1274{ 1275 PVR_FROM_HANDLE(pvr_descriptor_pool, pool, descriptorPool); 1276 PVR_FROM_HANDLE(pvr_device, device, _device); 1277 1278 for (uint32_t i = 0; i < count; i++) { 1279 struct pvr_descriptor_set *set; 1280 1281 if (!pDescriptorSets[i]) 1282 continue; 1283 1284 set = pvr_descriptor_set_from_handle(pDescriptorSets[i]); 1285 pvr_free_descriptor_set(device, pool, set); 1286 } 1287 1288 return VK_SUCCESS; 1289} 1290 1291static int pvr_compare_layout_binding(const void *a, const void *b) 1292{ 1293 uint32_t binding_a; 1294 uint32_t binding_b; 1295 1296 binding_a = ((struct pvr_descriptor_set_layout_binding *)a)->binding_number; 1297 binding_b = ((struct pvr_descriptor_set_layout_binding *)b)->binding_number; 1298 1299 if (binding_a < binding_b) 1300 return -1; 1301 1302 if (binding_a > binding_b) 1303 return 1; 1304 1305 return 0; 1306} 1307 1308/* This function does not assume that the binding will always exist for a 1309 * particular binding_num. Caller should check before using the return pointer. 1310 */ 1311static struct pvr_descriptor_set_layout_binding * 1312pvr_get_descriptor_binding(const struct pvr_descriptor_set_layout *layout, 1313 const uint32_t binding_num) 1314{ 1315 struct pvr_descriptor_set_layout_binding binding; 1316 binding.binding_number = binding_num; 1317 1318 return bsearch(&binding, 1319 layout->bindings, 1320 layout->binding_count, 1321 sizeof(binding), 1322 pvr_compare_layout_binding); 1323} 1324 1325static void pvr_descriptor_update_buffer_info( 1326 const struct pvr_device *device, 1327 const VkWriteDescriptorSet *write_set, 1328 struct pvr_descriptor_set *set, 1329 const struct pvr_descriptor_set_layout_binding *binding, 1330 uint32_t *mem_ptr, 1331 uint32_t start_stage, 1332 uint32_t end_stage) 1333{ 1334 struct pvr_descriptor_size_info size_info; 1335 bool is_dynamic; 1336 1337 is_dynamic = (binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) || 1338 (binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC); 1339 1340 pvr_descriptor_size_info_init(device, binding->type, &size_info); 1341 1342 for (uint32_t i = 0; i < write_set->descriptorCount; i++) { 1343 const VkDescriptorBufferInfo *buffer_info = &write_set->pBufferInfo[i]; 1344 PVR_FROM_HANDLE(pvr_buffer, buffer, buffer_info->buffer); 1345 const uint32_t desc_idx = 1346 binding->descriptor_index + write_set->dstArrayElement + i; 1347 const pvr_dev_addr_t addr = 1348 PVR_DEV_ADDR_OFFSET(buffer->dev_addr, buffer_info->offset); 1349 uint32_t range = (buffer_info->range == VK_WHOLE_SIZE) 1350 ? (buffer->vk.size - buffer_info->offset) 1351 : (buffer_info->range); 1352 1353 set->descriptors[desc_idx].type = write_set->descriptorType; 1354 set->descriptors[desc_idx].buffer_dev_addr = addr; 1355 set->descriptors[desc_idx].buffer_create_info_size = buffer->vk.size; 1356 set->descriptors[desc_idx].buffer_desc_range = range; 1357 1358 if (is_dynamic) 1359 continue; 1360 1361 /* Update the entries in the descriptor memory for static buffer. */ 1362 for (uint32_t j = start_stage; j < end_stage; j++) { 1363 uint32_t primary_offset; 1364 uint32_t secondary_offset; 1365 1366 if (!(binding->shader_stage_mask & BITFIELD_BIT(j))) 1367 continue; 1368 1369 /* Offset calculation functions expect descriptor_index to be 1370 * binding relative not layout relative, so we have used 1371 * write_set->dstArrayElement + i rather than desc_idx. 1372 */ 1373 primary_offset = 1374 pvr_get_descriptor_primary_offset(device, 1375 set->layout, 1376 binding, 1377 j, 1378 write_set->dstArrayElement + i); 1379 secondary_offset = 1380 pvr_get_descriptor_secondary_offset(device, 1381 set->layout, 1382 binding, 1383 j, 1384 write_set->dstArrayElement + i); 1385 1386 memcpy(mem_ptr + primary_offset, &addr, size_info.primary << 2); 1387 memcpy(mem_ptr + secondary_offset, &range, size_info.secondary << 2); 1388 } 1389 } 1390} 1391 1392static void pvr_descriptor_update_sampler( 1393 const struct pvr_device *device, 1394 const VkWriteDescriptorSet *write_set, 1395 struct pvr_descriptor_set *set, 1396 const struct pvr_descriptor_set_layout_binding *binding, 1397 uint32_t *mem_ptr, 1398 uint32_t start_stage, 1399 uint32_t end_stage) 1400{ 1401 struct pvr_descriptor_size_info size_info; 1402 1403 pvr_descriptor_size_info_init(device, binding->type, &size_info); 1404 1405 for (uint32_t i = 0; i < write_set->descriptorCount; i++) { 1406 PVR_FROM_HANDLE(pvr_sampler, sampler, write_set->pImageInfo[i].sampler); 1407 const uint32_t desc_idx = 1408 binding->descriptor_index + write_set->dstArrayElement + i; 1409 1410 set->descriptors[desc_idx].type = write_set->descriptorType; 1411 set->descriptors[desc_idx].sampler = sampler; 1412 1413 for (uint32_t j = start_stage; j < end_stage; j++) { 1414 uint32_t primary_offset; 1415 1416 if (!(binding->shader_stage_mask & BITFIELD_BIT(j))) 1417 continue; 1418 1419 /* Offset calculation functions expect descriptor_index to be binding 1420 * relative not layout relative, so we have used 1421 * write_set->dstArrayElement + i rather than desc_idx. 1422 */ 1423 primary_offset = 1424 pvr_get_descriptor_primary_offset(device, 1425 set->layout, 1426 binding, 1427 j, 1428 write_set->dstArrayElement + i); 1429 1430 memcpy(mem_ptr + primary_offset, 1431 sampler->descriptor.words, 1432 sizeof(sampler->descriptor.words)); 1433 } 1434 } 1435} 1436 1437static void 1438pvr_write_image_descriptor_primaries(const struct pvr_device_info *dev_info, 1439 const struct pvr_image_view *iview, 1440 VkDescriptorType descriptorType, 1441 uint32_t *primary) 1442{ 1443 uint64_t *qword_ptr = (uint64_t *)primary; 1444 1445 if (descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE && 1446 (iview->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE || 1447 iview->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)) { 1448 qword_ptr[0] = iview->texture_state[PVR_TEXTURE_STATE_STORAGE][0]; 1449 qword_ptr[1] = iview->texture_state[PVR_TEXTURE_STATE_STORAGE][1]; 1450 } else if (descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) { 1451 qword_ptr[0] = iview->texture_state[PVR_TEXTURE_STATE_ATTACHMENT][0]; 1452 qword_ptr[1] = iview->texture_state[PVR_TEXTURE_STATE_ATTACHMENT][1]; 1453 } else { 1454 qword_ptr[0] = iview->texture_state[PVR_TEXTURE_STATE_SAMPLE][0]; 1455 qword_ptr[1] = iview->texture_state[PVR_TEXTURE_STATE_SAMPLE][1]; 1456 } 1457 1458 if (descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE && 1459 !PVR_HAS_FEATURE(dev_info, tpu_extended_integer_lookup)) { 1460 uint64_t tmp; 1461 1462 pvr_csb_pack (&tmp, TEXSTATE_STRIDE_IMAGE_WORD1, word1) { 1463 word1.index_lookup = true; 1464 } 1465 1466 qword_ptr[1] |= tmp; 1467 } 1468} 1469 1470static void 1471pvr_write_image_descriptor_secondaries(const struct pvr_device_info *dev_info, 1472 const struct pvr_image_view *iview, 1473 VkDescriptorType descriptorType, 1474 uint32_t *secondary) 1475{ 1476 const bool cube_array_adjust = 1477 descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE && 1478 iview->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; 1479 1480 if (!PVR_HAS_FEATURE(dev_info, tpu_array_textures)) { 1481 uint64_t addr = iview->image->dev_addr.addr + 1482 iview->vk.base_array_layer * iview->image->layer_size; 1483 1484 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYBASE] = (uint32_t)addr; 1485 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYBASE + 1U] = 1486 (uint32_t)(addr >> 32U); 1487 1488 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYSTRIDE] = 1489 cube_array_adjust ? iview->image->layer_size * 6 1490 : iview->image->layer_size; 1491 } 1492 1493 if (cube_array_adjust) { 1494 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYMAXINDEX(dev_info)] = 1495 iview->vk.layer_count / 6 - 1; 1496 } else { 1497 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_ARRAYMAXINDEX(dev_info)] = 1498 iview->vk.layer_count - 1; 1499 } 1500 1501 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_WIDTH(dev_info)] = 1502 iview->vk.extent.width; 1503 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_HEIGHT(dev_info)] = 1504 iview->vk.extent.height; 1505 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_DEPTH(dev_info)] = 1506 iview->vk.extent.depth; 1507} 1508 1509static void pvr_descriptor_update_sampler_texture( 1510 const struct pvr_device *device, 1511 const VkWriteDescriptorSet *write_set, 1512 struct pvr_descriptor_set *set, 1513 const struct pvr_descriptor_set_layout_binding *binding, 1514 uint32_t *mem_ptr, 1515 uint32_t start_stage, 1516 uint32_t end_stage) 1517{ 1518 const struct pvr_device_info *dev_info = &device->pdevice->dev_info; 1519 1520 for (uint32_t i = 0; i < write_set->descriptorCount; i++) { 1521 PVR_FROM_HANDLE(pvr_image_view, 1522 iview, 1523 write_set->pImageInfo[i].imageView); 1524 const uint32_t desc_idx = 1525 binding->descriptor_index + write_set->dstArrayElement + i; 1526 1527 set->descriptors[desc_idx].type = write_set->descriptorType; 1528 set->descriptors[desc_idx].iview = iview; 1529 set->descriptors[desc_idx].layout = write_set->pImageInfo[i].imageLayout; 1530 1531 for (uint32_t j = start_stage; j < end_stage; j++) { 1532 uint32_t secondary_offset; 1533 uint32_t primary_offset; 1534 1535 if (!(binding->shader_stage_mask & BITFIELD_BIT(j))) 1536 continue; 1537 1538 /* Offset calculation functions expect descriptor_index to be 1539 * binding relative not layout relative, so we have used 1540 * write_set->dstArrayElement + i rather than desc_idx. 1541 */ 1542 primary_offset = 1543 pvr_get_descriptor_primary_offset(device, 1544 set->layout, 1545 binding, 1546 j, 1547 write_set->dstArrayElement + i); 1548 secondary_offset = 1549 pvr_get_descriptor_secondary_offset(device, 1550 set->layout, 1551 binding, 1552 j, 1553 write_set->dstArrayElement + i); 1554 1555 pvr_write_image_descriptor_primaries(dev_info, 1556 iview, 1557 write_set->descriptorType, 1558 mem_ptr + primary_offset); 1559 1560 /* We don't need to update the sampler words if they belong to an 1561 * immutable sampler. 1562 */ 1563 if (!binding->has_immutable_samplers) { 1564 PVR_FROM_HANDLE(pvr_sampler, 1565 sampler, 1566 write_set->pImageInfo[i].sampler); 1567 set->descriptors[desc_idx].sampler = sampler; 1568 1569 /* Sampler words are located at the end of the primary image words. 1570 */ 1571 memcpy(mem_ptr + primary_offset + PVR_IMAGE_DESCRIPTOR_SIZE, 1572 sampler->descriptor.words, 1573 sizeof(sampler->descriptor.words)); 1574 } 1575 1576 pvr_write_image_descriptor_secondaries(dev_info, 1577 iview, 1578 write_set->descriptorType, 1579 mem_ptr + secondary_offset); 1580 } 1581 } 1582} 1583 1584static void pvr_descriptor_update_texture( 1585 const struct pvr_device *device, 1586 const VkWriteDescriptorSet *write_set, 1587 struct pvr_descriptor_set *set, 1588 const struct pvr_descriptor_set_layout_binding *binding, 1589 uint32_t *mem_ptr, 1590 uint32_t start_stage, 1591 uint32_t end_stage) 1592{ 1593 const struct pvr_device_info *dev_info = &device->pdevice->dev_info; 1594 1595 for (uint32_t i = 0; i < write_set->descriptorCount; i++) { 1596 PVR_FROM_HANDLE(pvr_image_view, 1597 iview, 1598 write_set->pImageInfo[i].imageView); 1599 const uint32_t desc_idx = 1600 binding->descriptor_index + write_set->dstArrayElement + i; 1601 1602 set->descriptors[desc_idx].type = write_set->descriptorType; 1603 set->descriptors[desc_idx].iview = iview; 1604 set->descriptors[desc_idx].layout = write_set->pImageInfo[i].imageLayout; 1605 1606 for (uint32_t j = start_stage; j < end_stage; j++) { 1607 uint32_t secondary_offset; 1608 uint32_t primary_offset; 1609 1610 if (!(binding->shader_stage_mask & BITFIELD_BIT(j))) 1611 continue; 1612 1613 /* Offset calculation functions expect descriptor_index to be 1614 * binding relative not layout relative, so we have used 1615 * write_set->dstArrayElement + i rather than desc_idx. 1616 */ 1617 primary_offset = 1618 pvr_get_descriptor_primary_offset(device, 1619 set->layout, 1620 binding, 1621 j, 1622 write_set->dstArrayElement + i); 1623 secondary_offset = 1624 pvr_get_descriptor_secondary_offset(device, 1625 set->layout, 1626 binding, 1627 j, 1628 write_set->dstArrayElement + i); 1629 1630 pvr_write_image_descriptor_primaries(dev_info, 1631 iview, 1632 write_set->descriptorType, 1633 mem_ptr + primary_offset); 1634 1635 pvr_write_image_descriptor_secondaries(dev_info, 1636 iview, 1637 write_set->descriptorType, 1638 mem_ptr + secondary_offset); 1639 } 1640 } 1641} 1642 1643static void pvr_write_buffer_descriptor(const struct pvr_device_info *dev_info, 1644 const struct pvr_buffer_view *bview, 1645 VkDescriptorType descriptorType, 1646 uint32_t *primary, 1647 uint32_t *secondary) 1648{ 1649 uint64_t *qword_ptr = (uint64_t *)primary; 1650 1651 qword_ptr[0] = bview->texture_state[0]; 1652 qword_ptr[1] = bview->texture_state[1]; 1653 1654 if (descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER && 1655 !PVR_HAS_FEATURE(dev_info, tpu_extended_integer_lookup)) { 1656 uint64_t tmp; 1657 1658 pvr_csb_pack (&tmp, TEXSTATE_STRIDE_IMAGE_WORD1, word1) { 1659 word1.index_lookup = true; 1660 } 1661 1662 qword_ptr[1] |= tmp; 1663 } 1664 1665 if (secondary) { 1666 /* NOTE: Range check for texture buffer writes is not strictly required as 1667 * we have already validated that the index is in range. We'd need a 1668 * compiler change to allow us to skip the range check. 1669 */ 1670 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_WIDTH(dev_info)] = 1671 (uint32_t)(bview->range / vk_format_get_blocksize(bview->format)); 1672 secondary[PVR_DESC_IMAGE_SECONDARY_OFFSET_HEIGHT(dev_info)] = 1; 1673 } 1674} 1675 1676static void pvr_descriptor_update_buffer_view( 1677 const struct pvr_device *device, 1678 const VkWriteDescriptorSet *write_set, 1679 struct pvr_descriptor_set *set, 1680 const struct pvr_descriptor_set_layout_binding *binding, 1681 uint32_t *mem_ptr, 1682 uint32_t start_stage, 1683 uint32_t end_stage) 1684{ 1685 const struct pvr_device_info *dev_info = &device->pdevice->dev_info; 1686 struct pvr_descriptor_size_info size_info; 1687 1688 pvr_descriptor_size_info_init(device, binding->type, &size_info); 1689 1690 for (uint32_t i = 0; i < write_set->descriptorCount; i++) { 1691 PVR_FROM_HANDLE(pvr_buffer_view, bview, write_set->pTexelBufferView[i]); 1692 const uint32_t desc_idx = 1693 binding->descriptor_index + write_set->dstArrayElement + i; 1694 1695 set->descriptors[desc_idx].type = write_set->descriptorType; 1696 set->descriptors[desc_idx].bview = bview; 1697 1698 for (uint32_t j = start_stage; j < end_stage; j++) { 1699 uint32_t secondary_offset; 1700 uint32_t primary_offset; 1701 1702 if (!(binding->shader_stage_mask & BITFIELD_BIT(j))) 1703 continue; 1704 1705 /* Offset calculation functions expect descriptor_index to be 1706 * binding relative not layout relative, so we have used 1707 * write_set->dstArrayElement + i rather than desc_idx. 1708 */ 1709 primary_offset = 1710 pvr_get_descriptor_primary_offset(device, 1711 set->layout, 1712 binding, 1713 j, 1714 write_set->dstArrayElement + i); 1715 secondary_offset = 1716 pvr_get_descriptor_secondary_offset(device, 1717 set->layout, 1718 binding, 1719 j, 1720 write_set->dstArrayElement + i); 1721 1722 pvr_write_buffer_descriptor( 1723 dev_info, 1724 bview, 1725 write_set->descriptorType, 1726 mem_ptr + primary_offset, 1727 size_info.secondary ? mem_ptr + secondary_offset : NULL); 1728 } 1729 } 1730} 1731 1732static void pvr_descriptor_update_input_attachment( 1733 const struct pvr_device *device, 1734 const VkWriteDescriptorSet *write_set, 1735 struct pvr_descriptor_set *set, 1736 const struct pvr_descriptor_set_layout_binding *binding, 1737 uint32_t *mem_ptr, 1738 uint32_t start_stage, 1739 uint32_t end_stage) 1740{ 1741 const struct pvr_device_info *dev_info = &device->pdevice->dev_info; 1742 struct pvr_descriptor_size_info size_info; 1743 1744 pvr_descriptor_size_info_init(device, binding->type, &size_info); 1745 1746 for (uint32_t i = 0; i < write_set->descriptorCount; i++) { 1747 PVR_FROM_HANDLE(pvr_image_view, 1748 iview, 1749 write_set->pImageInfo[i].imageView); 1750 const uint32_t desc_idx = 1751 binding->descriptor_index + write_set->dstArrayElement + i; 1752 1753 set->descriptors[desc_idx].type = write_set->descriptorType; 1754 set->descriptors[desc_idx].iview = iview; 1755 set->descriptors[desc_idx].layout = write_set->pImageInfo[i].imageLayout; 1756 1757 for (uint32_t j = start_stage; j < end_stage; j++) { 1758 uint32_t primary_offset; 1759 1760 if (!(binding->shader_stage_mask & BITFIELD_BIT(j))) 1761 continue; 1762 1763 /* Offset calculation functions expect descriptor_index to be 1764 * binding relative not layout relative, so we have used 1765 * write_set->dstArrayElement + i rather than desc_idx. 1766 */ 1767 primary_offset = 1768 pvr_get_descriptor_primary_offset(device, 1769 set->layout, 1770 binding, 1771 j, 1772 write_set->dstArrayElement + i); 1773 1774 pvr_write_image_descriptor_primaries(dev_info, 1775 iview, 1776 write_set->descriptorType, 1777 mem_ptr + primary_offset); 1778 1779 *(uint64_t *)(mem_ptr + primary_offset + PVR_IMAGE_DESCRIPTOR_SIZE) = 1780 device->input_attachment_sampler; 1781 1782 if (!PVR_HAS_FEATURE(dev_info, tpu_array_textures)) { 1783 const uint32_t secondary_offset = 1784 pvr_get_descriptor_secondary_offset(device, 1785 set->layout, 1786 binding, 1787 j, 1788 write_set->dstArrayElement + 1789 i); 1790 1791 pvr_write_image_descriptor_secondaries(dev_info, 1792 iview, 1793 write_set->descriptorType, 1794 mem_ptr + secondary_offset); 1795 } 1796 } 1797 } 1798} 1799 1800void pvr_UpdateDescriptorSets(VkDevice _device, 1801 uint32_t descriptorWriteCount, 1802 const VkWriteDescriptorSet *pDescriptorWrites, 1803 uint32_t descriptorCopyCount, 1804 const VkCopyDescriptorSet *pDescriptorCopies) 1805{ 1806 PVR_FROM_HANDLE(pvr_device, device, _device); 1807 1808 for (uint32_t i = 0; i < descriptorWriteCount; i++) { 1809 const VkWriteDescriptorSet *write_set = &pDescriptorWrites[i]; 1810 PVR_FROM_HANDLE(pvr_descriptor_set, set, write_set->dstSet); 1811 uint32_t *map = set->pvr_bo->bo->map; 1812 const struct pvr_descriptor_set_layout_binding *binding = 1813 pvr_get_descriptor_binding(set->layout, write_set->dstBinding); 1814 1815 /* Binding should not be NULL. */ 1816 assert(binding); 1817 1818 /* Only need to update the descriptor if it is actually being used. If it 1819 * was not used in any stage, then the shader_stage_mask would be 0 and we 1820 * can skip this update. 1821 */ 1822 if (binding->shader_stage_mask == 0) 1823 continue; 1824 1825 vk_foreach_struct_const (ext, write_set->pNext) { 1826 pvr_debug_ignored_stype(ext->sType); 1827 } 1828 1829 switch (write_set->descriptorType) { 1830 case VK_DESCRIPTOR_TYPE_SAMPLER: 1831 pvr_descriptor_update_sampler(device, 1832 write_set, 1833 set, 1834 binding, 1835 map, 1836 0, 1837 PVR_STAGE_ALLOCATION_COUNT); 1838 break; 1839 1840 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 1841 pvr_descriptor_update_sampler_texture(device, 1842 write_set, 1843 set, 1844 binding, 1845 map, 1846 0, 1847 PVR_STAGE_ALLOCATION_COUNT); 1848 break; 1849 1850 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 1851 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 1852 pvr_descriptor_update_texture(device, 1853 write_set, 1854 set, 1855 binding, 1856 map, 1857 0, 1858 PVR_STAGE_ALLOCATION_COUNT); 1859 break; 1860 1861 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 1862 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 1863 pvr_descriptor_update_buffer_view(device, 1864 write_set, 1865 set, 1866 binding, 1867 map, 1868 0, 1869 PVR_STAGE_ALLOCATION_COUNT); 1870 break; 1871 1872 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 1873 pvr_descriptor_update_input_attachment(device, 1874 write_set, 1875 set, 1876 binding, 1877 map, 1878 0, 1879 PVR_STAGE_ALLOCATION_COUNT); 1880 break; 1881 1882 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 1883 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 1884 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 1885 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 1886 pvr_descriptor_update_buffer_info(device, 1887 write_set, 1888 set, 1889 binding, 1890 map, 1891 0, 1892 PVR_STAGE_ALLOCATION_COUNT); 1893 break; 1894 1895 default: 1896 unreachable("Unknown descriptor type"); 1897 break; 1898 } 1899 } 1900 1901 if (descriptorCopyCount > 0) 1902 pvr_finishme("Descriptor copying support missing\n"); 1903} 1904