1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2016 Red Hat. 3bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci * Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22bf215546Sopenharmony_ci * IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci#include <assert.h> 25bf215546Sopenharmony_ci#include <fcntl.h> 26bf215546Sopenharmony_ci#include <stdbool.h> 27bf215546Sopenharmony_ci#include <string.h> 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "util/mesa-sha1.h" 30bf215546Sopenharmony_ci#include "radv_private.h" 31bf215546Sopenharmony_ci#include "sid.h" 32bf215546Sopenharmony_ci#include "vk_descriptors.h" 33bf215546Sopenharmony_ci#include "vk_format.h" 34bf215546Sopenharmony_ci#include "vk_util.h" 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_cistatic unsigned 37bf215546Sopenharmony_ciradv_descriptor_type_buffer_count(VkDescriptorType type) 38bf215546Sopenharmony_ci{ 39bf215546Sopenharmony_ci switch (type) { 40bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 41bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: 42bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: 43bf215546Sopenharmony_ci return 0; 44bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 45bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 46bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 47bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 48bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE: 49bf215546Sopenharmony_ci return 3; 50bf215546Sopenharmony_ci default: 51bf215546Sopenharmony_ci return 1; 52bf215546Sopenharmony_ci } 53bf215546Sopenharmony_ci} 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_cistatic bool 56bf215546Sopenharmony_cihas_equal_immutable_samplers(const VkSampler *samplers, uint32_t count) 57bf215546Sopenharmony_ci{ 58bf215546Sopenharmony_ci if (!samplers) 59bf215546Sopenharmony_ci return false; 60bf215546Sopenharmony_ci for (uint32_t i = 1; i < count; ++i) { 61bf215546Sopenharmony_ci if (memcmp(radv_sampler_from_handle(samplers[0])->state, 62bf215546Sopenharmony_ci radv_sampler_from_handle(samplers[i])->state, 16)) { 63bf215546Sopenharmony_ci return false; 64bf215546Sopenharmony_ci } 65bf215546Sopenharmony_ci } 66bf215546Sopenharmony_ci return true; 67bf215546Sopenharmony_ci} 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_cistatic bool 70bf215546Sopenharmony_ciradv_mutable_descriptor_type_size_alignment(const VkMutableDescriptorTypeListVALVE *list, 71bf215546Sopenharmony_ci uint64_t *out_size, uint64_t *out_align) 72bf215546Sopenharmony_ci{ 73bf215546Sopenharmony_ci uint32_t max_size = 0; 74bf215546Sopenharmony_ci uint32_t max_align = 0; 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci for (uint32_t i = 0; i < list->descriptorTypeCount; i++) { 77bf215546Sopenharmony_ci uint32_t size = 0; 78bf215546Sopenharmony_ci uint32_t align = 0; 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci switch (list->pDescriptorTypes[i]) { 81bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 82bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 83bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 84bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 85bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 86bf215546Sopenharmony_ci size = 16; 87bf215546Sopenharmony_ci align = 16; 88bf215546Sopenharmony_ci break; 89bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 90bf215546Sopenharmony_ci size = 32; 91bf215546Sopenharmony_ci align = 32; 92bf215546Sopenharmony_ci break; 93bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 94bf215546Sopenharmony_ci size = 64; 95bf215546Sopenharmony_ci align = 32; 96bf215546Sopenharmony_ci break; 97bf215546Sopenharmony_ci default: 98bf215546Sopenharmony_ci return false; 99bf215546Sopenharmony_ci } 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci max_size = MAX2(max_size, size); 102bf215546Sopenharmony_ci max_align = MAX2(max_align, align); 103bf215546Sopenharmony_ci } 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci *out_size = max_size; 106bf215546Sopenharmony_ci *out_align = max_align; 107bf215546Sopenharmony_ci return true; 108bf215546Sopenharmony_ci} 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 111bf215546Sopenharmony_ciradv_CreateDescriptorSetLayout(VkDevice _device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, 112bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 113bf215546Sopenharmony_ci VkDescriptorSetLayout *pSetLayout) 114bf215546Sopenharmony_ci{ 115bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 116bf215546Sopenharmony_ci struct radv_descriptor_set_layout *set_layout; 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO); 119bf215546Sopenharmony_ci const VkDescriptorSetLayoutBindingFlagsCreateInfo *variable_flags = 120bf215546Sopenharmony_ci vk_find_struct_const(pCreateInfo->pNext, DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO); 121bf215546Sopenharmony_ci const VkMutableDescriptorTypeCreateInfoVALVE *mutable_info = 122bf215546Sopenharmony_ci vk_find_struct_const(pCreateInfo->pNext, MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE); 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci uint32_t num_bindings = 0; 125bf215546Sopenharmony_ci uint32_t immutable_sampler_count = 0; 126bf215546Sopenharmony_ci uint32_t ycbcr_sampler_count = 0; 127bf215546Sopenharmony_ci for (uint32_t j = 0; j < pCreateInfo->bindingCount; j++) { 128bf215546Sopenharmony_ci num_bindings = MAX2(num_bindings, pCreateInfo->pBindings[j].binding + 1); 129bf215546Sopenharmony_ci if ((pCreateInfo->pBindings[j].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || 130bf215546Sopenharmony_ci pCreateInfo->pBindings[j].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) && 131bf215546Sopenharmony_ci pCreateInfo->pBindings[j].pImmutableSamplers) { 132bf215546Sopenharmony_ci immutable_sampler_count += pCreateInfo->pBindings[j].descriptorCount; 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci bool has_ycbcr_sampler = false; 135bf215546Sopenharmony_ci for (unsigned i = 0; i < pCreateInfo->pBindings[j].descriptorCount; ++i) { 136bf215546Sopenharmony_ci if (radv_sampler_from_handle(pCreateInfo->pBindings[j].pImmutableSamplers[i]) 137bf215546Sopenharmony_ci ->ycbcr_sampler) 138bf215546Sopenharmony_ci has_ycbcr_sampler = true; 139bf215546Sopenharmony_ci } 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci if (has_ycbcr_sampler) 142bf215546Sopenharmony_ci ycbcr_sampler_count += pCreateInfo->pBindings[j].descriptorCount; 143bf215546Sopenharmony_ci } 144bf215546Sopenharmony_ci } 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci uint32_t samplers_offset = offsetof(struct radv_descriptor_set_layout, binding[num_bindings]); 147bf215546Sopenharmony_ci size_t size = samplers_offset + immutable_sampler_count * 4 * sizeof(uint32_t); 148bf215546Sopenharmony_ci if (ycbcr_sampler_count > 0) { 149bf215546Sopenharmony_ci /* Store block of offsets first, followed by the conversion descriptors (padded to the struct 150bf215546Sopenharmony_ci * alignment) */ 151bf215546Sopenharmony_ci size += num_bindings * sizeof(uint32_t); 152bf215546Sopenharmony_ci size = ALIGN(size, alignof(struct radv_sampler_ycbcr_conversion_state)); 153bf215546Sopenharmony_ci size += ycbcr_sampler_count * sizeof(struct radv_sampler_ycbcr_conversion_state); 154bf215546Sopenharmony_ci } 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci /* We need to allocate decriptor set layouts off the device allocator with DEVICE scope because 157bf215546Sopenharmony_ci * they are reference counted and may not be destroyed when vkDestroyDescriptorSetLayout is 158bf215546Sopenharmony_ci * called. 159bf215546Sopenharmony_ci */ 160bf215546Sopenharmony_ci set_layout = vk_descriptor_set_layout_zalloc(&device->vk, size); 161bf215546Sopenharmony_ci if (!set_layout) 162bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci set_layout->flags = pCreateInfo->flags; 165bf215546Sopenharmony_ci set_layout->layout_size = size; 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci /* We just allocate all the samplers at the end of the struct */ 168bf215546Sopenharmony_ci uint32_t *samplers = (uint32_t *)&set_layout->binding[num_bindings]; 169bf215546Sopenharmony_ci struct radv_sampler_ycbcr_conversion_state *ycbcr_samplers = NULL; 170bf215546Sopenharmony_ci uint32_t *ycbcr_sampler_offsets = NULL; 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci if (ycbcr_sampler_count > 0) { 173bf215546Sopenharmony_ci ycbcr_sampler_offsets = samplers + 4 * immutable_sampler_count; 174bf215546Sopenharmony_ci set_layout->ycbcr_sampler_offsets_offset = (char *)ycbcr_sampler_offsets - (char *)set_layout; 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci uintptr_t first_ycbcr_sampler_offset = 177bf215546Sopenharmony_ci (uintptr_t)ycbcr_sampler_offsets + sizeof(uint32_t) * num_bindings; 178bf215546Sopenharmony_ci first_ycbcr_sampler_offset = 179bf215546Sopenharmony_ci ALIGN(first_ycbcr_sampler_offset, alignof(struct radv_sampler_ycbcr_conversion_state)); 180bf215546Sopenharmony_ci ycbcr_samplers = (struct radv_sampler_ycbcr_conversion_state *)first_ycbcr_sampler_offset; 181bf215546Sopenharmony_ci } else 182bf215546Sopenharmony_ci set_layout->ycbcr_sampler_offsets_offset = 0; 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci VkDescriptorSetLayoutBinding *bindings = NULL; 185bf215546Sopenharmony_ci VkResult result = 186bf215546Sopenharmony_ci vk_create_sorted_bindings(pCreateInfo->pBindings, pCreateInfo->bindingCount, &bindings); 187bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 188bf215546Sopenharmony_ci vk_descriptor_set_layout_unref(&device->vk, &set_layout->vk); 189bf215546Sopenharmony_ci return vk_error(device, result); 190bf215546Sopenharmony_ci } 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci set_layout->binding_count = num_bindings; 193bf215546Sopenharmony_ci set_layout->shader_stages = 0; 194bf215546Sopenharmony_ci set_layout->dynamic_shader_stages = 0; 195bf215546Sopenharmony_ci set_layout->has_immutable_samplers = false; 196bf215546Sopenharmony_ci set_layout->size = 0; 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci uint32_t buffer_count = 0; 199bf215546Sopenharmony_ci uint32_t dynamic_offset_count = 0; 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci for (uint32_t j = 0; j < pCreateInfo->bindingCount; j++) { 202bf215546Sopenharmony_ci const VkDescriptorSetLayoutBinding *binding = bindings + j; 203bf215546Sopenharmony_ci uint32_t b = binding->binding; 204bf215546Sopenharmony_ci uint32_t alignment = 0; 205bf215546Sopenharmony_ci unsigned binding_buffer_count = 206bf215546Sopenharmony_ci radv_descriptor_type_buffer_count(binding->descriptorType); 207bf215546Sopenharmony_ci uint32_t descriptor_count = binding->descriptorCount; 208bf215546Sopenharmony_ci bool has_ycbcr_sampler = false; 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci /* main image + fmask */ 211bf215546Sopenharmony_ci uint32_t max_sampled_image_descriptors = 2; 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci if (binding->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER && 214bf215546Sopenharmony_ci binding->pImmutableSamplers) { 215bf215546Sopenharmony_ci for (unsigned i = 0; i < binding->descriptorCount; ++i) { 216bf215546Sopenharmony_ci struct radv_sampler_ycbcr_conversion *conversion = 217bf215546Sopenharmony_ci radv_sampler_from_handle(binding->pImmutableSamplers[i])->ycbcr_sampler; 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci if (conversion) { 220bf215546Sopenharmony_ci has_ycbcr_sampler = true; 221bf215546Sopenharmony_ci max_sampled_image_descriptors = MAX2(max_sampled_image_descriptors, 222bf215546Sopenharmony_ci vk_format_get_plane_count(conversion->state.format)); 223bf215546Sopenharmony_ci } 224bf215546Sopenharmony_ci } 225bf215546Sopenharmony_ci } 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci switch (binding->descriptorType) { 228bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 229bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 230bf215546Sopenharmony_ci assert(!(pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)); 231bf215546Sopenharmony_ci set_layout->binding[b].dynamic_offset_count = 1; 232bf215546Sopenharmony_ci set_layout->dynamic_shader_stages |= binding->stageFlags; 233bf215546Sopenharmony_ci if (binding->stageFlags & RADV_RT_STAGE_BITS) 234bf215546Sopenharmony_ci set_layout->dynamic_shader_stages |= VK_SHADER_STAGE_COMPUTE_BIT; 235bf215546Sopenharmony_ci set_layout->binding[b].size = 0; 236bf215546Sopenharmony_ci alignment = 1; 237bf215546Sopenharmony_ci break; 238bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 239bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 240bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 241bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 242bf215546Sopenharmony_ci set_layout->binding[b].size = 16; 243bf215546Sopenharmony_ci alignment = 16; 244bf215546Sopenharmony_ci break; 245bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 246bf215546Sopenharmony_ci set_layout->binding[b].size = 32; 247bf215546Sopenharmony_ci alignment = 32; 248bf215546Sopenharmony_ci break; 249bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 250bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 251bf215546Sopenharmony_ci /* main descriptor + fmask descriptor */ 252bf215546Sopenharmony_ci set_layout->binding[b].size = 64; 253bf215546Sopenharmony_ci alignment = 32; 254bf215546Sopenharmony_ci break; 255bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 256bf215546Sopenharmony_ci /* main descriptor + fmask descriptor + sampler */ 257bf215546Sopenharmony_ci set_layout->binding[b].size = 96; 258bf215546Sopenharmony_ci alignment = 32; 259bf215546Sopenharmony_ci break; 260bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 261bf215546Sopenharmony_ci set_layout->binding[b].size = 16; 262bf215546Sopenharmony_ci alignment = 16; 263bf215546Sopenharmony_ci break; 264bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE: { 265bf215546Sopenharmony_ci uint64_t mutable_size = 0, mutable_align = 0; 266bf215546Sopenharmony_ci radv_mutable_descriptor_type_size_alignment(&mutable_info->pMutableDescriptorTypeLists[j], 267bf215546Sopenharmony_ci &mutable_size, &mutable_align); 268bf215546Sopenharmony_ci assert(mutable_size && mutable_align); 269bf215546Sopenharmony_ci set_layout->binding[b].size = mutable_size; 270bf215546Sopenharmony_ci alignment = mutable_align; 271bf215546Sopenharmony_ci break; 272bf215546Sopenharmony_ci } 273bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: 274bf215546Sopenharmony_ci alignment = 16; 275bf215546Sopenharmony_ci set_layout->binding[b].size = descriptor_count; 276bf215546Sopenharmony_ci descriptor_count = 1; 277bf215546Sopenharmony_ci break; 278bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: 279bf215546Sopenharmony_ci set_layout->binding[b].size = 16; 280bf215546Sopenharmony_ci alignment = 16; 281bf215546Sopenharmony_ci break; 282bf215546Sopenharmony_ci default: 283bf215546Sopenharmony_ci break; 284bf215546Sopenharmony_ci } 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_ci set_layout->size = align(set_layout->size, alignment); 287bf215546Sopenharmony_ci set_layout->binding[b].type = binding->descriptorType; 288bf215546Sopenharmony_ci set_layout->binding[b].array_size = descriptor_count; 289bf215546Sopenharmony_ci set_layout->binding[b].offset = set_layout->size; 290bf215546Sopenharmony_ci set_layout->binding[b].buffer_offset = buffer_count; 291bf215546Sopenharmony_ci set_layout->binding[b].dynamic_offset_offset = dynamic_offset_count; 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci if (variable_flags && binding->binding < variable_flags->bindingCount && 294bf215546Sopenharmony_ci (variable_flags->pBindingFlags[binding->binding] & 295bf215546Sopenharmony_ci VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT)) { 296bf215546Sopenharmony_ci assert( 297bf215546Sopenharmony_ci !binding->pImmutableSamplers); /* Terribly ill defined how many samplers are valid */ 298bf215546Sopenharmony_ci assert(binding->binding == num_bindings - 1); 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_ci set_layout->has_variable_descriptors = true; 301bf215546Sopenharmony_ci } 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci if ((binding->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || 304bf215546Sopenharmony_ci binding->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) && 305bf215546Sopenharmony_ci binding->pImmutableSamplers) { 306bf215546Sopenharmony_ci set_layout->binding[b].immutable_samplers_offset = samplers_offset; 307bf215546Sopenharmony_ci set_layout->binding[b].immutable_samplers_equal = 308bf215546Sopenharmony_ci has_equal_immutable_samplers(binding->pImmutableSamplers, binding->descriptorCount); 309bf215546Sopenharmony_ci set_layout->has_immutable_samplers = true; 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_ci for (uint32_t i = 0; i < binding->descriptorCount; i++) 312bf215546Sopenharmony_ci memcpy(samplers + 4 * i, 313bf215546Sopenharmony_ci &radv_sampler_from_handle(binding->pImmutableSamplers[i])->state, 16); 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci /* Don't reserve space for the samplers if they're not accessed. */ 316bf215546Sopenharmony_ci if (set_layout->binding[b].immutable_samplers_equal) { 317bf215546Sopenharmony_ci if (binding->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER && 318bf215546Sopenharmony_ci max_sampled_image_descriptors <= 2) 319bf215546Sopenharmony_ci set_layout->binding[b].size -= 32; 320bf215546Sopenharmony_ci else if (binding->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) 321bf215546Sopenharmony_ci set_layout->binding[b].size -= 16; 322bf215546Sopenharmony_ci } 323bf215546Sopenharmony_ci samplers += 4 * binding->descriptorCount; 324bf215546Sopenharmony_ci samplers_offset += 4 * sizeof(uint32_t) * binding->descriptorCount; 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci if (has_ycbcr_sampler) { 327bf215546Sopenharmony_ci ycbcr_sampler_offsets[b] = (const char *)ycbcr_samplers - (const char *)set_layout; 328bf215546Sopenharmony_ci for (uint32_t i = 0; i < binding->descriptorCount; i++) { 329bf215546Sopenharmony_ci if (radv_sampler_from_handle(binding->pImmutableSamplers[i])->ycbcr_sampler) 330bf215546Sopenharmony_ci ycbcr_samplers[i] = 331bf215546Sopenharmony_ci radv_sampler_from_handle(binding->pImmutableSamplers[i])->ycbcr_sampler->state; 332bf215546Sopenharmony_ci else 333bf215546Sopenharmony_ci ycbcr_samplers[i].format = VK_FORMAT_UNDEFINED; 334bf215546Sopenharmony_ci } 335bf215546Sopenharmony_ci ycbcr_samplers += binding->descriptorCount; 336bf215546Sopenharmony_ci } 337bf215546Sopenharmony_ci } 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci set_layout->size += descriptor_count * set_layout->binding[b].size; 340bf215546Sopenharmony_ci buffer_count += descriptor_count * binding_buffer_count; 341bf215546Sopenharmony_ci dynamic_offset_count += descriptor_count * set_layout->binding[b].dynamic_offset_count; 342bf215546Sopenharmony_ci set_layout->shader_stages |= binding->stageFlags; 343bf215546Sopenharmony_ci } 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci free(bindings); 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci set_layout->buffer_count = buffer_count; 348bf215546Sopenharmony_ci set_layout->dynamic_offset_count = dynamic_offset_count; 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci *pSetLayout = radv_descriptor_set_layout_to_handle(set_layout); 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci return VK_SUCCESS; 353bf215546Sopenharmony_ci} 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 356bf215546Sopenharmony_ciradv_GetDescriptorSetLayoutSupport(VkDevice device, 357bf215546Sopenharmony_ci const VkDescriptorSetLayoutCreateInfo *pCreateInfo, 358bf215546Sopenharmony_ci VkDescriptorSetLayoutSupport *pSupport) 359bf215546Sopenharmony_ci{ 360bf215546Sopenharmony_ci VkDescriptorSetLayoutBinding *bindings = NULL; 361bf215546Sopenharmony_ci VkResult result = 362bf215546Sopenharmony_ci vk_create_sorted_bindings(pCreateInfo->pBindings, pCreateInfo->bindingCount, &bindings); 363bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 364bf215546Sopenharmony_ci pSupport->supported = false; 365bf215546Sopenharmony_ci return; 366bf215546Sopenharmony_ci } 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci const VkDescriptorSetLayoutBindingFlagsCreateInfo *variable_flags = 369bf215546Sopenharmony_ci vk_find_struct_const(pCreateInfo->pNext, DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO); 370bf215546Sopenharmony_ci VkDescriptorSetVariableDescriptorCountLayoutSupport *variable_count = vk_find_struct( 371bf215546Sopenharmony_ci (void *)pCreateInfo->pNext, DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT); 372bf215546Sopenharmony_ci const VkMutableDescriptorTypeCreateInfoVALVE *mutable_info = 373bf215546Sopenharmony_ci vk_find_struct_const(pCreateInfo->pNext, MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE); 374bf215546Sopenharmony_ci if (variable_count) { 375bf215546Sopenharmony_ci variable_count->maxVariableDescriptorCount = 0; 376bf215546Sopenharmony_ci } 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci bool supported = true; 379bf215546Sopenharmony_ci uint64_t size = 0; 380bf215546Sopenharmony_ci for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) { 381bf215546Sopenharmony_ci const VkDescriptorSetLayoutBinding *binding = bindings + i; 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci uint64_t descriptor_size = 0; 384bf215546Sopenharmony_ci uint64_t descriptor_alignment = 1; 385bf215546Sopenharmony_ci uint32_t descriptor_count = binding->descriptorCount; 386bf215546Sopenharmony_ci switch (binding->descriptorType) { 387bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 388bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 389bf215546Sopenharmony_ci break; 390bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 391bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 392bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 393bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 394bf215546Sopenharmony_ci descriptor_size = 16; 395bf215546Sopenharmony_ci descriptor_alignment = 16; 396bf215546Sopenharmony_ci break; 397bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 398bf215546Sopenharmony_ci descriptor_size = 32; 399bf215546Sopenharmony_ci descriptor_alignment = 32; 400bf215546Sopenharmony_ci break; 401bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 402bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 403bf215546Sopenharmony_ci descriptor_size = 64; 404bf215546Sopenharmony_ci descriptor_alignment = 32; 405bf215546Sopenharmony_ci break; 406bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 407bf215546Sopenharmony_ci if (!has_equal_immutable_samplers(binding->pImmutableSamplers, descriptor_count)) { 408bf215546Sopenharmony_ci descriptor_size = 64; 409bf215546Sopenharmony_ci } else { 410bf215546Sopenharmony_ci descriptor_size = 96; 411bf215546Sopenharmony_ci } 412bf215546Sopenharmony_ci descriptor_alignment = 32; 413bf215546Sopenharmony_ci break; 414bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 415bf215546Sopenharmony_ci if (!has_equal_immutable_samplers(binding->pImmutableSamplers, descriptor_count)) { 416bf215546Sopenharmony_ci descriptor_size = 16; 417bf215546Sopenharmony_ci descriptor_alignment = 16; 418bf215546Sopenharmony_ci } 419bf215546Sopenharmony_ci break; 420bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: 421bf215546Sopenharmony_ci descriptor_alignment = 16; 422bf215546Sopenharmony_ci descriptor_size = descriptor_count; 423bf215546Sopenharmony_ci descriptor_count = 1; 424bf215546Sopenharmony_ci break; 425bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE: 426bf215546Sopenharmony_ci if (!radv_mutable_descriptor_type_size_alignment( 427bf215546Sopenharmony_ci &mutable_info->pMutableDescriptorTypeLists[i], &descriptor_size, 428bf215546Sopenharmony_ci &descriptor_alignment)) { 429bf215546Sopenharmony_ci supported = false; 430bf215546Sopenharmony_ci } 431bf215546Sopenharmony_ci break; 432bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: 433bf215546Sopenharmony_ci descriptor_size = 16; 434bf215546Sopenharmony_ci descriptor_alignment = 16; 435bf215546Sopenharmony_ci break; 436bf215546Sopenharmony_ci default: 437bf215546Sopenharmony_ci break; 438bf215546Sopenharmony_ci } 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci if (size && !align_u64(size, descriptor_alignment)) { 441bf215546Sopenharmony_ci supported = false; 442bf215546Sopenharmony_ci } 443bf215546Sopenharmony_ci size = align_u64(size, descriptor_alignment); 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_ci uint64_t max_count = INT32_MAX; 446bf215546Sopenharmony_ci if (binding->descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) 447bf215546Sopenharmony_ci max_count = INT32_MAX - size; 448bf215546Sopenharmony_ci else if (descriptor_size) 449bf215546Sopenharmony_ci max_count = (INT32_MAX - size) / descriptor_size; 450bf215546Sopenharmony_ci 451bf215546Sopenharmony_ci if (max_count < descriptor_count) { 452bf215546Sopenharmony_ci supported = false; 453bf215546Sopenharmony_ci } 454bf215546Sopenharmony_ci if (variable_flags && binding->binding < variable_flags->bindingCount && variable_count && 455bf215546Sopenharmony_ci (variable_flags->pBindingFlags[binding->binding] & 456bf215546Sopenharmony_ci VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT)) { 457bf215546Sopenharmony_ci variable_count->maxVariableDescriptorCount = MIN2(UINT32_MAX, max_count); 458bf215546Sopenharmony_ci } 459bf215546Sopenharmony_ci size += descriptor_count * descriptor_size; 460bf215546Sopenharmony_ci } 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_ci free(bindings); 463bf215546Sopenharmony_ci 464bf215546Sopenharmony_ci pSupport->supported = supported; 465bf215546Sopenharmony_ci} 466bf215546Sopenharmony_ci 467bf215546Sopenharmony_ci/* 468bf215546Sopenharmony_ci * Pipeline layouts. These have nothing to do with the pipeline. They are 469bf215546Sopenharmony_ci * just multiple descriptor set layouts pasted together. 470bf215546Sopenharmony_ci */ 471bf215546Sopenharmony_civoid 472bf215546Sopenharmony_ciradv_pipeline_layout_init(struct radv_device *device, struct radv_pipeline_layout *layout, 473bf215546Sopenharmony_ci bool independent_sets) 474bf215546Sopenharmony_ci{ 475bf215546Sopenharmony_ci memset(layout, 0, sizeof(*layout)); 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci vk_object_base_init(&device->vk, &layout->base, VK_OBJECT_TYPE_PIPELINE_LAYOUT); 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_ci layout->independent_sets = independent_sets; 480bf215546Sopenharmony_ci} 481bf215546Sopenharmony_ci 482bf215546Sopenharmony_civoid 483bf215546Sopenharmony_ciradv_pipeline_layout_add_set(struct radv_pipeline_layout *layout, uint32_t set_idx, 484bf215546Sopenharmony_ci struct radv_descriptor_set_layout *set_layout) 485bf215546Sopenharmony_ci{ 486bf215546Sopenharmony_ci unsigned dynamic_offset_count = 0; 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_ci if (layout->set[set_idx].layout) 489bf215546Sopenharmony_ci return; 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci layout->num_sets = MAX2(set_idx + 1, layout->num_sets); 492bf215546Sopenharmony_ci 493bf215546Sopenharmony_ci layout->set[set_idx].layout = set_layout; 494bf215546Sopenharmony_ci vk_descriptor_set_layout_ref(&set_layout->vk); 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci for (uint32_t b = 0; b < set_layout->binding_count; b++) { 497bf215546Sopenharmony_ci dynamic_offset_count += set_layout->binding[b].array_size * set_layout->binding[b].dynamic_offset_count; 498bf215546Sopenharmony_ci } 499bf215546Sopenharmony_ci 500bf215546Sopenharmony_ci layout->set[set_idx].dynamic_offset_start = layout->dynamic_offset_count; 501bf215546Sopenharmony_ci 502bf215546Sopenharmony_ci layout->dynamic_offset_count += dynamic_offset_count; 503bf215546Sopenharmony_ci layout->dynamic_shader_stages |= set_layout->dynamic_shader_stages; 504bf215546Sopenharmony_ci} 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_civoid 507bf215546Sopenharmony_ciradv_pipeline_layout_hash(struct radv_pipeline_layout *layout) 508bf215546Sopenharmony_ci{ 509bf215546Sopenharmony_ci struct mesa_sha1 ctx; 510bf215546Sopenharmony_ci 511bf215546Sopenharmony_ci _mesa_sha1_init(&ctx); 512bf215546Sopenharmony_ci for (uint32_t i = 0; i < layout->num_sets; i++) { 513bf215546Sopenharmony_ci struct radv_descriptor_set_layout *set_layout = layout->set[i].layout; 514bf215546Sopenharmony_ci 515bf215546Sopenharmony_ci if (!set_layout) 516bf215546Sopenharmony_ci continue; 517bf215546Sopenharmony_ci 518bf215546Sopenharmony_ci /* Hash the entire set layout except for the vk_object_base and the reference counter. The 519bf215546Sopenharmony_ci * rest of the set layout is carefully constructed to not have pointers so a full hash instead 520bf215546Sopenharmony_ci * of a per-field hash should be ok. 521bf215546Sopenharmony_ci */ 522bf215546Sopenharmony_ci uint32_t hash_offset = sizeof(struct vk_object_base) + sizeof(uint32_t); 523bf215546Sopenharmony_ci _mesa_sha1_update(&ctx, (const char *)set_layout + hash_offset, 524bf215546Sopenharmony_ci set_layout->layout_size - hash_offset); 525bf215546Sopenharmony_ci } 526bf215546Sopenharmony_ci _mesa_sha1_update(&ctx, &layout->push_constant_size, sizeof(layout->push_constant_size)); 527bf215546Sopenharmony_ci _mesa_sha1_final(&ctx, layout->sha1); 528bf215546Sopenharmony_ci} 529bf215546Sopenharmony_ci 530bf215546Sopenharmony_civoid 531bf215546Sopenharmony_ciradv_pipeline_layout_finish(struct radv_device *device, struct radv_pipeline_layout *layout) 532bf215546Sopenharmony_ci{ 533bf215546Sopenharmony_ci for (uint32_t i = 0; i < layout->num_sets; i++) { 534bf215546Sopenharmony_ci if (!layout->set[i].layout) 535bf215546Sopenharmony_ci continue; 536bf215546Sopenharmony_ci 537bf215546Sopenharmony_ci vk_descriptor_set_layout_unref(&device->vk, &layout->set[i].layout->vk); 538bf215546Sopenharmony_ci } 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci vk_object_base_finish(&layout->base); 541bf215546Sopenharmony_ci} 542bf215546Sopenharmony_ci 543bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 544bf215546Sopenharmony_ciradv_CreatePipelineLayout(VkDevice _device, const VkPipelineLayoutCreateInfo *pCreateInfo, 545bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 546bf215546Sopenharmony_ci VkPipelineLayout *pPipelineLayout) 547bf215546Sopenharmony_ci{ 548bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 549bf215546Sopenharmony_ci struct radv_pipeline_layout *layout; 550bf215546Sopenharmony_ci 551bf215546Sopenharmony_ci assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO); 552bf215546Sopenharmony_ci 553bf215546Sopenharmony_ci layout = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*layout), 8, 554bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 555bf215546Sopenharmony_ci if (layout == NULL) 556bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ci radv_pipeline_layout_init(device, layout, 559bf215546Sopenharmony_ci pCreateInfo->flags & VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT); 560bf215546Sopenharmony_ci 561bf215546Sopenharmony_ci layout->num_sets = pCreateInfo->setLayoutCount; 562bf215546Sopenharmony_ci 563bf215546Sopenharmony_ci for (uint32_t set = 0; set < pCreateInfo->setLayoutCount; set++) { 564bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_descriptor_set_layout, set_layout, pCreateInfo->pSetLayouts[set]); 565bf215546Sopenharmony_ci 566bf215546Sopenharmony_ci /* From the Vulkan spec 1.3.211: 567bf215546Sopenharmony_ci * 568bf215546Sopenharmony_ci * "VUID-VkPipelineLayoutCreateInfo-flags-06562 569bf215546Sopenharmony_ci * If flags: does not include VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT, elements of 570bf215546Sopenharmony_ci * pSetLayouts must be valid VkDescriptorSetLayout objects" 571bf215546Sopenharmony_ci */ 572bf215546Sopenharmony_ci if (set_layout == NULL) { 573bf215546Sopenharmony_ci assert(layout->independent_sets); 574bf215546Sopenharmony_ci continue; 575bf215546Sopenharmony_ci } 576bf215546Sopenharmony_ci 577bf215546Sopenharmony_ci radv_pipeline_layout_add_set(layout, set, set_layout); 578bf215546Sopenharmony_ci } 579bf215546Sopenharmony_ci 580bf215546Sopenharmony_ci layout->push_constant_size = 0; 581bf215546Sopenharmony_ci 582bf215546Sopenharmony_ci for (unsigned i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) { 583bf215546Sopenharmony_ci const VkPushConstantRange *range = pCreateInfo->pPushConstantRanges + i; 584bf215546Sopenharmony_ci layout->push_constant_size = MAX2(layout->push_constant_size, range->offset + range->size); 585bf215546Sopenharmony_ci } 586bf215546Sopenharmony_ci 587bf215546Sopenharmony_ci layout->push_constant_size = align(layout->push_constant_size, 16); 588bf215546Sopenharmony_ci 589bf215546Sopenharmony_ci radv_pipeline_layout_hash(layout); 590bf215546Sopenharmony_ci 591bf215546Sopenharmony_ci *pPipelineLayout = radv_pipeline_layout_to_handle(layout); 592bf215546Sopenharmony_ci 593bf215546Sopenharmony_ci return VK_SUCCESS; 594bf215546Sopenharmony_ci} 595bf215546Sopenharmony_ci 596bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 597bf215546Sopenharmony_ciradv_DestroyPipelineLayout(VkDevice _device, VkPipelineLayout _pipelineLayout, 598bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 599bf215546Sopenharmony_ci{ 600bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 601bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_pipeline_layout, pipeline_layout, _pipelineLayout); 602bf215546Sopenharmony_ci 603bf215546Sopenharmony_ci if (!pipeline_layout) 604bf215546Sopenharmony_ci return; 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_ci radv_pipeline_layout_finish(device, pipeline_layout); 607bf215546Sopenharmony_ci 608bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, pipeline_layout); 609bf215546Sopenharmony_ci} 610bf215546Sopenharmony_ci 611bf215546Sopenharmony_cistatic VkResult 612bf215546Sopenharmony_ciradv_descriptor_set_create(struct radv_device *device, struct radv_descriptor_pool *pool, 613bf215546Sopenharmony_ci struct radv_descriptor_set_layout *layout, const uint32_t *variable_count, 614bf215546Sopenharmony_ci struct radv_descriptor_set **out_set) 615bf215546Sopenharmony_ci{ 616bf215546Sopenharmony_ci if (pool->entry_count == pool->max_entry_count) 617bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_POOL_MEMORY; 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_ci struct radv_descriptor_set *set; 620bf215546Sopenharmony_ci uint32_t buffer_count = layout->buffer_count; 621bf215546Sopenharmony_ci if (variable_count) { 622bf215546Sopenharmony_ci unsigned stride = 623bf215546Sopenharmony_ci radv_descriptor_type_buffer_count(layout->binding[layout->binding_count - 1].type); 624bf215546Sopenharmony_ci buffer_count = 625bf215546Sopenharmony_ci layout->binding[layout->binding_count - 1].buffer_offset + *variable_count * stride; 626bf215546Sopenharmony_ci } 627bf215546Sopenharmony_ci unsigned range_offset = 628bf215546Sopenharmony_ci sizeof(struct radv_descriptor_set_header) + sizeof(struct radeon_winsys_bo *) * buffer_count; 629bf215546Sopenharmony_ci const unsigned dynamic_offset_count = layout->dynamic_offset_count; 630bf215546Sopenharmony_ci unsigned mem_size = 631bf215546Sopenharmony_ci range_offset + sizeof(struct radv_descriptor_range) * dynamic_offset_count; 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_ci if (pool->host_memory_base) { 634bf215546Sopenharmony_ci if (pool->host_memory_end - pool->host_memory_ptr < mem_size) 635bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_POOL_MEMORY; 636bf215546Sopenharmony_ci 637bf215546Sopenharmony_ci set = (struct radv_descriptor_set *)pool->host_memory_ptr; 638bf215546Sopenharmony_ci pool->host_memory_ptr += mem_size; 639bf215546Sopenharmony_ci } else { 640bf215546Sopenharmony_ci set = vk_alloc2(&device->vk.alloc, NULL, mem_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 641bf215546Sopenharmony_ci 642bf215546Sopenharmony_ci if (!set) 643bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 644bf215546Sopenharmony_ci } 645bf215546Sopenharmony_ci 646bf215546Sopenharmony_ci memset(set, 0, mem_size); 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_ci vk_object_base_init(&device->vk, &set->header.base, VK_OBJECT_TYPE_DESCRIPTOR_SET); 649bf215546Sopenharmony_ci 650bf215546Sopenharmony_ci if (dynamic_offset_count) { 651bf215546Sopenharmony_ci set->header.dynamic_descriptors = 652bf215546Sopenharmony_ci (struct radv_descriptor_range *)((uint8_t *)set + range_offset); 653bf215546Sopenharmony_ci } 654bf215546Sopenharmony_ci 655bf215546Sopenharmony_ci set->header.layout = layout; 656bf215546Sopenharmony_ci set->header.buffer_count = buffer_count; 657bf215546Sopenharmony_ci uint32_t layout_size = layout->size; 658bf215546Sopenharmony_ci if (variable_count) { 659bf215546Sopenharmony_ci uint32_t stride = layout->binding[layout->binding_count - 1].size; 660bf215546Sopenharmony_ci if (layout->binding[layout->binding_count - 1].type == 661bf215546Sopenharmony_ci VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) 662bf215546Sopenharmony_ci stride = 1; 663bf215546Sopenharmony_ci 664bf215546Sopenharmony_ci layout_size = layout->binding[layout->binding_count - 1].offset + *variable_count * stride; 665bf215546Sopenharmony_ci } 666bf215546Sopenharmony_ci layout_size = align_u32(layout_size, 32); 667bf215546Sopenharmony_ci set->header.size = layout_size; 668bf215546Sopenharmony_ci 669bf215546Sopenharmony_ci /* try to allocate linearly first, so that we don't spend 670bf215546Sopenharmony_ci * time looking for gaps if the app only allocates & 671bf215546Sopenharmony_ci * resets via the pool. */ 672bf215546Sopenharmony_ci if (pool->current_offset + layout_size <= pool->size) { 673bf215546Sopenharmony_ci set->header.bo = pool->bo; 674bf215546Sopenharmony_ci set->header.mapped_ptr = (uint32_t *)(pool->mapped_ptr + pool->current_offset); 675bf215546Sopenharmony_ci set->header.va = pool->bo ? (radv_buffer_get_va(set->header.bo) + pool->current_offset) : 0; 676bf215546Sopenharmony_ci if (!pool->host_memory_base) { 677bf215546Sopenharmony_ci pool->entries[pool->entry_count].offset = pool->current_offset; 678bf215546Sopenharmony_ci pool->entries[pool->entry_count].size = layout_size; 679bf215546Sopenharmony_ci } 680bf215546Sopenharmony_ci pool->entries[pool->entry_count].set = set; 681bf215546Sopenharmony_ci pool->current_offset += layout_size; 682bf215546Sopenharmony_ci } else if (!pool->host_memory_base) { 683bf215546Sopenharmony_ci uint64_t offset = 0; 684bf215546Sopenharmony_ci int index; 685bf215546Sopenharmony_ci 686bf215546Sopenharmony_ci for (index = 0; index < pool->entry_count; ++index) { 687bf215546Sopenharmony_ci if (pool->entries[index].offset - offset >= layout_size) 688bf215546Sopenharmony_ci break; 689bf215546Sopenharmony_ci offset = pool->entries[index].offset + pool->entries[index].size; 690bf215546Sopenharmony_ci } 691bf215546Sopenharmony_ci 692bf215546Sopenharmony_ci if (pool->size - offset < layout_size) { 693bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, NULL, set); 694bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_POOL_MEMORY; 695bf215546Sopenharmony_ci } 696bf215546Sopenharmony_ci set->header.bo = pool->bo; 697bf215546Sopenharmony_ci set->header.mapped_ptr = (uint32_t *)(pool->mapped_ptr + offset); 698bf215546Sopenharmony_ci set->header.va = pool->bo ? (radv_buffer_get_va(set->header.bo) + offset) : 0; 699bf215546Sopenharmony_ci memmove(&pool->entries[index + 1], &pool->entries[index], 700bf215546Sopenharmony_ci sizeof(pool->entries[0]) * (pool->entry_count - index)); 701bf215546Sopenharmony_ci pool->entries[index].offset = offset; 702bf215546Sopenharmony_ci pool->entries[index].size = layout_size; 703bf215546Sopenharmony_ci pool->entries[index].set = set; 704bf215546Sopenharmony_ci } else 705bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_POOL_MEMORY; 706bf215546Sopenharmony_ci 707bf215546Sopenharmony_ci if (layout->has_immutable_samplers) { 708bf215546Sopenharmony_ci for (unsigned i = 0; i < layout->binding_count; ++i) { 709bf215546Sopenharmony_ci if (!layout->binding[i].immutable_samplers_offset || 710bf215546Sopenharmony_ci layout->binding[i].immutable_samplers_equal) 711bf215546Sopenharmony_ci continue; 712bf215546Sopenharmony_ci 713bf215546Sopenharmony_ci unsigned offset = layout->binding[i].offset / 4; 714bf215546Sopenharmony_ci if (layout->binding[i].type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 715bf215546Sopenharmony_ci offset += radv_combined_image_descriptor_sampler_offset(layout->binding + i) / 4; 716bf215546Sopenharmony_ci 717bf215546Sopenharmony_ci const uint32_t *samplers = 718bf215546Sopenharmony_ci (const uint32_t *)((const char *)layout + layout->binding[i].immutable_samplers_offset); 719bf215546Sopenharmony_ci for (unsigned j = 0; j < layout->binding[i].array_size; ++j) { 720bf215546Sopenharmony_ci memcpy(set->header.mapped_ptr + offset, samplers + 4 * j, 16); 721bf215546Sopenharmony_ci offset += layout->binding[i].size / 4; 722bf215546Sopenharmony_ci } 723bf215546Sopenharmony_ci } 724bf215546Sopenharmony_ci } 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_ci pool->entry_count++; 727bf215546Sopenharmony_ci vk_descriptor_set_layout_ref(&layout->vk); 728bf215546Sopenharmony_ci *out_set = set; 729bf215546Sopenharmony_ci return VK_SUCCESS; 730bf215546Sopenharmony_ci} 731bf215546Sopenharmony_ci 732bf215546Sopenharmony_cistatic void 733bf215546Sopenharmony_ciradv_descriptor_set_destroy(struct radv_device *device, struct radv_descriptor_pool *pool, 734bf215546Sopenharmony_ci struct radv_descriptor_set *set, bool free_bo) 735bf215546Sopenharmony_ci{ 736bf215546Sopenharmony_ci vk_descriptor_set_layout_unref(&device->vk, &set->header.layout->vk); 737bf215546Sopenharmony_ci 738bf215546Sopenharmony_ci if (pool->host_memory_base) 739bf215546Sopenharmony_ci return; 740bf215546Sopenharmony_ci 741bf215546Sopenharmony_ci if (free_bo && !pool->host_memory_base) { 742bf215546Sopenharmony_ci for (int i = 0; i < pool->entry_count; ++i) { 743bf215546Sopenharmony_ci if (pool->entries[i].set == set) { 744bf215546Sopenharmony_ci memmove(&pool->entries[i], &pool->entries[i + 1], 745bf215546Sopenharmony_ci sizeof(pool->entries[i]) * (pool->entry_count - i - 1)); 746bf215546Sopenharmony_ci --pool->entry_count; 747bf215546Sopenharmony_ci break; 748bf215546Sopenharmony_ci } 749bf215546Sopenharmony_ci } 750bf215546Sopenharmony_ci } 751bf215546Sopenharmony_ci vk_object_base_finish(&set->header.base); 752bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, NULL, set); 753bf215546Sopenharmony_ci} 754bf215546Sopenharmony_ci 755bf215546Sopenharmony_cistatic void 756bf215546Sopenharmony_ciradv_destroy_descriptor_pool(struct radv_device *device, const VkAllocationCallbacks *pAllocator, 757bf215546Sopenharmony_ci struct radv_descriptor_pool *pool) 758bf215546Sopenharmony_ci{ 759bf215546Sopenharmony_ci for (int i = 0; i < pool->entry_count; ++i) { 760bf215546Sopenharmony_ci radv_descriptor_set_destroy(device, pool, pool->entries[i].set, false); 761bf215546Sopenharmony_ci } 762bf215546Sopenharmony_ci 763bf215546Sopenharmony_ci if (pool->bo) 764bf215546Sopenharmony_ci device->ws->buffer_destroy(device->ws, pool->bo); 765bf215546Sopenharmony_ci if (pool->host_bo) 766bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, pool->host_bo); 767bf215546Sopenharmony_ci 768bf215546Sopenharmony_ci vk_object_base_finish(&pool->base); 769bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, pool); 770bf215546Sopenharmony_ci} 771bf215546Sopenharmony_ci 772bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 773bf215546Sopenharmony_ciradv_CreateDescriptorPool(VkDevice _device, const VkDescriptorPoolCreateInfo *pCreateInfo, 774bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 775bf215546Sopenharmony_ci VkDescriptorPool *pDescriptorPool) 776bf215546Sopenharmony_ci{ 777bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 778bf215546Sopenharmony_ci struct radv_descriptor_pool *pool; 779bf215546Sopenharmony_ci uint64_t size = sizeof(struct radv_descriptor_pool); 780bf215546Sopenharmony_ci uint64_t bo_size = 0, bo_count = 0, range_count = 0; 781bf215546Sopenharmony_ci 782bf215546Sopenharmony_ci const VkMutableDescriptorTypeCreateInfoVALVE *mutable_info = 783bf215546Sopenharmony_ci vk_find_struct_const(pCreateInfo->pNext, MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE); 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ci vk_foreach_struct_const(ext, pCreateInfo->pNext) 786bf215546Sopenharmony_ci { 787bf215546Sopenharmony_ci switch (ext->sType) { 788bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO: { 789bf215546Sopenharmony_ci const VkDescriptorPoolInlineUniformBlockCreateInfo *info = 790bf215546Sopenharmony_ci (const VkDescriptorPoolInlineUniformBlockCreateInfo *)ext; 791bf215546Sopenharmony_ci /* the sizes are 4 aligned, and we need to align to at 792bf215546Sopenharmony_ci * most 32, which needs at most 28 bytes extra per 793bf215546Sopenharmony_ci * binding. */ 794bf215546Sopenharmony_ci bo_size += 28llu * info->maxInlineUniformBlockBindings; 795bf215546Sopenharmony_ci break; 796bf215546Sopenharmony_ci } 797bf215546Sopenharmony_ci default: 798bf215546Sopenharmony_ci break; 799bf215546Sopenharmony_ci } 800bf215546Sopenharmony_ci } 801bf215546Sopenharmony_ci 802bf215546Sopenharmony_ci for (unsigned i = 0; i < pCreateInfo->poolSizeCount; ++i) { 803bf215546Sopenharmony_ci bo_count += radv_descriptor_type_buffer_count(pCreateInfo->pPoolSizes[i].type) * 804bf215546Sopenharmony_ci pCreateInfo->pPoolSizes[i].descriptorCount; 805bf215546Sopenharmony_ci 806bf215546Sopenharmony_ci switch (pCreateInfo->pPoolSizes[i].type) { 807bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 808bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 809bf215546Sopenharmony_ci range_count += pCreateInfo->pPoolSizes[i].descriptorCount; 810bf215546Sopenharmony_ci break; 811bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 812bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 813bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 814bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 815bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 816bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: 817bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 818bf215546Sopenharmony_ci /* 32 as we may need to align for images */ 819bf215546Sopenharmony_ci bo_size += 32 * pCreateInfo->pPoolSizes[i].descriptorCount; 820bf215546Sopenharmony_ci break; 821bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 822bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 823bf215546Sopenharmony_ci bo_size += 64 * pCreateInfo->pPoolSizes[i].descriptorCount; 824bf215546Sopenharmony_ci break; 825bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE: 826bf215546Sopenharmony_ci /* Per spec, if a mutable descriptor type list is provided for the pool entry, we 827bf215546Sopenharmony_ci * allocate enough memory to hold any subset of that list. 828bf215546Sopenharmony_ci * If there is no mutable descriptor type list available, 829bf215546Sopenharmony_ci * we must allocate enough for any supported mutable descriptor type, i.e. 64 bytes. */ 830bf215546Sopenharmony_ci if (mutable_info && i < mutable_info->mutableDescriptorTypeListCount) { 831bf215546Sopenharmony_ci uint64_t mutable_size, mutable_alignment; 832bf215546Sopenharmony_ci if (radv_mutable_descriptor_type_size_alignment( 833bf215546Sopenharmony_ci &mutable_info->pMutableDescriptorTypeLists[i], &mutable_size, 834bf215546Sopenharmony_ci &mutable_alignment)) { 835bf215546Sopenharmony_ci /* 32 as we may need to align for images */ 836bf215546Sopenharmony_ci mutable_size = align(mutable_size, 32); 837bf215546Sopenharmony_ci bo_size += mutable_size * pCreateInfo->pPoolSizes[i].descriptorCount; 838bf215546Sopenharmony_ci } 839bf215546Sopenharmony_ci } else { 840bf215546Sopenharmony_ci bo_size += 64 * pCreateInfo->pPoolSizes[i].descriptorCount; 841bf215546Sopenharmony_ci } 842bf215546Sopenharmony_ci break; 843bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 844bf215546Sopenharmony_ci bo_size += 96 * pCreateInfo->pPoolSizes[i].descriptorCount; 845bf215546Sopenharmony_ci break; 846bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: 847bf215546Sopenharmony_ci bo_size += pCreateInfo->pPoolSizes[i].descriptorCount; 848bf215546Sopenharmony_ci break; 849bf215546Sopenharmony_ci default: 850bf215546Sopenharmony_ci break; 851bf215546Sopenharmony_ci } 852bf215546Sopenharmony_ci } 853bf215546Sopenharmony_ci 854bf215546Sopenharmony_ci uint64_t entries_size = sizeof(struct radv_descriptor_pool_entry) * pCreateInfo->maxSets; 855bf215546Sopenharmony_ci size += entries_size; 856bf215546Sopenharmony_ci 857bf215546Sopenharmony_ci if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT)) { 858bf215546Sopenharmony_ci uint64_t host_size = pCreateInfo->maxSets * sizeof(struct radv_descriptor_set); 859bf215546Sopenharmony_ci host_size += sizeof(struct radeon_winsys_bo *) * bo_count; 860bf215546Sopenharmony_ci host_size += sizeof(struct radv_descriptor_range) * range_count; 861bf215546Sopenharmony_ci size += host_size; 862bf215546Sopenharmony_ci } 863bf215546Sopenharmony_ci 864bf215546Sopenharmony_ci pool = vk_alloc2(&device->vk.alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 865bf215546Sopenharmony_ci if (!pool) 866bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 867bf215546Sopenharmony_ci 868bf215546Sopenharmony_ci memset(pool, 0, sizeof(*pool)); 869bf215546Sopenharmony_ci 870bf215546Sopenharmony_ci vk_object_base_init(&device->vk, &pool->base, VK_OBJECT_TYPE_DESCRIPTOR_POOL); 871bf215546Sopenharmony_ci 872bf215546Sopenharmony_ci if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT)) { 873bf215546Sopenharmony_ci pool->host_memory_base = (uint8_t *)pool + sizeof(struct radv_descriptor_pool) + entries_size; 874bf215546Sopenharmony_ci pool->host_memory_ptr = pool->host_memory_base; 875bf215546Sopenharmony_ci pool->host_memory_end = (uint8_t *)pool + size; 876bf215546Sopenharmony_ci } 877bf215546Sopenharmony_ci 878bf215546Sopenharmony_ci if (bo_size) { 879bf215546Sopenharmony_ci if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE)) { 880bf215546Sopenharmony_ci enum radeon_bo_flag flags = RADEON_FLAG_NO_INTERPROCESS_SHARING | RADEON_FLAG_READ_ONLY | 881bf215546Sopenharmony_ci RADEON_FLAG_32BIT; 882bf215546Sopenharmony_ci 883bf215546Sopenharmony_ci if (device->instance->zero_vram) 884bf215546Sopenharmony_ci flags |= RADEON_FLAG_ZERO_VRAM; 885bf215546Sopenharmony_ci 886bf215546Sopenharmony_ci VkResult result = device->ws->buffer_create( 887bf215546Sopenharmony_ci device->ws, bo_size, 32, RADEON_DOMAIN_VRAM, flags, RADV_BO_PRIORITY_DESCRIPTOR, 0, 888bf215546Sopenharmony_ci &pool->bo); 889bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 890bf215546Sopenharmony_ci radv_destroy_descriptor_pool(device, pAllocator, pool); 891bf215546Sopenharmony_ci return vk_error(device, result); 892bf215546Sopenharmony_ci } 893bf215546Sopenharmony_ci pool->mapped_ptr = (uint8_t *)device->ws->buffer_map(pool->bo); 894bf215546Sopenharmony_ci if (!pool->mapped_ptr) { 895bf215546Sopenharmony_ci radv_destroy_descriptor_pool(device, pAllocator, pool); 896bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); 897bf215546Sopenharmony_ci } 898bf215546Sopenharmony_ci } else { 899bf215546Sopenharmony_ci pool->host_bo = 900bf215546Sopenharmony_ci vk_alloc2(&device->vk.alloc, pAllocator, bo_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 901bf215546Sopenharmony_ci if (!pool->host_bo) { 902bf215546Sopenharmony_ci radv_destroy_descriptor_pool(device, pAllocator, pool); 903bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 904bf215546Sopenharmony_ci } 905bf215546Sopenharmony_ci pool->mapped_ptr = pool->host_bo; 906bf215546Sopenharmony_ci } 907bf215546Sopenharmony_ci } 908bf215546Sopenharmony_ci pool->size = bo_size; 909bf215546Sopenharmony_ci pool->max_entry_count = pCreateInfo->maxSets; 910bf215546Sopenharmony_ci 911bf215546Sopenharmony_ci *pDescriptorPool = radv_descriptor_pool_to_handle(pool); 912bf215546Sopenharmony_ci return VK_SUCCESS; 913bf215546Sopenharmony_ci} 914bf215546Sopenharmony_ci 915bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 916bf215546Sopenharmony_ciradv_DestroyDescriptorPool(VkDevice _device, VkDescriptorPool _pool, 917bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 918bf215546Sopenharmony_ci{ 919bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 920bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_descriptor_pool, pool, _pool); 921bf215546Sopenharmony_ci 922bf215546Sopenharmony_ci if (!pool) 923bf215546Sopenharmony_ci return; 924bf215546Sopenharmony_ci 925bf215546Sopenharmony_ci radv_destroy_descriptor_pool(device, pAllocator, pool); 926bf215546Sopenharmony_ci} 927bf215546Sopenharmony_ci 928bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 929bf215546Sopenharmony_ciradv_ResetDescriptorPool(VkDevice _device, VkDescriptorPool descriptorPool, 930bf215546Sopenharmony_ci VkDescriptorPoolResetFlags flags) 931bf215546Sopenharmony_ci{ 932bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 933bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_descriptor_pool, pool, descriptorPool); 934bf215546Sopenharmony_ci 935bf215546Sopenharmony_ci for (int i = 0; i < pool->entry_count; ++i) { 936bf215546Sopenharmony_ci radv_descriptor_set_destroy(device, pool, pool->entries[i].set, false); 937bf215546Sopenharmony_ci } 938bf215546Sopenharmony_ci pool->entry_count = 0; 939bf215546Sopenharmony_ci 940bf215546Sopenharmony_ci pool->current_offset = 0; 941bf215546Sopenharmony_ci pool->host_memory_ptr = pool->host_memory_base; 942bf215546Sopenharmony_ci 943bf215546Sopenharmony_ci return VK_SUCCESS; 944bf215546Sopenharmony_ci} 945bf215546Sopenharmony_ci 946bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 947bf215546Sopenharmony_ciradv_AllocateDescriptorSets(VkDevice _device, const VkDescriptorSetAllocateInfo *pAllocateInfo, 948bf215546Sopenharmony_ci VkDescriptorSet *pDescriptorSets) 949bf215546Sopenharmony_ci{ 950bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 951bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_descriptor_pool, pool, pAllocateInfo->descriptorPool); 952bf215546Sopenharmony_ci 953bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 954bf215546Sopenharmony_ci uint32_t i; 955bf215546Sopenharmony_ci struct radv_descriptor_set *set = NULL; 956bf215546Sopenharmony_ci 957bf215546Sopenharmony_ci const VkDescriptorSetVariableDescriptorCountAllocateInfo *variable_counts = vk_find_struct_const( 958bf215546Sopenharmony_ci pAllocateInfo->pNext, DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO); 959bf215546Sopenharmony_ci const uint32_t zero = 0; 960bf215546Sopenharmony_ci 961bf215546Sopenharmony_ci /* allocate a set of buffers for each shader to contain descriptors */ 962bf215546Sopenharmony_ci for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) { 963bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_descriptor_set_layout, layout, pAllocateInfo->pSetLayouts[i]); 964bf215546Sopenharmony_ci 965bf215546Sopenharmony_ci const uint32_t *variable_count = NULL; 966bf215546Sopenharmony_ci if (layout->has_variable_descriptors && variable_counts) { 967bf215546Sopenharmony_ci if (i < variable_counts->descriptorSetCount) 968bf215546Sopenharmony_ci variable_count = variable_counts->pDescriptorCounts + i; 969bf215546Sopenharmony_ci else 970bf215546Sopenharmony_ci variable_count = &zero; 971bf215546Sopenharmony_ci } 972bf215546Sopenharmony_ci 973bf215546Sopenharmony_ci assert(!(layout->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)); 974bf215546Sopenharmony_ci 975bf215546Sopenharmony_ci result = radv_descriptor_set_create(device, pool, layout, variable_count, &set); 976bf215546Sopenharmony_ci if (result != VK_SUCCESS) 977bf215546Sopenharmony_ci break; 978bf215546Sopenharmony_ci 979bf215546Sopenharmony_ci pDescriptorSets[i] = radv_descriptor_set_to_handle(set); 980bf215546Sopenharmony_ci } 981bf215546Sopenharmony_ci 982bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 983bf215546Sopenharmony_ci radv_FreeDescriptorSets(_device, pAllocateInfo->descriptorPool, i, pDescriptorSets); 984bf215546Sopenharmony_ci for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) { 985bf215546Sopenharmony_ci pDescriptorSets[i] = VK_NULL_HANDLE; 986bf215546Sopenharmony_ci } 987bf215546Sopenharmony_ci } 988bf215546Sopenharmony_ci return result; 989bf215546Sopenharmony_ci} 990bf215546Sopenharmony_ci 991bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 992bf215546Sopenharmony_ciradv_FreeDescriptorSets(VkDevice _device, VkDescriptorPool descriptorPool, uint32_t count, 993bf215546Sopenharmony_ci const VkDescriptorSet *pDescriptorSets) 994bf215546Sopenharmony_ci{ 995bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 996bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_descriptor_pool, pool, descriptorPool); 997bf215546Sopenharmony_ci 998bf215546Sopenharmony_ci for (uint32_t i = 0; i < count; i++) { 999bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_descriptor_set, set, pDescriptorSets[i]); 1000bf215546Sopenharmony_ci 1001bf215546Sopenharmony_ci if (set && !pool->host_memory_base) 1002bf215546Sopenharmony_ci radv_descriptor_set_destroy(device, pool, set, true); 1003bf215546Sopenharmony_ci } 1004bf215546Sopenharmony_ci return VK_SUCCESS; 1005bf215546Sopenharmony_ci} 1006bf215546Sopenharmony_ci 1007bf215546Sopenharmony_cistatic ALWAYS_INLINE void 1008bf215546Sopenharmony_ciwrite_texel_buffer_descriptor(struct radv_device *device, struct radv_cmd_buffer *cmd_buffer, 1009bf215546Sopenharmony_ci unsigned *dst, struct radeon_winsys_bo **buffer_list, 1010bf215546Sopenharmony_ci const VkBufferView _buffer_view) 1011bf215546Sopenharmony_ci{ 1012bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_buffer_view, buffer_view, _buffer_view); 1013bf215546Sopenharmony_ci 1014bf215546Sopenharmony_ci if (!buffer_view) { 1015bf215546Sopenharmony_ci memset(dst, 0, 4 * 4); 1016bf215546Sopenharmony_ci if (!cmd_buffer) 1017bf215546Sopenharmony_ci *buffer_list = NULL; 1018bf215546Sopenharmony_ci return; 1019bf215546Sopenharmony_ci } 1020bf215546Sopenharmony_ci 1021bf215546Sopenharmony_ci memcpy(dst, buffer_view->state, 4 * 4); 1022bf215546Sopenharmony_ci 1023bf215546Sopenharmony_ci if (cmd_buffer) 1024bf215546Sopenharmony_ci radv_cs_add_buffer(device->ws, cmd_buffer->cs, buffer_view->bo); 1025bf215546Sopenharmony_ci else 1026bf215546Sopenharmony_ci *buffer_list = buffer_view->bo; 1027bf215546Sopenharmony_ci} 1028bf215546Sopenharmony_ci 1029bf215546Sopenharmony_cistatic ALWAYS_INLINE void 1030bf215546Sopenharmony_ciwrite_buffer_descriptor(struct radv_device *device, struct radv_cmd_buffer *cmd_buffer, 1031bf215546Sopenharmony_ci unsigned *dst, struct radeon_winsys_bo **buffer_list, 1032bf215546Sopenharmony_ci const VkDescriptorBufferInfo *buffer_info) 1033bf215546Sopenharmony_ci{ 1034bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_buffer, buffer, buffer_info->buffer); 1035bf215546Sopenharmony_ci 1036bf215546Sopenharmony_ci if (!buffer) { 1037bf215546Sopenharmony_ci memset(dst, 0, 4 * 4); 1038bf215546Sopenharmony_ci if (!cmd_buffer) 1039bf215546Sopenharmony_ci *buffer_list = NULL; 1040bf215546Sopenharmony_ci return; 1041bf215546Sopenharmony_ci } 1042bf215546Sopenharmony_ci 1043bf215546Sopenharmony_ci uint64_t va = radv_buffer_get_va(buffer->bo); 1044bf215546Sopenharmony_ci 1045bf215546Sopenharmony_ci uint32_t range = vk_buffer_range(&buffer->vk, buffer_info->offset, buffer_info->range); 1046bf215546Sopenharmony_ci assert(buffer->vk.size > 0 && range > 0); 1047bf215546Sopenharmony_ci 1048bf215546Sopenharmony_ci /* robustBufferAccess is relaxed enough to allow this (in combination 1049bf215546Sopenharmony_ci * with the alignment/size we return from vkGetBufferMemoryRequirements) 1050bf215546Sopenharmony_ci * and this allows the shader compiler to create more efficient 8/16-bit 1051bf215546Sopenharmony_ci * buffer accesses. */ 1052bf215546Sopenharmony_ci range = align(range, 4); 1053bf215546Sopenharmony_ci 1054bf215546Sopenharmony_ci va += buffer_info->offset + buffer->offset; 1055bf215546Sopenharmony_ci 1056bf215546Sopenharmony_ci uint32_t rsrc_word3 = 1057bf215546Sopenharmony_ci S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) | S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) | 1058bf215546Sopenharmony_ci S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) | S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W); 1059bf215546Sopenharmony_ci 1060bf215546Sopenharmony_ci if (device->physical_device->rad_info.gfx_level >= GFX11) { 1061bf215546Sopenharmony_ci rsrc_word3 |= S_008F0C_FORMAT(V_008F0C_GFX11_FORMAT_32_FLOAT) | 1062bf215546Sopenharmony_ci S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_RAW); 1063bf215546Sopenharmony_ci } else if (device->physical_device->rad_info.gfx_level >= GFX10) { 1064bf215546Sopenharmony_ci rsrc_word3 |= S_008F0C_FORMAT(V_008F0C_GFX10_FORMAT_32_FLOAT) | 1065bf215546Sopenharmony_ci S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_RAW) | S_008F0C_RESOURCE_LEVEL(1); 1066bf215546Sopenharmony_ci } else { 1067bf215546Sopenharmony_ci rsrc_word3 |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) | 1068bf215546Sopenharmony_ci S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32); 1069bf215546Sopenharmony_ci } 1070bf215546Sopenharmony_ci 1071bf215546Sopenharmony_ci dst[0] = va; 1072bf215546Sopenharmony_ci dst[1] = S_008F04_BASE_ADDRESS_HI(va >> 32); 1073bf215546Sopenharmony_ci dst[2] = range; 1074bf215546Sopenharmony_ci dst[3] = rsrc_word3; 1075bf215546Sopenharmony_ci 1076bf215546Sopenharmony_ci if (cmd_buffer) 1077bf215546Sopenharmony_ci radv_cs_add_buffer(device->ws, cmd_buffer->cs, buffer->bo); 1078bf215546Sopenharmony_ci else 1079bf215546Sopenharmony_ci *buffer_list = buffer->bo; 1080bf215546Sopenharmony_ci} 1081bf215546Sopenharmony_ci 1082bf215546Sopenharmony_cistatic ALWAYS_INLINE void 1083bf215546Sopenharmony_ciwrite_block_descriptor(struct radv_device *device, struct radv_cmd_buffer *cmd_buffer, void *dst, 1084bf215546Sopenharmony_ci const VkWriteDescriptorSet *writeset) 1085bf215546Sopenharmony_ci{ 1086bf215546Sopenharmony_ci const VkWriteDescriptorSetInlineUniformBlock *inline_ub = 1087bf215546Sopenharmony_ci vk_find_struct_const(writeset->pNext, WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK); 1088bf215546Sopenharmony_ci 1089bf215546Sopenharmony_ci memcpy(dst, inline_ub->pData, inline_ub->dataSize); 1090bf215546Sopenharmony_ci} 1091bf215546Sopenharmony_ci 1092bf215546Sopenharmony_cistatic ALWAYS_INLINE void 1093bf215546Sopenharmony_ciwrite_dynamic_buffer_descriptor(struct radv_device *device, struct radv_descriptor_range *range, 1094bf215546Sopenharmony_ci struct radeon_winsys_bo **buffer_list, 1095bf215546Sopenharmony_ci const VkDescriptorBufferInfo *buffer_info) 1096bf215546Sopenharmony_ci{ 1097bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_buffer, buffer, buffer_info->buffer); 1098bf215546Sopenharmony_ci uint64_t va; 1099bf215546Sopenharmony_ci unsigned size; 1100bf215546Sopenharmony_ci 1101bf215546Sopenharmony_ci if (!buffer) { 1102bf215546Sopenharmony_ci range->va = 0; 1103bf215546Sopenharmony_ci *buffer_list = NULL; 1104bf215546Sopenharmony_ci return; 1105bf215546Sopenharmony_ci } 1106bf215546Sopenharmony_ci 1107bf215546Sopenharmony_ci va = radv_buffer_get_va(buffer->bo); 1108bf215546Sopenharmony_ci 1109bf215546Sopenharmony_ci size = vk_buffer_range(&buffer->vk, buffer_info->offset, buffer_info->range); 1110bf215546Sopenharmony_ci assert(buffer->vk.size > 0 && size > 0); 1111bf215546Sopenharmony_ci 1112bf215546Sopenharmony_ci /* robustBufferAccess is relaxed enough to allow this (in combination 1113bf215546Sopenharmony_ci * with the alignment/size we return from vkGetBufferMemoryRequirements) 1114bf215546Sopenharmony_ci * and this allows the shader compiler to create more efficient 8/16-bit 1115bf215546Sopenharmony_ci * buffer accesses. */ 1116bf215546Sopenharmony_ci size = align(size, 4); 1117bf215546Sopenharmony_ci 1118bf215546Sopenharmony_ci va += buffer_info->offset + buffer->offset; 1119bf215546Sopenharmony_ci range->va = va; 1120bf215546Sopenharmony_ci range->size = size; 1121bf215546Sopenharmony_ci 1122bf215546Sopenharmony_ci *buffer_list = buffer->bo; 1123bf215546Sopenharmony_ci} 1124bf215546Sopenharmony_ci 1125bf215546Sopenharmony_cistatic ALWAYS_INLINE void 1126bf215546Sopenharmony_ciwrite_image_descriptor(struct radv_device *device, struct radv_cmd_buffer *cmd_buffer, 1127bf215546Sopenharmony_ci unsigned size, unsigned *dst, struct radeon_winsys_bo **buffer_list, 1128bf215546Sopenharmony_ci VkDescriptorType descriptor_type, const VkDescriptorImageInfo *image_info) 1129bf215546Sopenharmony_ci{ 1130bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_image_view, iview, image_info->imageView); 1131bf215546Sopenharmony_ci union radv_descriptor *descriptor; 1132bf215546Sopenharmony_ci 1133bf215546Sopenharmony_ci if (!iview) { 1134bf215546Sopenharmony_ci memset(dst, 0, size); 1135bf215546Sopenharmony_ci if (!cmd_buffer) 1136bf215546Sopenharmony_ci *buffer_list = NULL; 1137bf215546Sopenharmony_ci return; 1138bf215546Sopenharmony_ci } 1139bf215546Sopenharmony_ci 1140bf215546Sopenharmony_ci if (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) { 1141bf215546Sopenharmony_ci descriptor = &iview->storage_descriptor; 1142bf215546Sopenharmony_ci } else { 1143bf215546Sopenharmony_ci descriptor = &iview->descriptor; 1144bf215546Sopenharmony_ci } 1145bf215546Sopenharmony_ci assert(size > 0); 1146bf215546Sopenharmony_ci 1147bf215546Sopenharmony_ci memcpy(dst, descriptor, size); 1148bf215546Sopenharmony_ci 1149bf215546Sopenharmony_ci const uint32_t max_bindings = sizeof(iview->image->bindings) / 1150bf215546Sopenharmony_ci sizeof(iview->image->bindings[0]); 1151bf215546Sopenharmony_ci for (uint32_t b = 0; b < max_bindings; b++) { 1152bf215546Sopenharmony_ci if (cmd_buffer) { 1153bf215546Sopenharmony_ci if (iview->image->bindings[b].bo) 1154bf215546Sopenharmony_ci radv_cs_add_buffer(device->ws, cmd_buffer->cs, iview->image->bindings[b].bo); 1155bf215546Sopenharmony_ci } else { 1156bf215546Sopenharmony_ci *buffer_list = iview->image->bindings[b].bo; 1157bf215546Sopenharmony_ci buffer_list++; 1158bf215546Sopenharmony_ci } 1159bf215546Sopenharmony_ci } 1160bf215546Sopenharmony_ci} 1161bf215546Sopenharmony_ci 1162bf215546Sopenharmony_cistatic ALWAYS_INLINE void 1163bf215546Sopenharmony_ciwrite_combined_image_sampler_descriptor(struct radv_device *device, 1164bf215546Sopenharmony_ci struct radv_cmd_buffer *cmd_buffer, unsigned sampler_offset, 1165bf215546Sopenharmony_ci unsigned *dst, struct radeon_winsys_bo **buffer_list, 1166bf215546Sopenharmony_ci VkDescriptorType descriptor_type, 1167bf215546Sopenharmony_ci const VkDescriptorImageInfo *image_info, bool has_sampler) 1168bf215546Sopenharmony_ci{ 1169bf215546Sopenharmony_ci write_image_descriptor(device, cmd_buffer, sampler_offset, dst, buffer_list, descriptor_type, 1170bf215546Sopenharmony_ci image_info); 1171bf215546Sopenharmony_ci /* copy over sampler state */ 1172bf215546Sopenharmony_ci if (has_sampler) { 1173bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_sampler, sampler, image_info->sampler); 1174bf215546Sopenharmony_ci memcpy(dst + sampler_offset / sizeof(*dst), sampler->state, 16); 1175bf215546Sopenharmony_ci } 1176bf215546Sopenharmony_ci} 1177bf215546Sopenharmony_ci 1178bf215546Sopenharmony_cistatic ALWAYS_INLINE void 1179bf215546Sopenharmony_ciwrite_sampler_descriptor(struct radv_device *device, unsigned *dst, 1180bf215546Sopenharmony_ci const VkDescriptorImageInfo *image_info) 1181bf215546Sopenharmony_ci{ 1182bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_sampler, sampler, image_info->sampler); 1183bf215546Sopenharmony_ci 1184bf215546Sopenharmony_ci memcpy(dst, sampler->state, 16); 1185bf215546Sopenharmony_ci} 1186bf215546Sopenharmony_ci 1187bf215546Sopenharmony_cistatic ALWAYS_INLINE void 1188bf215546Sopenharmony_ciwrite_accel_struct(void *ptr, VkAccelerationStructureKHR _accel_struct) 1189bf215546Sopenharmony_ci{ 1190bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_acceleration_structure, accel_struct, _accel_struct); 1191bf215546Sopenharmony_ci uint64_t va = accel_struct ? radv_accel_struct_get_va(accel_struct) : 0; 1192bf215546Sopenharmony_ci memcpy(ptr, &va, sizeof(va)); 1193bf215546Sopenharmony_ci} 1194bf215546Sopenharmony_ci 1195bf215546Sopenharmony_cistatic ALWAYS_INLINE void 1196bf215546Sopenharmony_ciradv_update_descriptor_sets_impl(struct radv_device *device, struct radv_cmd_buffer *cmd_buffer, 1197bf215546Sopenharmony_ci VkDescriptorSet dstSetOverride, uint32_t descriptorWriteCount, 1198bf215546Sopenharmony_ci const VkWriteDescriptorSet *pDescriptorWrites, 1199bf215546Sopenharmony_ci uint32_t descriptorCopyCount, 1200bf215546Sopenharmony_ci const VkCopyDescriptorSet *pDescriptorCopies) 1201bf215546Sopenharmony_ci{ 1202bf215546Sopenharmony_ci uint32_t i, j; 1203bf215546Sopenharmony_ci for (i = 0; i < descriptorWriteCount; i++) { 1204bf215546Sopenharmony_ci const VkWriteDescriptorSet *writeset = &pDescriptorWrites[i]; 1205bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_descriptor_set, set, 1206bf215546Sopenharmony_ci dstSetOverride ? dstSetOverride : writeset->dstSet); 1207bf215546Sopenharmony_ci const struct radv_descriptor_set_binding_layout *binding_layout = 1208bf215546Sopenharmony_ci set->header.layout->binding + writeset->dstBinding; 1209bf215546Sopenharmony_ci uint32_t *ptr = set->header.mapped_ptr; 1210bf215546Sopenharmony_ci struct radeon_winsys_bo **buffer_list = set->descriptors; 1211bf215546Sopenharmony_ci /* Immutable samplers are not copied into push descriptors when they are 1212bf215546Sopenharmony_ci * allocated, so if we are writing push descriptors we have to copy the 1213bf215546Sopenharmony_ci * immutable samplers into them now. 1214bf215546Sopenharmony_ci */ 1215bf215546Sopenharmony_ci const bool copy_immutable_samplers = cmd_buffer && 1216bf215546Sopenharmony_ci binding_layout->immutable_samplers_offset && 1217bf215546Sopenharmony_ci !binding_layout->immutable_samplers_equal; 1218bf215546Sopenharmony_ci const uint32_t *samplers = radv_immutable_samplers(set->header.layout, binding_layout); 1219bf215546Sopenharmony_ci const VkWriteDescriptorSetAccelerationStructureKHR *accel_structs = NULL; 1220bf215546Sopenharmony_ci 1221bf215546Sopenharmony_ci ptr += binding_layout->offset / 4; 1222bf215546Sopenharmony_ci 1223bf215546Sopenharmony_ci if (writeset->descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) { 1224bf215546Sopenharmony_ci write_block_descriptor(device, cmd_buffer, (uint8_t *)ptr + writeset->dstArrayElement, 1225bf215546Sopenharmony_ci writeset); 1226bf215546Sopenharmony_ci continue; 1227bf215546Sopenharmony_ci } else if (writeset->descriptorType == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) { 1228bf215546Sopenharmony_ci accel_structs = 1229bf215546Sopenharmony_ci vk_find_struct_const(writeset->pNext, WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR); 1230bf215546Sopenharmony_ci } 1231bf215546Sopenharmony_ci 1232bf215546Sopenharmony_ci ptr += binding_layout->size * writeset->dstArrayElement / 4; 1233bf215546Sopenharmony_ci buffer_list += binding_layout->buffer_offset; 1234bf215546Sopenharmony_ci buffer_list += writeset->dstArrayElement; 1235bf215546Sopenharmony_ci for (j = 0; j < writeset->descriptorCount; ++j) { 1236bf215546Sopenharmony_ci switch (writeset->descriptorType) { 1237bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 1238bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: { 1239bf215546Sopenharmony_ci unsigned idx = writeset->dstArrayElement + j; 1240bf215546Sopenharmony_ci idx += binding_layout->dynamic_offset_offset; 1241bf215546Sopenharmony_ci assert(!(set->header.layout->flags & 1242bf215546Sopenharmony_ci VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)); 1243bf215546Sopenharmony_ci write_dynamic_buffer_descriptor(device, set->header.dynamic_descriptors + idx, 1244bf215546Sopenharmony_ci buffer_list, writeset->pBufferInfo + j); 1245bf215546Sopenharmony_ci break; 1246bf215546Sopenharmony_ci } 1247bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 1248bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 1249bf215546Sopenharmony_ci write_buffer_descriptor(device, cmd_buffer, ptr, buffer_list, 1250bf215546Sopenharmony_ci writeset->pBufferInfo + j); 1251bf215546Sopenharmony_ci break; 1252bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 1253bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 1254bf215546Sopenharmony_ci write_texel_buffer_descriptor(device, cmd_buffer, ptr, buffer_list, 1255bf215546Sopenharmony_ci writeset->pTexelBufferView[j]); 1256bf215546Sopenharmony_ci break; 1257bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 1258bf215546Sopenharmony_ci write_image_descriptor(device, cmd_buffer, 32, ptr, buffer_list, 1259bf215546Sopenharmony_ci writeset->descriptorType, writeset->pImageInfo + j); 1260bf215546Sopenharmony_ci break; 1261bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 1262bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 1263bf215546Sopenharmony_ci write_image_descriptor(device, cmd_buffer, 64, ptr, buffer_list, 1264bf215546Sopenharmony_ci writeset->descriptorType, writeset->pImageInfo + j); 1265bf215546Sopenharmony_ci break; 1266bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: { 1267bf215546Sopenharmony_ci unsigned sampler_offset = radv_combined_image_descriptor_sampler_offset(binding_layout); 1268bf215546Sopenharmony_ci write_combined_image_sampler_descriptor( 1269bf215546Sopenharmony_ci device, cmd_buffer, sampler_offset, ptr, buffer_list, writeset->descriptorType, 1270bf215546Sopenharmony_ci writeset->pImageInfo + j, !binding_layout->immutable_samplers_offset); 1271bf215546Sopenharmony_ci if (copy_immutable_samplers) { 1272bf215546Sopenharmony_ci const unsigned idx = writeset->dstArrayElement + j; 1273bf215546Sopenharmony_ci memcpy((char *)ptr + sampler_offset, samplers + 4 * idx, 16); 1274bf215546Sopenharmony_ci } 1275bf215546Sopenharmony_ci break; 1276bf215546Sopenharmony_ci } 1277bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 1278bf215546Sopenharmony_ci if (!binding_layout->immutable_samplers_offset) { 1279bf215546Sopenharmony_ci write_sampler_descriptor(device, ptr, writeset->pImageInfo + j); 1280bf215546Sopenharmony_ci } else if (copy_immutable_samplers) { 1281bf215546Sopenharmony_ci unsigned idx = writeset->dstArrayElement + j; 1282bf215546Sopenharmony_ci memcpy(ptr, samplers + 4 * idx, 16); 1283bf215546Sopenharmony_ci } 1284bf215546Sopenharmony_ci break; 1285bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: 1286bf215546Sopenharmony_ci write_accel_struct(ptr, accel_structs->pAccelerationStructures[j]); 1287bf215546Sopenharmony_ci break; 1288bf215546Sopenharmony_ci default: 1289bf215546Sopenharmony_ci break; 1290bf215546Sopenharmony_ci } 1291bf215546Sopenharmony_ci ptr += binding_layout->size / 4; 1292bf215546Sopenharmony_ci ++buffer_list; 1293bf215546Sopenharmony_ci } 1294bf215546Sopenharmony_ci } 1295bf215546Sopenharmony_ci 1296bf215546Sopenharmony_ci for (i = 0; i < descriptorCopyCount; i++) { 1297bf215546Sopenharmony_ci const VkCopyDescriptorSet *copyset = &pDescriptorCopies[i]; 1298bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_descriptor_set, src_set, copyset->srcSet); 1299bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_descriptor_set, dst_set, copyset->dstSet); 1300bf215546Sopenharmony_ci const struct radv_descriptor_set_binding_layout *src_binding_layout = 1301bf215546Sopenharmony_ci src_set->header.layout->binding + copyset->srcBinding; 1302bf215546Sopenharmony_ci const struct radv_descriptor_set_binding_layout *dst_binding_layout = 1303bf215546Sopenharmony_ci dst_set->header.layout->binding + copyset->dstBinding; 1304bf215546Sopenharmony_ci uint32_t *src_ptr = src_set->header.mapped_ptr; 1305bf215546Sopenharmony_ci uint32_t *dst_ptr = dst_set->header.mapped_ptr; 1306bf215546Sopenharmony_ci struct radeon_winsys_bo **src_buffer_list = src_set->descriptors; 1307bf215546Sopenharmony_ci struct radeon_winsys_bo **dst_buffer_list = dst_set->descriptors; 1308bf215546Sopenharmony_ci 1309bf215546Sopenharmony_ci src_ptr += src_binding_layout->offset / 4; 1310bf215546Sopenharmony_ci dst_ptr += dst_binding_layout->offset / 4; 1311bf215546Sopenharmony_ci 1312bf215546Sopenharmony_ci if (src_binding_layout->type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) { 1313bf215546Sopenharmony_ci src_ptr += copyset->srcArrayElement / 4; 1314bf215546Sopenharmony_ci dst_ptr += copyset->dstArrayElement / 4; 1315bf215546Sopenharmony_ci 1316bf215546Sopenharmony_ci memcpy(dst_ptr, src_ptr, copyset->descriptorCount); 1317bf215546Sopenharmony_ci continue; 1318bf215546Sopenharmony_ci } 1319bf215546Sopenharmony_ci 1320bf215546Sopenharmony_ci src_ptr += src_binding_layout->size * copyset->srcArrayElement / 4; 1321bf215546Sopenharmony_ci dst_ptr += dst_binding_layout->size * copyset->dstArrayElement / 4; 1322bf215546Sopenharmony_ci 1323bf215546Sopenharmony_ci src_buffer_list += src_binding_layout->buffer_offset; 1324bf215546Sopenharmony_ci src_buffer_list += copyset->srcArrayElement; 1325bf215546Sopenharmony_ci 1326bf215546Sopenharmony_ci dst_buffer_list += dst_binding_layout->buffer_offset; 1327bf215546Sopenharmony_ci dst_buffer_list += copyset->dstArrayElement; 1328bf215546Sopenharmony_ci 1329bf215546Sopenharmony_ci /* In case of copies between mutable descriptor types 1330bf215546Sopenharmony_ci * and non-mutable descriptor types. */ 1331bf215546Sopenharmony_ci size_t copy_size = MIN2(src_binding_layout->size, dst_binding_layout->size); 1332bf215546Sopenharmony_ci 1333bf215546Sopenharmony_ci for (j = 0; j < copyset->descriptorCount; ++j) { 1334bf215546Sopenharmony_ci switch (src_binding_layout->type) { 1335bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 1336bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: { 1337bf215546Sopenharmony_ci unsigned src_idx = copyset->srcArrayElement + j; 1338bf215546Sopenharmony_ci unsigned dst_idx = copyset->dstArrayElement + j; 1339bf215546Sopenharmony_ci struct radv_descriptor_range *src_range, *dst_range; 1340bf215546Sopenharmony_ci src_idx += src_binding_layout->dynamic_offset_offset; 1341bf215546Sopenharmony_ci dst_idx += dst_binding_layout->dynamic_offset_offset; 1342bf215546Sopenharmony_ci 1343bf215546Sopenharmony_ci src_range = src_set->header.dynamic_descriptors + src_idx; 1344bf215546Sopenharmony_ci dst_range = dst_set->header.dynamic_descriptors + dst_idx; 1345bf215546Sopenharmony_ci *dst_range = *src_range; 1346bf215546Sopenharmony_ci break; 1347bf215546Sopenharmony_ci } 1348bf215546Sopenharmony_ci default: 1349bf215546Sopenharmony_ci memcpy(dst_ptr, src_ptr, copy_size); 1350bf215546Sopenharmony_ci } 1351bf215546Sopenharmony_ci src_ptr += src_binding_layout->size / 4; 1352bf215546Sopenharmony_ci dst_ptr += dst_binding_layout->size / 4; 1353bf215546Sopenharmony_ci 1354bf215546Sopenharmony_ci unsigned src_buffer_count = radv_descriptor_type_buffer_count(src_binding_layout->type); 1355bf215546Sopenharmony_ci unsigned dst_buffer_count = radv_descriptor_type_buffer_count(dst_binding_layout->type); 1356bf215546Sopenharmony_ci for (unsigned k = 0; k < dst_buffer_count; k++) { 1357bf215546Sopenharmony_ci if (k < src_buffer_count) 1358bf215546Sopenharmony_ci dst_buffer_list[k] = src_buffer_list[k]; 1359bf215546Sopenharmony_ci else 1360bf215546Sopenharmony_ci dst_buffer_list[k] = NULL; 1361bf215546Sopenharmony_ci } 1362bf215546Sopenharmony_ci 1363bf215546Sopenharmony_ci dst_buffer_list += dst_buffer_count; 1364bf215546Sopenharmony_ci src_buffer_list += src_buffer_count; 1365bf215546Sopenharmony_ci } 1366bf215546Sopenharmony_ci } 1367bf215546Sopenharmony_ci} 1368bf215546Sopenharmony_ci 1369bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1370bf215546Sopenharmony_ciradv_UpdateDescriptorSets(VkDevice _device, uint32_t descriptorWriteCount, 1371bf215546Sopenharmony_ci const VkWriteDescriptorSet *pDescriptorWrites, 1372bf215546Sopenharmony_ci uint32_t descriptorCopyCount, 1373bf215546Sopenharmony_ci const VkCopyDescriptorSet *pDescriptorCopies) 1374bf215546Sopenharmony_ci{ 1375bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 1376bf215546Sopenharmony_ci 1377bf215546Sopenharmony_ci radv_update_descriptor_sets_impl(device, NULL, VK_NULL_HANDLE, descriptorWriteCount, 1378bf215546Sopenharmony_ci pDescriptorWrites, descriptorCopyCount, pDescriptorCopies); 1379bf215546Sopenharmony_ci} 1380bf215546Sopenharmony_ci 1381bf215546Sopenharmony_civoid 1382bf215546Sopenharmony_ciradv_cmd_update_descriptor_sets(struct radv_device *device, struct radv_cmd_buffer *cmd_buffer, 1383bf215546Sopenharmony_ci VkDescriptorSet dstSetOverride, uint32_t descriptorWriteCount, 1384bf215546Sopenharmony_ci const VkWriteDescriptorSet *pDescriptorWrites, 1385bf215546Sopenharmony_ci uint32_t descriptorCopyCount, 1386bf215546Sopenharmony_ci const VkCopyDescriptorSet *pDescriptorCopies) 1387bf215546Sopenharmony_ci{ 1388bf215546Sopenharmony_ci /* Assume cmd_buffer != NULL to optimize out cmd_buffer checks in generic code above. */ 1389bf215546Sopenharmony_ci assume(cmd_buffer != NULL); 1390bf215546Sopenharmony_ci radv_update_descriptor_sets_impl(device, cmd_buffer, dstSetOverride, descriptorWriteCount, 1391bf215546Sopenharmony_ci pDescriptorWrites, descriptorCopyCount, pDescriptorCopies); 1392bf215546Sopenharmony_ci} 1393bf215546Sopenharmony_ci 1394bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 1395bf215546Sopenharmony_ciradv_CreateDescriptorUpdateTemplate(VkDevice _device, 1396bf215546Sopenharmony_ci const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo, 1397bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 1398bf215546Sopenharmony_ci VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate) 1399bf215546Sopenharmony_ci{ 1400bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 1401bf215546Sopenharmony_ci const uint32_t entry_count = pCreateInfo->descriptorUpdateEntryCount; 1402bf215546Sopenharmony_ci const size_t size = sizeof(struct radv_descriptor_update_template) + 1403bf215546Sopenharmony_ci sizeof(struct radv_descriptor_update_template_entry) * entry_count; 1404bf215546Sopenharmony_ci struct radv_descriptor_set_layout *set_layout = NULL; 1405bf215546Sopenharmony_ci struct radv_descriptor_update_template *templ; 1406bf215546Sopenharmony_ci uint32_t i; 1407bf215546Sopenharmony_ci 1408bf215546Sopenharmony_ci templ = vk_alloc2(&device->vk.alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 1409bf215546Sopenharmony_ci if (!templ) 1410bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 1411bf215546Sopenharmony_ci 1412bf215546Sopenharmony_ci vk_object_base_init(&device->vk, &templ->base, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE); 1413bf215546Sopenharmony_ci 1414bf215546Sopenharmony_ci templ->entry_count = entry_count; 1415bf215546Sopenharmony_ci 1416bf215546Sopenharmony_ci if (pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR) { 1417bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_pipeline_layout, pipeline_layout, pCreateInfo->pipelineLayout); 1418bf215546Sopenharmony_ci 1419bf215546Sopenharmony_ci /* descriptorSetLayout should be ignored for push descriptors 1420bf215546Sopenharmony_ci * and instead it refers to pipelineLayout and set. 1421bf215546Sopenharmony_ci */ 1422bf215546Sopenharmony_ci assert(pCreateInfo->set < MAX_SETS); 1423bf215546Sopenharmony_ci set_layout = pipeline_layout->set[pCreateInfo->set].layout; 1424bf215546Sopenharmony_ci 1425bf215546Sopenharmony_ci templ->bind_point = pCreateInfo->pipelineBindPoint; 1426bf215546Sopenharmony_ci } else { 1427bf215546Sopenharmony_ci assert(pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET); 1428bf215546Sopenharmony_ci set_layout = radv_descriptor_set_layout_from_handle(pCreateInfo->descriptorSetLayout); 1429bf215546Sopenharmony_ci } 1430bf215546Sopenharmony_ci 1431bf215546Sopenharmony_ci for (i = 0; i < entry_count; i++) { 1432bf215546Sopenharmony_ci const VkDescriptorUpdateTemplateEntry *entry = &pCreateInfo->pDescriptorUpdateEntries[i]; 1433bf215546Sopenharmony_ci const struct radv_descriptor_set_binding_layout *binding_layout = 1434bf215546Sopenharmony_ci set_layout->binding + entry->dstBinding; 1435bf215546Sopenharmony_ci const uint32_t buffer_offset = binding_layout->buffer_offset + entry->dstArrayElement; 1436bf215546Sopenharmony_ci const uint32_t *immutable_samplers = NULL; 1437bf215546Sopenharmony_ci uint32_t dst_offset; 1438bf215546Sopenharmony_ci uint32_t dst_stride; 1439bf215546Sopenharmony_ci 1440bf215546Sopenharmony_ci /* dst_offset is an offset into dynamic_descriptors when the descriptor 1441bf215546Sopenharmony_ci is dynamic, and an offset into mapped_ptr otherwise */ 1442bf215546Sopenharmony_ci switch (entry->descriptorType) { 1443bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 1444bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 1445bf215546Sopenharmony_ci assert(pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET); 1446bf215546Sopenharmony_ci dst_offset = binding_layout->dynamic_offset_offset + entry->dstArrayElement; 1447bf215546Sopenharmony_ci dst_stride = 0; /* Not used */ 1448bf215546Sopenharmony_ci break; 1449bf215546Sopenharmony_ci default: 1450bf215546Sopenharmony_ci switch (entry->descriptorType) { 1451bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 1452bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 1453bf215546Sopenharmony_ci /* Immutable samplers are copied into push descriptors when they are pushed */ 1454bf215546Sopenharmony_ci if (pCreateInfo->templateType == 1455bf215546Sopenharmony_ci VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR && 1456bf215546Sopenharmony_ci binding_layout->immutable_samplers_offset && 1457bf215546Sopenharmony_ci !binding_layout->immutable_samplers_equal) { 1458bf215546Sopenharmony_ci immutable_samplers = 1459bf215546Sopenharmony_ci radv_immutable_samplers(set_layout, binding_layout) + entry->dstArrayElement * 4; 1460bf215546Sopenharmony_ci } 1461bf215546Sopenharmony_ci break; 1462bf215546Sopenharmony_ci default: 1463bf215546Sopenharmony_ci break; 1464bf215546Sopenharmony_ci } 1465bf215546Sopenharmony_ci dst_offset = binding_layout->offset / 4; 1466bf215546Sopenharmony_ci if (entry->descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) 1467bf215546Sopenharmony_ci dst_offset += entry->dstArrayElement / 4; 1468bf215546Sopenharmony_ci else 1469bf215546Sopenharmony_ci dst_offset += binding_layout->size * entry->dstArrayElement / 4; 1470bf215546Sopenharmony_ci 1471bf215546Sopenharmony_ci dst_stride = binding_layout->size / 4; 1472bf215546Sopenharmony_ci break; 1473bf215546Sopenharmony_ci } 1474bf215546Sopenharmony_ci 1475bf215546Sopenharmony_ci templ->entry[i] = (struct radv_descriptor_update_template_entry){ 1476bf215546Sopenharmony_ci .descriptor_type = entry->descriptorType, 1477bf215546Sopenharmony_ci .descriptor_count = entry->descriptorCount, 1478bf215546Sopenharmony_ci .src_offset = entry->offset, 1479bf215546Sopenharmony_ci .src_stride = entry->stride, 1480bf215546Sopenharmony_ci .dst_offset = dst_offset, 1481bf215546Sopenharmony_ci .dst_stride = dst_stride, 1482bf215546Sopenharmony_ci .buffer_offset = buffer_offset, 1483bf215546Sopenharmony_ci .has_sampler = !binding_layout->immutable_samplers_offset, 1484bf215546Sopenharmony_ci .sampler_offset = radv_combined_image_descriptor_sampler_offset(binding_layout), 1485bf215546Sopenharmony_ci .immutable_samplers = immutable_samplers}; 1486bf215546Sopenharmony_ci } 1487bf215546Sopenharmony_ci 1488bf215546Sopenharmony_ci *pDescriptorUpdateTemplate = radv_descriptor_update_template_to_handle(templ); 1489bf215546Sopenharmony_ci return VK_SUCCESS; 1490bf215546Sopenharmony_ci} 1491bf215546Sopenharmony_ci 1492bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1493bf215546Sopenharmony_ciradv_DestroyDescriptorUpdateTemplate(VkDevice _device, 1494bf215546Sopenharmony_ci VkDescriptorUpdateTemplate descriptorUpdateTemplate, 1495bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 1496bf215546Sopenharmony_ci{ 1497bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 1498bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_descriptor_update_template, templ, descriptorUpdateTemplate); 1499bf215546Sopenharmony_ci 1500bf215546Sopenharmony_ci if (!templ) 1501bf215546Sopenharmony_ci return; 1502bf215546Sopenharmony_ci 1503bf215546Sopenharmony_ci vk_object_base_finish(&templ->base); 1504bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, templ); 1505bf215546Sopenharmony_ci} 1506bf215546Sopenharmony_ci 1507bf215546Sopenharmony_cistatic ALWAYS_INLINE void 1508bf215546Sopenharmony_ciradv_update_descriptor_set_with_template_impl(struct radv_device *device, 1509bf215546Sopenharmony_ci struct radv_cmd_buffer *cmd_buffer, 1510bf215546Sopenharmony_ci struct radv_descriptor_set *set, 1511bf215546Sopenharmony_ci VkDescriptorUpdateTemplate descriptorUpdateTemplate, 1512bf215546Sopenharmony_ci const void *pData) 1513bf215546Sopenharmony_ci{ 1514bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_descriptor_update_template, templ, descriptorUpdateTemplate); 1515bf215546Sopenharmony_ci uint32_t i; 1516bf215546Sopenharmony_ci 1517bf215546Sopenharmony_ci for (i = 0; i < templ->entry_count; ++i) { 1518bf215546Sopenharmony_ci struct radeon_winsys_bo **buffer_list = set->descriptors + templ->entry[i].buffer_offset; 1519bf215546Sopenharmony_ci uint32_t *pDst = set->header.mapped_ptr + templ->entry[i].dst_offset; 1520bf215546Sopenharmony_ci const uint8_t *pSrc = ((const uint8_t *)pData) + templ->entry[i].src_offset; 1521bf215546Sopenharmony_ci uint32_t j; 1522bf215546Sopenharmony_ci 1523bf215546Sopenharmony_ci if (templ->entry[i].descriptor_type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) { 1524bf215546Sopenharmony_ci memcpy((uint8_t *)pDst, pSrc, templ->entry[i].descriptor_count); 1525bf215546Sopenharmony_ci continue; 1526bf215546Sopenharmony_ci } 1527bf215546Sopenharmony_ci 1528bf215546Sopenharmony_ci for (j = 0; j < templ->entry[i].descriptor_count; ++j) { 1529bf215546Sopenharmony_ci switch (templ->entry[i].descriptor_type) { 1530bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 1531bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: { 1532bf215546Sopenharmony_ci const unsigned idx = templ->entry[i].dst_offset + j; 1533bf215546Sopenharmony_ci assert(!(set->header.layout->flags & 1534bf215546Sopenharmony_ci VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)); 1535bf215546Sopenharmony_ci write_dynamic_buffer_descriptor(device, set->header.dynamic_descriptors + idx, 1536bf215546Sopenharmony_ci buffer_list, (struct VkDescriptorBufferInfo *)pSrc); 1537bf215546Sopenharmony_ci break; 1538bf215546Sopenharmony_ci } 1539bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 1540bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 1541bf215546Sopenharmony_ci write_buffer_descriptor(device, cmd_buffer, pDst, buffer_list, 1542bf215546Sopenharmony_ci (struct VkDescriptorBufferInfo *)pSrc); 1543bf215546Sopenharmony_ci break; 1544bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 1545bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 1546bf215546Sopenharmony_ci write_texel_buffer_descriptor(device, cmd_buffer, pDst, buffer_list, 1547bf215546Sopenharmony_ci *(VkBufferView *)pSrc); 1548bf215546Sopenharmony_ci break; 1549bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 1550bf215546Sopenharmony_ci write_image_descriptor(device, cmd_buffer, 32, pDst, buffer_list, 1551bf215546Sopenharmony_ci templ->entry[i].descriptor_type, 1552bf215546Sopenharmony_ci (struct VkDescriptorImageInfo *)pSrc); 1553bf215546Sopenharmony_ci break; 1554bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 1555bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 1556bf215546Sopenharmony_ci write_image_descriptor(device, cmd_buffer, 64, pDst, buffer_list, 1557bf215546Sopenharmony_ci templ->entry[i].descriptor_type, 1558bf215546Sopenharmony_ci (struct VkDescriptorImageInfo *)pSrc); 1559bf215546Sopenharmony_ci break; 1560bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 1561bf215546Sopenharmony_ci write_combined_image_sampler_descriptor( 1562bf215546Sopenharmony_ci device, cmd_buffer, templ->entry[i].sampler_offset, pDst, buffer_list, 1563bf215546Sopenharmony_ci templ->entry[i].descriptor_type, (struct VkDescriptorImageInfo *)pSrc, 1564bf215546Sopenharmony_ci templ->entry[i].has_sampler); 1565bf215546Sopenharmony_ci if (cmd_buffer && templ->entry[i].immutable_samplers) { 1566bf215546Sopenharmony_ci memcpy((char *)pDst + templ->entry[i].sampler_offset, 1567bf215546Sopenharmony_ci templ->entry[i].immutable_samplers + 4 * j, 16); 1568bf215546Sopenharmony_ci } 1569bf215546Sopenharmony_ci break; 1570bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 1571bf215546Sopenharmony_ci if (templ->entry[i].has_sampler) 1572bf215546Sopenharmony_ci write_sampler_descriptor(device, pDst, (struct VkDescriptorImageInfo *)pSrc); 1573bf215546Sopenharmony_ci else if (cmd_buffer && templ->entry[i].immutable_samplers) 1574bf215546Sopenharmony_ci memcpy(pDst, templ->entry[i].immutable_samplers + 4 * j, 16); 1575bf215546Sopenharmony_ci break; 1576bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: 1577bf215546Sopenharmony_ci write_accel_struct(pDst, *(const VkAccelerationStructureKHR *)pSrc); 1578bf215546Sopenharmony_ci break; 1579bf215546Sopenharmony_ci default: 1580bf215546Sopenharmony_ci break; 1581bf215546Sopenharmony_ci } 1582bf215546Sopenharmony_ci pSrc += templ->entry[i].src_stride; 1583bf215546Sopenharmony_ci pDst += templ->entry[i].dst_stride; 1584bf215546Sopenharmony_ci ++buffer_list; 1585bf215546Sopenharmony_ci } 1586bf215546Sopenharmony_ci } 1587bf215546Sopenharmony_ci} 1588bf215546Sopenharmony_ci 1589bf215546Sopenharmony_civoid 1590bf215546Sopenharmony_ciradv_cmd_update_descriptor_set_with_template(struct radv_device *device, 1591bf215546Sopenharmony_ci struct radv_cmd_buffer *cmd_buffer, 1592bf215546Sopenharmony_ci struct radv_descriptor_set *set, 1593bf215546Sopenharmony_ci VkDescriptorUpdateTemplate descriptorUpdateTemplate, 1594bf215546Sopenharmony_ci const void *pData) 1595bf215546Sopenharmony_ci{ 1596bf215546Sopenharmony_ci /* Assume cmd_buffer != NULL to optimize out cmd_buffer checks in generic code above. */ 1597bf215546Sopenharmony_ci assume(cmd_buffer != NULL); 1598bf215546Sopenharmony_ci radv_update_descriptor_set_with_template_impl(device, cmd_buffer, set, descriptorUpdateTemplate, pData); 1599bf215546Sopenharmony_ci} 1600bf215546Sopenharmony_ci 1601bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1602bf215546Sopenharmony_ciradv_UpdateDescriptorSetWithTemplate(VkDevice _device, VkDescriptorSet descriptorSet, 1603bf215546Sopenharmony_ci VkDescriptorUpdateTemplate descriptorUpdateTemplate, 1604bf215546Sopenharmony_ci const void *pData) 1605bf215546Sopenharmony_ci{ 1606bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 1607bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_descriptor_set, set, descriptorSet); 1608bf215546Sopenharmony_ci 1609bf215546Sopenharmony_ci radv_update_descriptor_set_with_template_impl(device, NULL, set, descriptorUpdateTemplate, pData); 1610bf215546Sopenharmony_ci} 1611bf215546Sopenharmony_ci 1612bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1613bf215546Sopenharmony_ciradv_GetDescriptorSetLayoutHostMappingInfoVALVE( 1614bf215546Sopenharmony_ci VkDevice _device, const VkDescriptorSetBindingReferenceVALVE *pBindingReference, 1615bf215546Sopenharmony_ci VkDescriptorSetLayoutHostMappingInfoVALVE *pHostMapping) 1616bf215546Sopenharmony_ci{ 1617bf215546Sopenharmony_ci struct radv_descriptor_set_layout *set_layout = 1618bf215546Sopenharmony_ci radv_descriptor_set_layout_from_handle(pBindingReference->descriptorSetLayout); 1619bf215546Sopenharmony_ci 1620bf215546Sopenharmony_ci const struct radv_descriptor_set_binding_layout *binding_layout = 1621bf215546Sopenharmony_ci set_layout->binding + pBindingReference->binding; 1622bf215546Sopenharmony_ci 1623bf215546Sopenharmony_ci pHostMapping->descriptorOffset = binding_layout->offset; 1624bf215546Sopenharmony_ci pHostMapping->descriptorSize = binding_layout->size; 1625bf215546Sopenharmony_ci} 1626bf215546Sopenharmony_ci 1627bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1628bf215546Sopenharmony_ciradv_GetDescriptorSetHostMappingVALVE(VkDevice _device, VkDescriptorSet descriptorSet, 1629bf215546Sopenharmony_ci void **ppData) 1630bf215546Sopenharmony_ci{ 1631bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_descriptor_set, set, descriptorSet); 1632bf215546Sopenharmony_ci *ppData = set->header.mapped_ptr; 1633bf215546Sopenharmony_ci} 1634bf215546Sopenharmony_ci 1635bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 1636bf215546Sopenharmony_ciradv_CreateSamplerYcbcrConversion(VkDevice _device, 1637bf215546Sopenharmony_ci const VkSamplerYcbcrConversionCreateInfo *pCreateInfo, 1638bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 1639bf215546Sopenharmony_ci VkSamplerYcbcrConversion *pYcbcrConversion) 1640bf215546Sopenharmony_ci{ 1641bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 1642bf215546Sopenharmony_ci struct radv_sampler_ycbcr_conversion *conversion = NULL; 1643bf215546Sopenharmony_ci 1644bf215546Sopenharmony_ci conversion = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*conversion), 8, 1645bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 1646bf215546Sopenharmony_ci 1647bf215546Sopenharmony_ci if (conversion == NULL) 1648bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 1649bf215546Sopenharmony_ci 1650bf215546Sopenharmony_ci vk_object_base_init(&device->vk, &conversion->base, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION); 1651bf215546Sopenharmony_ci 1652bf215546Sopenharmony_ci conversion->state.format = pCreateInfo->format; 1653bf215546Sopenharmony_ci conversion->state.ycbcr_model = pCreateInfo->ycbcrModel; 1654bf215546Sopenharmony_ci conversion->state.ycbcr_range = pCreateInfo->ycbcrRange; 1655bf215546Sopenharmony_ci conversion->state.components = pCreateInfo->components; 1656bf215546Sopenharmony_ci conversion->state.chroma_offsets[0] = pCreateInfo->xChromaOffset; 1657bf215546Sopenharmony_ci conversion->state.chroma_offsets[1] = pCreateInfo->yChromaOffset; 1658bf215546Sopenharmony_ci conversion->state.chroma_filter = pCreateInfo->chromaFilter; 1659bf215546Sopenharmony_ci 1660bf215546Sopenharmony_ci *pYcbcrConversion = radv_sampler_ycbcr_conversion_to_handle(conversion); 1661bf215546Sopenharmony_ci return VK_SUCCESS; 1662bf215546Sopenharmony_ci} 1663bf215546Sopenharmony_ci 1664bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1665bf215546Sopenharmony_ciradv_DestroySamplerYcbcrConversion(VkDevice _device, VkSamplerYcbcrConversion ycbcrConversion, 1666bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 1667bf215546Sopenharmony_ci{ 1668bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 1669bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_sampler_ycbcr_conversion, ycbcr_conversion, ycbcrConversion); 1670bf215546Sopenharmony_ci 1671bf215546Sopenharmony_ci if (!ycbcr_conversion) 1672bf215546Sopenharmony_ci return; 1673bf215546Sopenharmony_ci 1674bf215546Sopenharmony_ci vk_object_base_finish(&ycbcr_conversion->base); 1675bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, ycbcr_conversion); 1676bf215546Sopenharmony_ci} 1677