1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © Microsoft Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include "dzn_private.h" 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "vk_alloc.h" 27bf215546Sopenharmony_ci#include "vk_descriptors.h" 28bf215546Sopenharmony_ci#include "vk_util.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "util/mesa-sha1.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_cistatic uint32_t 33bf215546Sopenharmony_citranslate_desc_stages(VkShaderStageFlags in) 34bf215546Sopenharmony_ci{ 35bf215546Sopenharmony_ci if (in == VK_SHADER_STAGE_ALL) 36bf215546Sopenharmony_ci in = VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT; 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci uint32_t out = 0; 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci u_foreach_bit(s, in) 41bf215546Sopenharmony_ci out |= BITFIELD_BIT(vk_to_mesa_shader_stage(BITFIELD_BIT(s))); 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci return out; 44bf215546Sopenharmony_ci} 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_cistatic D3D12_SHADER_VISIBILITY 47bf215546Sopenharmony_citranslate_desc_visibility(VkShaderStageFlags in) 48bf215546Sopenharmony_ci{ 49bf215546Sopenharmony_ci switch (in) { 50bf215546Sopenharmony_ci case VK_SHADER_STAGE_VERTEX_BIT: return D3D12_SHADER_VISIBILITY_VERTEX; 51bf215546Sopenharmony_ci case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return D3D12_SHADER_VISIBILITY_HULL; 52bf215546Sopenharmony_ci case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return D3D12_SHADER_VISIBILITY_DOMAIN; 53bf215546Sopenharmony_ci case VK_SHADER_STAGE_GEOMETRY_BIT: return D3D12_SHADER_VISIBILITY_GEOMETRY; 54bf215546Sopenharmony_ci case VK_SHADER_STAGE_FRAGMENT_BIT: return D3D12_SHADER_VISIBILITY_PIXEL; 55bf215546Sopenharmony_ci default: return D3D12_SHADER_VISIBILITY_ALL; 56bf215546Sopenharmony_ci } 57bf215546Sopenharmony_ci} 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_cistatic D3D12_DESCRIPTOR_RANGE_TYPE 60bf215546Sopenharmony_cidesc_type_to_range_type(VkDescriptorType in, bool writeable) 61bf215546Sopenharmony_ci{ 62bf215546Sopenharmony_ci switch (in) { 63bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 64bf215546Sopenharmony_ci return D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 67bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 68bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 69bf215546Sopenharmony_ci return D3D12_DESCRIPTOR_RANGE_TYPE_SRV; 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 72bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 73bf215546Sopenharmony_ci return D3D12_DESCRIPTOR_RANGE_TYPE_CBV; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 76bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 77bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 78bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 79bf215546Sopenharmony_ci return writeable ? D3D12_DESCRIPTOR_RANGE_TYPE_UAV : D3D12_DESCRIPTOR_RANGE_TYPE_SRV; 80bf215546Sopenharmony_ci default: 81bf215546Sopenharmony_ci unreachable("Unsupported desc type"); 82bf215546Sopenharmony_ci } 83bf215546Sopenharmony_ci} 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_cistatic bool 86bf215546Sopenharmony_ciis_dynamic_desc_type(VkDescriptorType desc_type) 87bf215546Sopenharmony_ci{ 88bf215546Sopenharmony_ci return (desc_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || 89bf215546Sopenharmony_ci desc_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC); 90bf215546Sopenharmony_ci} 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_cistatic bool 93bf215546Sopenharmony_cidzn_descriptor_type_depends_on_shader_usage(VkDescriptorType type) 94bf215546Sopenharmony_ci{ 95bf215546Sopenharmony_ci return type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER || 96bf215546Sopenharmony_ci type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || 97bf215546Sopenharmony_ci type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || 98bf215546Sopenharmony_ci type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; 99bf215546Sopenharmony_ci} 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_cistatic inline bool 102bf215546Sopenharmony_cidzn_desc_type_has_sampler(VkDescriptorType type) 103bf215546Sopenharmony_ci{ 104bf215546Sopenharmony_ci return type == VK_DESCRIPTOR_TYPE_SAMPLER || 105bf215546Sopenharmony_ci type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 106bf215546Sopenharmony_ci} 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_cistatic uint32_t 109bf215546Sopenharmony_cinum_descs_for_type(VkDescriptorType type, bool static_sampler) 110bf215546Sopenharmony_ci{ 111bf215546Sopenharmony_ci unsigned num_descs = 1; 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci /* Some type map to an SRV or UAV depending on how the shaders is using the 114bf215546Sopenharmony_ci * resource (NONWRITEABLE flag set or not), in that case we need to reserve 115bf215546Sopenharmony_ci * slots for both the UAV and SRV descs. 116bf215546Sopenharmony_ci */ 117bf215546Sopenharmony_ci if (dzn_descriptor_type_depends_on_shader_usage(type)) 118bf215546Sopenharmony_ci num_descs++; 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci /* There's no combined SRV+SAMPLER type in d3d12, we need an descriptor 121bf215546Sopenharmony_ci * for the sampler. 122bf215546Sopenharmony_ci */ 123bf215546Sopenharmony_ci if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 124bf215546Sopenharmony_ci num_descs++; 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci /* Don't count immutable samplers, they have their own descriptor. */ 127bf215546Sopenharmony_ci if (static_sampler && dzn_desc_type_has_sampler(type)) 128bf215546Sopenharmony_ci num_descs--; 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci return num_descs; 131bf215546Sopenharmony_ci} 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_cistatic VkResult 134bf215546Sopenharmony_cidzn_descriptor_set_layout_create(struct dzn_device *device, 135bf215546Sopenharmony_ci const VkDescriptorSetLayoutCreateInfo *pCreateInfo, 136bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 137bf215546Sopenharmony_ci VkDescriptorSetLayout *out) 138bf215546Sopenharmony_ci{ 139bf215546Sopenharmony_ci const VkDescriptorSetLayoutBinding *bindings = pCreateInfo->pBindings; 140bf215546Sopenharmony_ci uint32_t binding_count = 0, static_sampler_count = 0, total_ranges = 0; 141bf215546Sopenharmony_ci uint32_t dynamic_ranges_offset = 0, immutable_sampler_count = 0; 142bf215546Sopenharmony_ci uint32_t range_count[MAX_SHADER_VISIBILITIES][NUM_POOL_TYPES] = { 0 }; 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) { 145bf215546Sopenharmony_ci binding_count = MAX2(binding_count, bindings[i].binding + 1); 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci if (!bindings[i].descriptorCount) 148bf215546Sopenharmony_ci continue; 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci D3D12_SHADER_VISIBILITY visibility = 151bf215546Sopenharmony_ci translate_desc_visibility(bindings[i].stageFlags); 152bf215546Sopenharmony_ci VkDescriptorType desc_type = bindings[i].descriptorType; 153bf215546Sopenharmony_ci bool has_sampler = dzn_desc_type_has_sampler(desc_type); 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci /* From the Vulkan 1.1.97 spec for VkDescriptorSetLayoutBinding: 156bf215546Sopenharmony_ci * 157bf215546Sopenharmony_ci * "If descriptorType specifies a VK_DESCRIPTOR_TYPE_SAMPLER or 158bf215546Sopenharmony_ci * VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER type descriptor, then 159bf215546Sopenharmony_ci * pImmutableSamplers can be used to initialize a set of immutable 160bf215546Sopenharmony_ci * samplers. [...] If descriptorType is not one of these descriptor 161bf215546Sopenharmony_ci * types, then pImmutableSamplers is ignored. 162bf215546Sopenharmony_ci * 163bf215546Sopenharmony_ci * We need to be careful here and only parse pImmutableSamplers if we 164bf215546Sopenharmony_ci * have one of the right descriptor types. 165bf215546Sopenharmony_ci */ 166bf215546Sopenharmony_ci bool immutable_samplers = 167bf215546Sopenharmony_ci has_sampler && 168bf215546Sopenharmony_ci bindings[i].pImmutableSamplers != NULL; 169bf215546Sopenharmony_ci bool static_sampler = false; 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci if (immutable_samplers && bindings[i].descriptorCount == 1) { 172bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_sampler, sampler, bindings[i].pImmutableSamplers[0]); 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci if (sampler->static_border_color != -1) 175bf215546Sopenharmony_ci static_sampler = true; 176bf215546Sopenharmony_ci } 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci if (static_sampler) { 179bf215546Sopenharmony_ci static_sampler_count += bindings[i].descriptorCount; 180bf215546Sopenharmony_ci } else if (has_sampler) { 181bf215546Sopenharmony_ci range_count[visibility][D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER]++; 182bf215546Sopenharmony_ci total_ranges++; 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci if (immutable_samplers) 185bf215546Sopenharmony_ci immutable_sampler_count += bindings[i].descriptorCount; 186bf215546Sopenharmony_ci } 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci if (desc_type != VK_DESCRIPTOR_TYPE_SAMPLER) { 189bf215546Sopenharmony_ci range_count[visibility][D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV]++; 190bf215546Sopenharmony_ci total_ranges++; 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci if (dzn_descriptor_type_depends_on_shader_usage(desc_type)) { 193bf215546Sopenharmony_ci range_count[visibility][D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV]++; 194bf215546Sopenharmony_ci total_ranges++; 195bf215546Sopenharmony_ci } 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci if (!is_dynamic_desc_type(desc_type)) { 198bf215546Sopenharmony_ci uint32_t factor = 199bf215546Sopenharmony_ci dzn_descriptor_type_depends_on_shader_usage(desc_type) ? 2 : 1; 200bf215546Sopenharmony_ci dynamic_ranges_offset += bindings[i].descriptorCount * factor; 201bf215546Sopenharmony_ci } 202bf215546Sopenharmony_ci } 203bf215546Sopenharmony_ci } 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci /* We need to allocate decriptor set layouts off the device allocator 206bf215546Sopenharmony_ci * with DEVICE scope because they are reference counted and may not be 207bf215546Sopenharmony_ci * destroyed when vkDestroyDescriptorSetLayout is called. 208bf215546Sopenharmony_ci */ 209bf215546Sopenharmony_ci VK_MULTIALLOC(ma); 210bf215546Sopenharmony_ci VK_MULTIALLOC_DECL(&ma, struct dzn_descriptor_set_layout, set_layout, 1); 211bf215546Sopenharmony_ci VK_MULTIALLOC_DECL(&ma, D3D12_DESCRIPTOR_RANGE1, 212bf215546Sopenharmony_ci ranges, total_ranges); 213bf215546Sopenharmony_ci VK_MULTIALLOC_DECL(&ma, D3D12_STATIC_SAMPLER_DESC, static_samplers, 214bf215546Sopenharmony_ci static_sampler_count); 215bf215546Sopenharmony_ci VK_MULTIALLOC_DECL(&ma, const struct dzn_sampler *, immutable_samplers, 216bf215546Sopenharmony_ci immutable_sampler_count); 217bf215546Sopenharmony_ci VK_MULTIALLOC_DECL(&ma, struct dzn_descriptor_set_layout_binding, binfos, 218bf215546Sopenharmony_ci binding_count); 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci if (!vk_descriptor_set_layout_multizalloc(&device->vk, &ma)) 221bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci set_layout->static_samplers = static_samplers; 224bf215546Sopenharmony_ci set_layout->static_sampler_count = static_sampler_count; 225bf215546Sopenharmony_ci set_layout->immutable_samplers = immutable_samplers; 226bf215546Sopenharmony_ci set_layout->immutable_sampler_count = immutable_sampler_count; 227bf215546Sopenharmony_ci set_layout->bindings = binfos; 228bf215546Sopenharmony_ci set_layout->binding_count = binding_count; 229bf215546Sopenharmony_ci set_layout->dynamic_buffers.range_offset = dynamic_ranges_offset; 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci for (uint32_t i = 0; i < MAX_SHADER_VISIBILITIES; i++) { 232bf215546Sopenharmony_ci dzn_foreach_pool_type (type) { 233bf215546Sopenharmony_ci if (range_count[i][type]) { 234bf215546Sopenharmony_ci set_layout->ranges[i][type] = ranges; 235bf215546Sopenharmony_ci set_layout->range_count[i][type] = range_count[i][type]; 236bf215546Sopenharmony_ci ranges += range_count[i][type]; 237bf215546Sopenharmony_ci } 238bf215546Sopenharmony_ci } 239bf215546Sopenharmony_ci } 240bf215546Sopenharmony_ci 241bf215546Sopenharmony_ci VkDescriptorSetLayoutBinding *ordered_bindings; 242bf215546Sopenharmony_ci VkResult ret = 243bf215546Sopenharmony_ci vk_create_sorted_bindings(pCreateInfo->pBindings, 244bf215546Sopenharmony_ci pCreateInfo->bindingCount, 245bf215546Sopenharmony_ci &ordered_bindings); 246bf215546Sopenharmony_ci if (ret != VK_SUCCESS) 247bf215546Sopenharmony_ci return ret; 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci assert(binding_count == 250bf215546Sopenharmony_ci (pCreateInfo->bindingCount ? 251bf215546Sopenharmony_ci (ordered_bindings[pCreateInfo->bindingCount - 1].binding + 1) : 0)); 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci uint32_t range_idx[MAX_SHADER_VISIBILITIES][NUM_POOL_TYPES] = { 0 }; 254bf215546Sopenharmony_ci uint32_t static_sampler_idx = 0, immutable_sampler_idx = 0; 255bf215546Sopenharmony_ci uint32_t dynamic_buffer_idx = 0; 256bf215546Sopenharmony_ci uint32_t base_register = 0; 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci for (uint32_t i = 0; i < binding_count; i++) { 259bf215546Sopenharmony_ci binfos[i].static_sampler_idx = ~0; 260bf215546Sopenharmony_ci binfos[i].immutable_sampler_idx = ~0; 261bf215546Sopenharmony_ci binfos[i].dynamic_buffer_idx = ~0; 262bf215546Sopenharmony_ci dzn_foreach_pool_type (type) 263bf215546Sopenharmony_ci binfos[i].range_idx[type] = ~0; 264bf215546Sopenharmony_ci } 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) { 267bf215546Sopenharmony_ci VkDescriptorType desc_type = ordered_bindings[i].descriptorType; 268bf215546Sopenharmony_ci uint32_t binding = ordered_bindings[i].binding; 269bf215546Sopenharmony_ci uint32_t desc_count = ordered_bindings[i].descriptorCount; 270bf215546Sopenharmony_ci bool has_sampler = dzn_desc_type_has_sampler(desc_type); 271bf215546Sopenharmony_ci bool has_immutable_samplers = 272bf215546Sopenharmony_ci has_sampler && 273bf215546Sopenharmony_ci ordered_bindings[i].pImmutableSamplers != NULL; 274bf215546Sopenharmony_ci bool has_static_sampler = has_immutable_samplers && desc_count == 1; 275bf215546Sopenharmony_ci bool is_dynamic = is_dynamic_desc_type(desc_type); 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci D3D12_SHADER_VISIBILITY visibility = 278bf215546Sopenharmony_ci translate_desc_visibility(ordered_bindings[i].stageFlags); 279bf215546Sopenharmony_ci binfos[binding].type = desc_type; 280bf215546Sopenharmony_ci binfos[binding].stages = 281bf215546Sopenharmony_ci translate_desc_stages(ordered_bindings[i].stageFlags); 282bf215546Sopenharmony_ci set_layout->stages |= binfos[binding].stages; 283bf215546Sopenharmony_ci binfos[binding].visibility = visibility; 284bf215546Sopenharmony_ci binfos[binding].base_shader_register = base_register; 285bf215546Sopenharmony_ci assert(base_register + desc_count >= base_register); 286bf215546Sopenharmony_ci base_register += desc_count; 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ci if (has_static_sampler) { 289bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_sampler, sampler, ordered_bindings[i].pImmutableSamplers[0]); 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci /* Not all border colors are supported. */ 292bf215546Sopenharmony_ci if (sampler->static_border_color != -1) { 293bf215546Sopenharmony_ci binfos[binding].static_sampler_idx = static_sampler_idx; 294bf215546Sopenharmony_ci D3D12_STATIC_SAMPLER_DESC *desc = (D3D12_STATIC_SAMPLER_DESC *) 295bf215546Sopenharmony_ci &static_samplers[static_sampler_idx]; 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci desc->Filter = sampler->desc.Filter; 298bf215546Sopenharmony_ci desc->AddressU = sampler->desc.AddressU; 299bf215546Sopenharmony_ci desc->AddressV = sampler->desc.AddressV; 300bf215546Sopenharmony_ci desc->AddressW = sampler->desc.AddressW; 301bf215546Sopenharmony_ci desc->MipLODBias = sampler->desc.MipLODBias; 302bf215546Sopenharmony_ci desc->MaxAnisotropy = sampler->desc.MaxAnisotropy; 303bf215546Sopenharmony_ci desc->ComparisonFunc = sampler->desc.ComparisonFunc; 304bf215546Sopenharmony_ci desc->BorderColor = sampler->static_border_color; 305bf215546Sopenharmony_ci desc->MinLOD = sampler->desc.MinLOD; 306bf215546Sopenharmony_ci desc->MaxLOD = sampler->desc.MaxLOD; 307bf215546Sopenharmony_ci desc->ShaderRegister = binfos[binding].base_shader_register; 308bf215546Sopenharmony_ci desc->ShaderVisibility = translate_desc_visibility(ordered_bindings[i].stageFlags); 309bf215546Sopenharmony_ci static_sampler_idx++; 310bf215546Sopenharmony_ci } else { 311bf215546Sopenharmony_ci has_static_sampler = false; 312bf215546Sopenharmony_ci } 313bf215546Sopenharmony_ci } 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci if (has_immutable_samplers && !has_static_sampler) { 316bf215546Sopenharmony_ci binfos[binding].immutable_sampler_idx = immutable_sampler_idx; 317bf215546Sopenharmony_ci for (uint32_t s = 0; s < desc_count; s++) { 318bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_sampler, sampler, ordered_bindings[i].pImmutableSamplers[s]); 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci immutable_samplers[immutable_sampler_idx++] = sampler; 321bf215546Sopenharmony_ci } 322bf215546Sopenharmony_ci } 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci if (is_dynamic) { 325bf215546Sopenharmony_ci binfos[binding].dynamic_buffer_idx = dynamic_buffer_idx; 326bf215546Sopenharmony_ci for (uint32_t d = 0; d < desc_count; d++) 327bf215546Sopenharmony_ci set_layout->dynamic_buffers.bindings[dynamic_buffer_idx + d] = binding; 328bf215546Sopenharmony_ci dynamic_buffer_idx += desc_count; 329bf215546Sopenharmony_ci assert(dynamic_buffer_idx <= MAX_DYNAMIC_BUFFERS); 330bf215546Sopenharmony_ci } 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci if (!ordered_bindings[i].descriptorCount) 333bf215546Sopenharmony_ci continue; 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci unsigned num_descs = 336bf215546Sopenharmony_ci num_descs_for_type(desc_type, has_static_sampler); 337bf215546Sopenharmony_ci if (!num_descs) continue; 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci assert(visibility < ARRAY_SIZE(set_layout->ranges)); 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci bool has_range[NUM_POOL_TYPES] = { 0 }; 342bf215546Sopenharmony_ci has_range[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER] = 343bf215546Sopenharmony_ci has_sampler && !has_static_sampler; 344bf215546Sopenharmony_ci has_range[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] = 345bf215546Sopenharmony_ci desc_type != VK_DESCRIPTOR_TYPE_SAMPLER; 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci dzn_foreach_pool_type (type) { 348bf215546Sopenharmony_ci if (!has_range[type]) continue; 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci uint32_t idx = range_idx[visibility][type]++; 351bf215546Sopenharmony_ci assert(idx < range_count[visibility][type]); 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci binfos[binding].range_idx[type] = idx; 354bf215546Sopenharmony_ci D3D12_DESCRIPTOR_RANGE1 *range = (D3D12_DESCRIPTOR_RANGE1 *) 355bf215546Sopenharmony_ci &set_layout->ranges[visibility][type][idx]; 356bf215546Sopenharmony_ci VkDescriptorType range_type = desc_type; 357bf215546Sopenharmony_ci if (desc_type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) { 358bf215546Sopenharmony_ci range_type = type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER ? 359bf215546Sopenharmony_ci VK_DESCRIPTOR_TYPE_SAMPLER : 360bf215546Sopenharmony_ci VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 361bf215546Sopenharmony_ci } 362bf215546Sopenharmony_ci range->RangeType = desc_type_to_range_type(range_type, false); 363bf215546Sopenharmony_ci range->NumDescriptors = desc_count; 364bf215546Sopenharmony_ci range->BaseShaderRegister = binfos[binding].base_shader_register; 365bf215546Sopenharmony_ci range->Flags = type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER ? 366bf215546Sopenharmony_ci D3D12_DESCRIPTOR_RANGE_FLAG_NONE : 367bf215546Sopenharmony_ci D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS; 368bf215546Sopenharmony_ci if (is_dynamic) { 369bf215546Sopenharmony_ci range->OffsetInDescriptorsFromTableStart = 370bf215546Sopenharmony_ci set_layout->dynamic_buffers.range_offset + 371bf215546Sopenharmony_ci set_layout->dynamic_buffers.desc_count; 372bf215546Sopenharmony_ci set_layout->dynamic_buffers.count += range->NumDescriptors; 373bf215546Sopenharmony_ci set_layout->dynamic_buffers.desc_count += range->NumDescriptors; 374bf215546Sopenharmony_ci } else { 375bf215546Sopenharmony_ci range->OffsetInDescriptorsFromTableStart = set_layout->range_desc_count[type]; 376bf215546Sopenharmony_ci set_layout->range_desc_count[type] += range->NumDescriptors; 377bf215546Sopenharmony_ci } 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci if (!dzn_descriptor_type_depends_on_shader_usage(desc_type)) 380bf215546Sopenharmony_ci continue; 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci assert(idx + 1 < range_count[visibility][type]); 383bf215546Sopenharmony_ci range_idx[visibility][type]++; 384bf215546Sopenharmony_ci range[1] = range[0]; 385bf215546Sopenharmony_ci range++; 386bf215546Sopenharmony_ci range->RangeType = desc_type_to_range_type(range_type, true); 387bf215546Sopenharmony_ci if (is_dynamic) { 388bf215546Sopenharmony_ci range->OffsetInDescriptorsFromTableStart = 389bf215546Sopenharmony_ci set_layout->dynamic_buffers.range_offset + 390bf215546Sopenharmony_ci set_layout->dynamic_buffers.desc_count; 391bf215546Sopenharmony_ci set_layout->dynamic_buffers.desc_count += range->NumDescriptors; 392bf215546Sopenharmony_ci } else { 393bf215546Sopenharmony_ci range->OffsetInDescriptorsFromTableStart = set_layout->range_desc_count[type]; 394bf215546Sopenharmony_ci set_layout->range_desc_count[type] += range->NumDescriptors; 395bf215546Sopenharmony_ci } 396bf215546Sopenharmony_ci } 397bf215546Sopenharmony_ci } 398bf215546Sopenharmony_ci 399bf215546Sopenharmony_ci free(ordered_bindings); 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_ci *out = dzn_descriptor_set_layout_to_handle(set_layout); 402bf215546Sopenharmony_ci return VK_SUCCESS; 403bf215546Sopenharmony_ci} 404bf215546Sopenharmony_ci 405bf215546Sopenharmony_cistatic uint32_t 406bf215546Sopenharmony_cidzn_descriptor_set_layout_get_heap_offset(const struct dzn_descriptor_set_layout *layout, 407bf215546Sopenharmony_ci uint32_t b, 408bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE type, 409bf215546Sopenharmony_ci bool writeable) 410bf215546Sopenharmony_ci{ 411bf215546Sopenharmony_ci assert(b < layout->binding_count); 412bf215546Sopenharmony_ci D3D12_SHADER_VISIBILITY visibility = layout->bindings[b].visibility; 413bf215546Sopenharmony_ci assert(visibility < ARRAY_SIZE(layout->ranges)); 414bf215546Sopenharmony_ci assert(type < NUM_POOL_TYPES); 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ci uint32_t range_idx = layout->bindings[b].range_idx[type]; 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ci if (range_idx == ~0) 419bf215546Sopenharmony_ci return ~0; 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ci if (writeable && 422bf215546Sopenharmony_ci !dzn_descriptor_type_depends_on_shader_usage(layout->bindings[b].type)) 423bf215546Sopenharmony_ci return ~0; 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci if (writeable) 426bf215546Sopenharmony_ci range_idx++; 427bf215546Sopenharmony_ci 428bf215546Sopenharmony_ci assert(range_idx < layout->range_count[visibility][type]); 429bf215546Sopenharmony_ci return layout->ranges[visibility][type][range_idx].OffsetInDescriptorsFromTableStart; 430bf215546Sopenharmony_ci} 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_cistatic uint32_t 433bf215546Sopenharmony_cidzn_descriptor_set_layout_get_desc_count(const struct dzn_descriptor_set_layout *layout, 434bf215546Sopenharmony_ci uint32_t b) 435bf215546Sopenharmony_ci{ 436bf215546Sopenharmony_ci D3D12_SHADER_VISIBILITY visibility = layout->bindings[b].visibility; 437bf215546Sopenharmony_ci assert(visibility < ARRAY_SIZE(layout->ranges)); 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_ci dzn_foreach_pool_type (type) { 440bf215546Sopenharmony_ci uint32_t range_idx = layout->bindings[b].range_idx[type]; 441bf215546Sopenharmony_ci assert(range_idx == ~0 || range_idx < layout->range_count[visibility][type]); 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_ci if (range_idx != ~0) 444bf215546Sopenharmony_ci return layout->ranges[visibility][type][range_idx].NumDescriptors; 445bf215546Sopenharmony_ci } 446bf215546Sopenharmony_ci 447bf215546Sopenharmony_ci return 0; 448bf215546Sopenharmony_ci} 449bf215546Sopenharmony_ci 450bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 451bf215546Sopenharmony_cidzn_CreateDescriptorSetLayout(VkDevice device, 452bf215546Sopenharmony_ci const VkDescriptorSetLayoutCreateInfo *pCreateInfo, 453bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 454bf215546Sopenharmony_ci VkDescriptorSetLayout *pSetLayout) 455bf215546Sopenharmony_ci{ 456bf215546Sopenharmony_ci return dzn_descriptor_set_layout_create(dzn_device_from_handle(device), 457bf215546Sopenharmony_ci pCreateInfo, pAllocator, pSetLayout); 458bf215546Sopenharmony_ci} 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 461bf215546Sopenharmony_cidzn_GetDescriptorSetLayoutSupport(VkDevice device, 462bf215546Sopenharmony_ci const VkDescriptorSetLayoutCreateInfo *pCreateInfo, 463bf215546Sopenharmony_ci VkDescriptorSetLayoutSupport *pSupport) 464bf215546Sopenharmony_ci{ 465bf215546Sopenharmony_ci const VkDescriptorSetLayoutBinding *bindings = pCreateInfo->pBindings; 466bf215546Sopenharmony_ci uint32_t sampler_count = 0, other_desc_count = 0; 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_ci for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) { 469bf215546Sopenharmony_ci VkDescriptorType desc_type = bindings[i].descriptorType; 470bf215546Sopenharmony_ci bool has_sampler = dzn_desc_type_has_sampler(desc_type); 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ci if (has_sampler) 473bf215546Sopenharmony_ci sampler_count += bindings[i].descriptorCount; 474bf215546Sopenharmony_ci if (desc_type != VK_DESCRIPTOR_TYPE_SAMPLER) 475bf215546Sopenharmony_ci other_desc_count += bindings[i].descriptorCount; 476bf215546Sopenharmony_ci if (dzn_descriptor_type_depends_on_shader_usage(desc_type)) 477bf215546Sopenharmony_ci other_desc_count += bindings[i].descriptorCount; 478bf215546Sopenharmony_ci } 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci pSupport->supported = 481bf215546Sopenharmony_ci sampler_count <= (MAX_DESCS_PER_SAMPLER_HEAP / MAX_SETS) && 482bf215546Sopenharmony_ci other_desc_count <= (MAX_DESCS_PER_CBV_SRV_UAV_HEAP / MAX_SETS); 483bf215546Sopenharmony_ci} 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_cistatic void 486bf215546Sopenharmony_cidzn_pipeline_layout_destroy(struct vk_device *vk_device, 487bf215546Sopenharmony_ci struct vk_pipeline_layout *vk_layout) 488bf215546Sopenharmony_ci{ 489bf215546Sopenharmony_ci struct dzn_pipeline_layout *layout = 490bf215546Sopenharmony_ci container_of(vk_layout, struct dzn_pipeline_layout, vk); 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci if (layout->root.sig) 493bf215546Sopenharmony_ci ID3D12RootSignature_Release(layout->root.sig); 494bf215546Sopenharmony_ci 495bf215546Sopenharmony_ci vk_pipeline_layout_destroy(vk_device, &layout->vk); 496bf215546Sopenharmony_ci} 497bf215546Sopenharmony_ci 498bf215546Sopenharmony_ci// Reserve two root parameters for the push constants and sysvals CBVs. 499bf215546Sopenharmony_ci#define MAX_INTERNAL_ROOT_PARAMS 2 500bf215546Sopenharmony_ci 501bf215546Sopenharmony_ci// One root parameter for samplers and the other one for views, multiplied by 502bf215546Sopenharmony_ci// the number of visibility combinations, plus the internal root parameters. 503bf215546Sopenharmony_ci#define MAX_ROOT_PARAMS ((MAX_SHADER_VISIBILITIES * 2) + MAX_INTERNAL_ROOT_PARAMS) 504bf215546Sopenharmony_ci 505bf215546Sopenharmony_ci// Maximum number of DWORDS (32-bit words) that can be used for a root signature 506bf215546Sopenharmony_ci#define MAX_ROOT_DWORDS 64 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_cistatic void 509bf215546Sopenharmony_cidzn_pipeline_layout_hash_stages(struct dzn_pipeline_layout *layout, 510bf215546Sopenharmony_ci const VkPipelineLayoutCreateInfo *info) 511bf215546Sopenharmony_ci{ 512bf215546Sopenharmony_ci uint32_t stages = 0; 513bf215546Sopenharmony_ci for (uint32_t stage = 0; stage < ARRAY_SIZE(layout->stages); stage++) { 514bf215546Sopenharmony_ci for (uint32_t set = 0; set < info->setLayoutCount; set++) { 515bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_set_layout, set_layout, info->pSetLayouts[set]); 516bf215546Sopenharmony_ci 517bf215546Sopenharmony_ci stages |= set_layout->stages; 518bf215546Sopenharmony_ci } 519bf215546Sopenharmony_ci } 520bf215546Sopenharmony_ci 521bf215546Sopenharmony_ci for (uint32_t stage = 0; stage < ARRAY_SIZE(layout->stages); stage++) { 522bf215546Sopenharmony_ci if (!(stages & BITFIELD_BIT(stage))) 523bf215546Sopenharmony_ci continue; 524bf215546Sopenharmony_ci 525bf215546Sopenharmony_ci struct mesa_sha1 ctx; 526bf215546Sopenharmony_ci 527bf215546Sopenharmony_ci _mesa_sha1_init(&ctx); 528bf215546Sopenharmony_ci for (uint32_t set = 0; set < info->setLayoutCount; set++) { 529bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_set_layout, set_layout, info->pSetLayouts[set]); 530bf215546Sopenharmony_ci if (!(BITFIELD_BIT(stage) & set_layout->stages)) 531bf215546Sopenharmony_ci continue; 532bf215546Sopenharmony_ci 533bf215546Sopenharmony_ci for (uint32_t b = 0; b < set_layout->binding_count; b++) { 534bf215546Sopenharmony_ci if (!(BITFIELD_BIT(stage) & set_layout->bindings[b].stages)) 535bf215546Sopenharmony_ci continue; 536bf215546Sopenharmony_ci 537bf215546Sopenharmony_ci _mesa_sha1_update(&ctx, &b, sizeof(b)); 538bf215546Sopenharmony_ci _mesa_sha1_update(&ctx, &set_layout->bindings[b].base_shader_register, 539bf215546Sopenharmony_ci sizeof(set_layout->bindings[b].base_shader_register)); 540bf215546Sopenharmony_ci } 541bf215546Sopenharmony_ci } 542bf215546Sopenharmony_ci _mesa_sha1_final(&ctx, layout->stages[stage].hash); 543bf215546Sopenharmony_ci } 544bf215546Sopenharmony_ci} 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_cistatic VkResult 547bf215546Sopenharmony_cidzn_pipeline_layout_create(struct dzn_device *device, 548bf215546Sopenharmony_ci const VkPipelineLayoutCreateInfo *pCreateInfo, 549bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 550bf215546Sopenharmony_ci VkPipelineLayout *out) 551bf215546Sopenharmony_ci{ 552bf215546Sopenharmony_ci uint32_t binding_count = 0; 553bf215546Sopenharmony_ci 554bf215546Sopenharmony_ci for (uint32_t s = 0; s < pCreateInfo->setLayoutCount; s++) { 555bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_set_layout, set_layout, pCreateInfo->pSetLayouts[s]); 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_ci if (!set_layout) 558bf215546Sopenharmony_ci continue; 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_ci binding_count += set_layout->binding_count; 561bf215546Sopenharmony_ci } 562bf215546Sopenharmony_ci 563bf215546Sopenharmony_ci VK_MULTIALLOC(ma); 564bf215546Sopenharmony_ci VK_MULTIALLOC_DECL(&ma, struct dzn_pipeline_layout, layout, 1); 565bf215546Sopenharmony_ci VK_MULTIALLOC_DECL(&ma, uint32_t, binding_translation, binding_count); 566bf215546Sopenharmony_ci 567bf215546Sopenharmony_ci if (!vk_pipeline_layout_multizalloc(&device->vk, &ma, pCreateInfo)) 568bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 569bf215546Sopenharmony_ci 570bf215546Sopenharmony_ci layout->vk.destroy = dzn_pipeline_layout_destroy; 571bf215546Sopenharmony_ci 572bf215546Sopenharmony_ci for (uint32_t s = 0; s < pCreateInfo->setLayoutCount; s++) { 573bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_set_layout, set_layout, pCreateInfo->pSetLayouts[s]); 574bf215546Sopenharmony_ci 575bf215546Sopenharmony_ci if (!set_layout || !set_layout->binding_count) 576bf215546Sopenharmony_ci continue; 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_ci layout->binding_translation[s].base_reg = binding_translation; 579bf215546Sopenharmony_ci binding_translation += set_layout->binding_count; 580bf215546Sopenharmony_ci } 581bf215546Sopenharmony_ci 582bf215546Sopenharmony_ci uint32_t range_count = 0, static_sampler_count = 0; 583bf215546Sopenharmony_ci 584bf215546Sopenharmony_ci layout->root.param_count = 0; 585bf215546Sopenharmony_ci dzn_foreach_pool_type (type) 586bf215546Sopenharmony_ci layout->desc_count[type] = 0; 587bf215546Sopenharmony_ci 588bf215546Sopenharmony_ci layout->set_count = pCreateInfo->setLayoutCount; 589bf215546Sopenharmony_ci for (uint32_t j = 0; j < layout->set_count; j++) { 590bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_set_layout, set_layout, pCreateInfo->pSetLayouts[j]); 591bf215546Sopenharmony_ci uint32_t *binding_trans = layout->binding_translation[j].base_reg; 592bf215546Sopenharmony_ci 593bf215546Sopenharmony_ci layout->sets[j].dynamic_buffer_count = set_layout->dynamic_buffers.count; 594bf215546Sopenharmony_ci memcpy(layout->sets[j].range_desc_count, set_layout->range_desc_count, 595bf215546Sopenharmony_ci sizeof(layout->sets[j].range_desc_count)); 596bf215546Sopenharmony_ci layout->binding_translation[j].binding_count = set_layout->binding_count; 597bf215546Sopenharmony_ci for (uint32_t b = 0; b < set_layout->binding_count; b++) 598bf215546Sopenharmony_ci binding_trans[b] = set_layout->bindings[b].base_shader_register; 599bf215546Sopenharmony_ci 600bf215546Sopenharmony_ci static_sampler_count += set_layout->static_sampler_count; 601bf215546Sopenharmony_ci dzn_foreach_pool_type (type) { 602bf215546Sopenharmony_ci layout->sets[j].heap_offsets[type] = layout->desc_count[type]; 603bf215546Sopenharmony_ci layout->desc_count[type] += set_layout->range_desc_count[type]; 604bf215546Sopenharmony_ci for (uint32_t i = 0; i < MAX_SHADER_VISIBILITIES; i++) 605bf215546Sopenharmony_ci range_count += set_layout->range_count[i][type]; 606bf215546Sopenharmony_ci } 607bf215546Sopenharmony_ci 608bf215546Sopenharmony_ci layout->desc_count[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] += 609bf215546Sopenharmony_ci set_layout->dynamic_buffers.desc_count; 610bf215546Sopenharmony_ci for (uint32_t o = 0, elem = 0; o < set_layout->dynamic_buffers.count; o++, elem++) { 611bf215546Sopenharmony_ci uint32_t b = set_layout->dynamic_buffers.bindings[o]; 612bf215546Sopenharmony_ci 613bf215546Sopenharmony_ci if (o > 0 && set_layout->dynamic_buffers.bindings[o - 1] != b) 614bf215546Sopenharmony_ci elem = 0; 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci uint32_t srv = 617bf215546Sopenharmony_ci dzn_descriptor_set_layout_get_heap_offset(set_layout, b, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, false); 618bf215546Sopenharmony_ci uint32_t uav = 619bf215546Sopenharmony_ci dzn_descriptor_set_layout_get_heap_offset(set_layout, b, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, true); 620bf215546Sopenharmony_ci 621bf215546Sopenharmony_ci layout->sets[j].dynamic_buffer_heap_offsets[o].srv = srv != ~0 ? srv + elem : ~0; 622bf215546Sopenharmony_ci layout->sets[j].dynamic_buffer_heap_offsets[o].uav = uav != ~0 ? uav + elem : ~0; 623bf215546Sopenharmony_ci } 624bf215546Sopenharmony_ci } 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci D3D12_DESCRIPTOR_RANGE1 *ranges = 627bf215546Sopenharmony_ci vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*ranges) * range_count, 8, 628bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 629bf215546Sopenharmony_ci if (range_count && !ranges) { 630bf215546Sopenharmony_ci vk_pipeline_layout_unref(&device->vk, &layout->vk); 631bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 632bf215546Sopenharmony_ci } 633bf215546Sopenharmony_ci 634bf215546Sopenharmony_ci D3D12_STATIC_SAMPLER_DESC *static_sampler_descs = 635bf215546Sopenharmony_ci vk_alloc2(&device->vk.alloc, pAllocator, 636bf215546Sopenharmony_ci sizeof(*static_sampler_descs) * static_sampler_count, 8, 637bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 638bf215546Sopenharmony_ci if (static_sampler_count && !static_sampler_descs) { 639bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, ranges); 640bf215546Sopenharmony_ci vk_pipeline_layout_unref(&device->vk, &layout->vk); 641bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 642bf215546Sopenharmony_ci } 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_ci 645bf215546Sopenharmony_ci D3D12_ROOT_PARAMETER1 root_params[MAX_ROOT_PARAMS] = { 0 }; 646bf215546Sopenharmony_ci D3D12_DESCRIPTOR_RANGE1 *range_ptr = ranges; 647bf215546Sopenharmony_ci D3D12_ROOT_PARAMETER1 *root_param; 648bf215546Sopenharmony_ci uint32_t root_dwords = 0; 649bf215546Sopenharmony_ci 650bf215546Sopenharmony_ci for (uint32_t i = 0; i < MAX_SHADER_VISIBILITIES; i++) { 651bf215546Sopenharmony_ci dzn_foreach_pool_type (type) { 652bf215546Sopenharmony_ci root_param = &root_params[layout->root.param_count]; 653bf215546Sopenharmony_ci root_param->ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; 654bf215546Sopenharmony_ci root_param->DescriptorTable.pDescriptorRanges = range_ptr; 655bf215546Sopenharmony_ci root_param->DescriptorTable.NumDescriptorRanges = 0; 656bf215546Sopenharmony_ci root_param->ShaderVisibility = (D3D12_SHADER_VISIBILITY)i; 657bf215546Sopenharmony_ci 658bf215546Sopenharmony_ci for (uint32_t j = 0; j < pCreateInfo->setLayoutCount; j++) { 659bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_set_layout, set_layout, pCreateInfo->pSetLayouts[j]); 660bf215546Sopenharmony_ci uint32_t range_count = set_layout->range_count[i][type]; 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_ci memcpy(range_ptr, set_layout->ranges[i][type], 663bf215546Sopenharmony_ci range_count * sizeof(D3D12_DESCRIPTOR_RANGE1)); 664bf215546Sopenharmony_ci for (uint32_t k = 0; k < range_count; k++) { 665bf215546Sopenharmony_ci range_ptr[k].RegisterSpace = j; 666bf215546Sopenharmony_ci range_ptr[k].OffsetInDescriptorsFromTableStart += 667bf215546Sopenharmony_ci layout->sets[j].heap_offsets[type]; 668bf215546Sopenharmony_ci } 669bf215546Sopenharmony_ci root_param->DescriptorTable.NumDescriptorRanges += range_count; 670bf215546Sopenharmony_ci range_ptr += range_count; 671bf215546Sopenharmony_ci } 672bf215546Sopenharmony_ci 673bf215546Sopenharmony_ci if (root_param->DescriptorTable.NumDescriptorRanges) { 674bf215546Sopenharmony_ci layout->root.type[layout->root.param_count++] = (D3D12_DESCRIPTOR_HEAP_TYPE)type; 675bf215546Sopenharmony_ci root_dwords++; 676bf215546Sopenharmony_ci } 677bf215546Sopenharmony_ci } 678bf215546Sopenharmony_ci } 679bf215546Sopenharmony_ci 680bf215546Sopenharmony_ci layout->root.sets_param_count = layout->root.param_count; 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_ci /* Add our sysval CBV, and make it visible to all shaders */ 683bf215546Sopenharmony_ci layout->root.sysval_cbv_param_idx = layout->root.param_count; 684bf215546Sopenharmony_ci root_param = &root_params[layout->root.param_count++]; 685bf215546Sopenharmony_ci root_param->ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; 686bf215546Sopenharmony_ci root_param->Descriptor.RegisterSpace = DZN_REGISTER_SPACE_SYSVALS; 687bf215546Sopenharmony_ci root_param->Constants.ShaderRegister = 0; 688bf215546Sopenharmony_ci root_param->Constants.Num32BitValues = 689bf215546Sopenharmony_ci DIV_ROUND_UP(MAX2(sizeof(struct dxil_spirv_vertex_runtime_data), 690bf215546Sopenharmony_ci sizeof(struct dxil_spirv_compute_runtime_data)), 691bf215546Sopenharmony_ci 4); 692bf215546Sopenharmony_ci root_param->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; 693bf215546Sopenharmony_ci root_dwords += root_param->Constants.Num32BitValues; 694bf215546Sopenharmony_ci 695bf215546Sopenharmony_ci D3D12_STATIC_SAMPLER_DESC *static_sampler_ptr = static_sampler_descs; 696bf215546Sopenharmony_ci for (uint32_t j = 0; j < pCreateInfo->setLayoutCount; j++) { 697bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_set_layout, set_layout, pCreateInfo->pSetLayouts[j]); 698bf215546Sopenharmony_ci 699bf215546Sopenharmony_ci memcpy(static_sampler_ptr, set_layout->static_samplers, 700bf215546Sopenharmony_ci set_layout->static_sampler_count * sizeof(*set_layout->static_samplers)); 701bf215546Sopenharmony_ci if (j > 0) { 702bf215546Sopenharmony_ci for (uint32_t k = 0; k < set_layout->static_sampler_count; k++) 703bf215546Sopenharmony_ci static_sampler_ptr[k].RegisterSpace = j; 704bf215546Sopenharmony_ci } 705bf215546Sopenharmony_ci static_sampler_ptr += set_layout->static_sampler_count; 706bf215546Sopenharmony_ci } 707bf215546Sopenharmony_ci 708bf215546Sopenharmony_ci uint32_t push_constant_size = 0; 709bf215546Sopenharmony_ci uint32_t push_constant_flags = 0; 710bf215546Sopenharmony_ci for (uint32_t j = 0; j < pCreateInfo->pushConstantRangeCount; j++) { 711bf215546Sopenharmony_ci const VkPushConstantRange *range = pCreateInfo->pPushConstantRanges + j; 712bf215546Sopenharmony_ci push_constant_size = MAX2(push_constant_size, range->offset + range->size); 713bf215546Sopenharmony_ci push_constant_flags |= range->stageFlags; 714bf215546Sopenharmony_ci } 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_ci if (push_constant_size > 0) { 717bf215546Sopenharmony_ci layout->root.push_constant_cbv_param_idx = layout->root.param_count; 718bf215546Sopenharmony_ci D3D12_ROOT_PARAMETER1 *root_param = &root_params[layout->root.param_count++]; 719bf215546Sopenharmony_ci 720bf215546Sopenharmony_ci root_param->ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; 721bf215546Sopenharmony_ci root_param->Constants.ShaderRegister = 0; 722bf215546Sopenharmony_ci root_param->Constants.Num32BitValues = ALIGN(push_constant_size, 4) / 4; 723bf215546Sopenharmony_ci root_param->Constants.RegisterSpace = DZN_REGISTER_SPACE_PUSH_CONSTANT; 724bf215546Sopenharmony_ci root_param->ShaderVisibility = translate_desc_visibility(push_constant_flags); 725bf215546Sopenharmony_ci root_dwords += root_param->Constants.Num32BitValues; 726bf215546Sopenharmony_ci } 727bf215546Sopenharmony_ci 728bf215546Sopenharmony_ci assert(layout->root.param_count <= ARRAY_SIZE(root_params)); 729bf215546Sopenharmony_ci assert(root_dwords <= MAX_ROOT_DWORDS); 730bf215546Sopenharmony_ci 731bf215546Sopenharmony_ci D3D12_VERSIONED_ROOT_SIGNATURE_DESC root_sig_desc = { 732bf215546Sopenharmony_ci .Version = D3D_ROOT_SIGNATURE_VERSION_1_1, 733bf215546Sopenharmony_ci .Desc_1_1 = { 734bf215546Sopenharmony_ci .NumParameters = layout->root.param_count, 735bf215546Sopenharmony_ci .pParameters = layout->root.param_count ? root_params : NULL, 736bf215546Sopenharmony_ci .NumStaticSamplers =static_sampler_count, 737bf215546Sopenharmony_ci .pStaticSamplers = static_sampler_descs, 738bf215546Sopenharmony_ci /* TODO Only enable this flag when needed (optimization) */ 739bf215546Sopenharmony_ci .Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT, 740bf215546Sopenharmony_ci }, 741bf215546Sopenharmony_ci }; 742bf215546Sopenharmony_ci 743bf215546Sopenharmony_ci layout->root.sig = dzn_device_create_root_sig(device, &root_sig_desc); 744bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, ranges); 745bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, static_sampler_descs); 746bf215546Sopenharmony_ci 747bf215546Sopenharmony_ci if (!layout->root.sig) { 748bf215546Sopenharmony_ci vk_pipeline_layout_unref(&device->vk, &layout->vk); 749bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 750bf215546Sopenharmony_ci } 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_ci dzn_pipeline_layout_hash_stages(layout, pCreateInfo); 753bf215546Sopenharmony_ci *out = dzn_pipeline_layout_to_handle(layout); 754bf215546Sopenharmony_ci return VK_SUCCESS; 755bf215546Sopenharmony_ci} 756bf215546Sopenharmony_ci 757bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 758bf215546Sopenharmony_cidzn_CreatePipelineLayout(VkDevice device, 759bf215546Sopenharmony_ci const VkPipelineLayoutCreateInfo *pCreateInfo, 760bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 761bf215546Sopenharmony_ci VkPipelineLayout *pPipelineLayout) 762bf215546Sopenharmony_ci{ 763bf215546Sopenharmony_ci return dzn_pipeline_layout_create(dzn_device_from_handle(device), 764bf215546Sopenharmony_ci pCreateInfo, pAllocator, pPipelineLayout); 765bf215546Sopenharmony_ci} 766bf215546Sopenharmony_ci 767bf215546Sopenharmony_cistatic D3D12_DESCRIPTOR_HEAP_TYPE 768bf215546Sopenharmony_cidesc_type_to_heap_type(VkDescriptorType in) 769bf215546Sopenharmony_ci{ 770bf215546Sopenharmony_ci switch (in) { 771bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 772bf215546Sopenharmony_ci return D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; 773bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 774bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 775bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 776bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 777bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 778bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 779bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 780bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 781bf215546Sopenharmony_ci return D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; 782bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 783bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 784bf215546Sopenharmony_ci default: 785bf215546Sopenharmony_ci unreachable("Unsupported desc type"); 786bf215546Sopenharmony_ci } 787bf215546Sopenharmony_ci} 788bf215546Sopenharmony_ci 789bf215546Sopenharmony_cistatic void 790bf215546Sopenharmony_cidzn_descriptor_heap_finish(struct dzn_descriptor_heap *heap) 791bf215546Sopenharmony_ci{ 792bf215546Sopenharmony_ci if (heap->heap) 793bf215546Sopenharmony_ci ID3D12DescriptorHeap_Release(heap->heap); 794bf215546Sopenharmony_ci 795bf215546Sopenharmony_ci if (heap->dev) 796bf215546Sopenharmony_ci ID3D12Device_Release(heap->dev); 797bf215546Sopenharmony_ci} 798bf215546Sopenharmony_ci 799bf215546Sopenharmony_cistatic VkResult 800bf215546Sopenharmony_cidzn_descriptor_heap_init(struct dzn_descriptor_heap *heap, 801bf215546Sopenharmony_ci struct dzn_device *device, 802bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE type, 803bf215546Sopenharmony_ci uint32_t desc_count, 804bf215546Sopenharmony_ci bool shader_visible) 805bf215546Sopenharmony_ci{ 806bf215546Sopenharmony_ci heap->desc_count = desc_count; 807bf215546Sopenharmony_ci heap->type = type; 808bf215546Sopenharmony_ci heap->dev = device->dev; 809bf215546Sopenharmony_ci ID3D12Device1_AddRef(heap->dev); 810bf215546Sopenharmony_ci heap->desc_sz = ID3D12Device1_GetDescriptorHandleIncrementSize(device->dev, type); 811bf215546Sopenharmony_ci 812bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_DESC desc = { 813bf215546Sopenharmony_ci .Type = type, 814bf215546Sopenharmony_ci .NumDescriptors = desc_count, 815bf215546Sopenharmony_ci .Flags = shader_visible ? 816bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE : 817bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_FLAG_NONE, 818bf215546Sopenharmony_ci }; 819bf215546Sopenharmony_ci 820bf215546Sopenharmony_ci if (FAILED(ID3D12Device1_CreateDescriptorHeap(device->dev, &desc, 821bf215546Sopenharmony_ci &IID_ID3D12DescriptorHeap, 822bf215546Sopenharmony_ci (void **)&heap->heap))) { 823bf215546Sopenharmony_ci return vk_error(device, 824bf215546Sopenharmony_ci shader_visible ? 825bf215546Sopenharmony_ci VK_ERROR_OUT_OF_DEVICE_MEMORY : VK_ERROR_OUT_OF_HOST_MEMORY); 826bf215546Sopenharmony_ci } 827bf215546Sopenharmony_ci 828bf215546Sopenharmony_ci D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle = dzn_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap->heap); 829bf215546Sopenharmony_ci heap->cpu_base = cpu_handle.ptr; 830bf215546Sopenharmony_ci if (shader_visible) { 831bf215546Sopenharmony_ci D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle = dzn_ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap->heap); 832bf215546Sopenharmony_ci heap->gpu_base = gpu_handle.ptr; 833bf215546Sopenharmony_ci } 834bf215546Sopenharmony_ci 835bf215546Sopenharmony_ci return VK_SUCCESS; 836bf215546Sopenharmony_ci} 837bf215546Sopenharmony_ci 838bf215546Sopenharmony_ciD3D12_CPU_DESCRIPTOR_HANDLE 839bf215546Sopenharmony_cidzn_descriptor_heap_get_cpu_handle(const struct dzn_descriptor_heap *heap, uint32_t desc_offset) 840bf215546Sopenharmony_ci{ 841bf215546Sopenharmony_ci return (D3D12_CPU_DESCRIPTOR_HANDLE) { 842bf215546Sopenharmony_ci .ptr = heap->cpu_base + (desc_offset * heap->desc_sz), 843bf215546Sopenharmony_ci }; 844bf215546Sopenharmony_ci} 845bf215546Sopenharmony_ci 846bf215546Sopenharmony_ciD3D12_GPU_DESCRIPTOR_HANDLE 847bf215546Sopenharmony_cidzn_descriptor_heap_get_gpu_handle(const struct dzn_descriptor_heap *heap, uint32_t desc_offset) 848bf215546Sopenharmony_ci{ 849bf215546Sopenharmony_ci return (D3D12_GPU_DESCRIPTOR_HANDLE) { 850bf215546Sopenharmony_ci .ptr = heap->gpu_base ? heap->gpu_base + (desc_offset * heap->desc_sz) : 0, 851bf215546Sopenharmony_ci }; 852bf215546Sopenharmony_ci} 853bf215546Sopenharmony_ci 854bf215546Sopenharmony_cistatic void 855bf215546Sopenharmony_cidzn_descriptor_heap_write_sampler_desc(struct dzn_descriptor_heap *heap, 856bf215546Sopenharmony_ci uint32_t desc_offset, 857bf215546Sopenharmony_ci const struct dzn_sampler *sampler) 858bf215546Sopenharmony_ci{ 859bf215546Sopenharmony_ci ID3D12Device1_CreateSampler(heap->dev, &sampler->desc, 860bf215546Sopenharmony_ci dzn_descriptor_heap_get_cpu_handle(heap, desc_offset)); 861bf215546Sopenharmony_ci} 862bf215546Sopenharmony_ci 863bf215546Sopenharmony_civoid 864bf215546Sopenharmony_cidzn_descriptor_heap_write_image_view_desc(struct dzn_descriptor_heap *heap, 865bf215546Sopenharmony_ci uint32_t desc_offset, 866bf215546Sopenharmony_ci bool writeable, bool cube_as_2darray, 867bf215546Sopenharmony_ci const struct dzn_image_view *iview) 868bf215546Sopenharmony_ci{ 869bf215546Sopenharmony_ci D3D12_CPU_DESCRIPTOR_HANDLE view_handle = 870bf215546Sopenharmony_ci dzn_descriptor_heap_get_cpu_handle(heap, desc_offset); 871bf215546Sopenharmony_ci struct dzn_image *image = container_of(iview->vk.image, struct dzn_image, vk); 872bf215546Sopenharmony_ci 873bf215546Sopenharmony_ci if (writeable) { 874bf215546Sopenharmony_ci ID3D12Device1_CreateUnorderedAccessView(heap->dev, image->res, NULL, &iview->uav_desc, view_handle); 875bf215546Sopenharmony_ci } else if (cube_as_2darray && 876bf215546Sopenharmony_ci (iview->srv_desc.ViewDimension == D3D12_SRV_DIMENSION_TEXTURECUBEARRAY || 877bf215546Sopenharmony_ci iview->srv_desc.ViewDimension == D3D12_SRV_DIMENSION_TEXTURECUBE)) { 878bf215546Sopenharmony_ci D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = iview->srv_desc; 879bf215546Sopenharmony_ci srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY; 880bf215546Sopenharmony_ci srv_desc.Texture2DArray.PlaneSlice = 0; 881bf215546Sopenharmony_ci if (iview->srv_desc.ViewDimension == D3D12_SRV_DIMENSION_TEXTURECUBEARRAY) { 882bf215546Sopenharmony_ci srv_desc.Texture2DArray.MostDetailedMip = 883bf215546Sopenharmony_ci iview->srv_desc.TextureCubeArray.MostDetailedMip; 884bf215546Sopenharmony_ci srv_desc.Texture2DArray.MipLevels = 885bf215546Sopenharmony_ci iview->srv_desc.TextureCubeArray.MipLevels; 886bf215546Sopenharmony_ci srv_desc.Texture2DArray.FirstArraySlice = 887bf215546Sopenharmony_ci iview->srv_desc.TextureCubeArray.First2DArrayFace; 888bf215546Sopenharmony_ci srv_desc.Texture2DArray.ArraySize = 889bf215546Sopenharmony_ci iview->srv_desc.TextureCubeArray.NumCubes * 6; 890bf215546Sopenharmony_ci } else { 891bf215546Sopenharmony_ci srv_desc.Texture2DArray.MostDetailedMip = 892bf215546Sopenharmony_ci iview->srv_desc.TextureCube.MostDetailedMip; 893bf215546Sopenharmony_ci srv_desc.Texture2DArray.MipLevels = 894bf215546Sopenharmony_ci iview->srv_desc.TextureCube.MipLevels; 895bf215546Sopenharmony_ci srv_desc.Texture2DArray.FirstArraySlice = 0; 896bf215546Sopenharmony_ci srv_desc.Texture2DArray.ArraySize = 6; 897bf215546Sopenharmony_ci } 898bf215546Sopenharmony_ci 899bf215546Sopenharmony_ci ID3D12Device1_CreateShaderResourceView(heap->dev, image->res, &srv_desc, view_handle); 900bf215546Sopenharmony_ci } else { 901bf215546Sopenharmony_ci ID3D12Device1_CreateShaderResourceView(heap->dev, image->res, &iview->srv_desc, view_handle); 902bf215546Sopenharmony_ci } 903bf215546Sopenharmony_ci} 904bf215546Sopenharmony_ci 905bf215546Sopenharmony_cistatic void 906bf215546Sopenharmony_cidzn_descriptor_heap_write_buffer_view_desc(struct dzn_descriptor_heap *heap, 907bf215546Sopenharmony_ci uint32_t desc_offset, 908bf215546Sopenharmony_ci bool writeable, 909bf215546Sopenharmony_ci const struct dzn_buffer_view *bview) 910bf215546Sopenharmony_ci{ 911bf215546Sopenharmony_ci D3D12_CPU_DESCRIPTOR_HANDLE view_handle = 912bf215546Sopenharmony_ci dzn_descriptor_heap_get_cpu_handle(heap, desc_offset); 913bf215546Sopenharmony_ci 914bf215546Sopenharmony_ci if (writeable) 915bf215546Sopenharmony_ci ID3D12Device1_CreateUnorderedAccessView(heap->dev, bview->buffer->res, NULL, &bview->uav_desc, view_handle); 916bf215546Sopenharmony_ci else 917bf215546Sopenharmony_ci ID3D12Device1_CreateShaderResourceView(heap->dev, bview->buffer->res, &bview->srv_desc, view_handle); 918bf215546Sopenharmony_ci} 919bf215546Sopenharmony_ci 920bf215546Sopenharmony_civoid 921bf215546Sopenharmony_cidzn_descriptor_heap_write_buffer_desc(struct dzn_descriptor_heap *heap, 922bf215546Sopenharmony_ci uint32_t desc_offset, 923bf215546Sopenharmony_ci bool writeable, 924bf215546Sopenharmony_ci const struct dzn_buffer_desc *info) 925bf215546Sopenharmony_ci{ 926bf215546Sopenharmony_ci D3D12_CPU_DESCRIPTOR_HANDLE view_handle = 927bf215546Sopenharmony_ci dzn_descriptor_heap_get_cpu_handle(heap, desc_offset); 928bf215546Sopenharmony_ci 929bf215546Sopenharmony_ci VkDeviceSize size = 930bf215546Sopenharmony_ci info->range == VK_WHOLE_SIZE ? 931bf215546Sopenharmony_ci info->buffer->size - info->offset : 932bf215546Sopenharmony_ci info->range; 933bf215546Sopenharmony_ci 934bf215546Sopenharmony_ci if (info->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || 935bf215546Sopenharmony_ci info->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) { 936bf215546Sopenharmony_ci assert(!writeable); 937bf215546Sopenharmony_ci D3D12_CONSTANT_BUFFER_VIEW_DESC cbv_desc = { 938bf215546Sopenharmony_ci .BufferLocation = ID3D12Resource_GetGPUVirtualAddress(info->buffer->res) + info->offset, 939bf215546Sopenharmony_ci .SizeInBytes = ALIGN_POT(size, 256), 940bf215546Sopenharmony_ci }; 941bf215546Sopenharmony_ci ID3D12Device1_CreateConstantBufferView(heap->dev, &cbv_desc, view_handle); 942bf215546Sopenharmony_ci } else if (writeable) { 943bf215546Sopenharmony_ci D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc = { 944bf215546Sopenharmony_ci .Format = DXGI_FORMAT_R32_TYPELESS, 945bf215546Sopenharmony_ci .ViewDimension = D3D12_UAV_DIMENSION_BUFFER, 946bf215546Sopenharmony_ci .Buffer = { 947bf215546Sopenharmony_ci .FirstElement = info->offset / sizeof(uint32_t), 948bf215546Sopenharmony_ci .NumElements = (UINT)size / sizeof(uint32_t), 949bf215546Sopenharmony_ci .Flags = D3D12_BUFFER_UAV_FLAG_RAW, 950bf215546Sopenharmony_ci }, 951bf215546Sopenharmony_ci }; 952bf215546Sopenharmony_ci ID3D12Device1_CreateUnorderedAccessView(heap->dev, info->buffer->res, NULL, &uav_desc, view_handle); 953bf215546Sopenharmony_ci } else { 954bf215546Sopenharmony_ci D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = { 955bf215546Sopenharmony_ci .Format = DXGI_FORMAT_R32_TYPELESS, 956bf215546Sopenharmony_ci .ViewDimension = D3D12_SRV_DIMENSION_BUFFER, 957bf215546Sopenharmony_ci .Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, 958bf215546Sopenharmony_ci .Buffer = { 959bf215546Sopenharmony_ci .FirstElement = info->offset / sizeof(uint32_t), 960bf215546Sopenharmony_ci .NumElements = (UINT)size / sizeof(uint32_t), 961bf215546Sopenharmony_ci .Flags = D3D12_BUFFER_SRV_FLAG_RAW, 962bf215546Sopenharmony_ci }, 963bf215546Sopenharmony_ci }; 964bf215546Sopenharmony_ci ID3D12Device1_CreateShaderResourceView(heap->dev, info->buffer->res, &srv_desc, view_handle); 965bf215546Sopenharmony_ci } 966bf215546Sopenharmony_ci} 967bf215546Sopenharmony_ci 968bf215546Sopenharmony_civoid 969bf215546Sopenharmony_cidzn_descriptor_heap_copy(struct dzn_descriptor_heap *dst_heap, 970bf215546Sopenharmony_ci uint32_t dst_offset, 971bf215546Sopenharmony_ci const struct dzn_descriptor_heap *src_heap, 972bf215546Sopenharmony_ci uint32_t src_offset, 973bf215546Sopenharmony_ci uint32_t desc_count) 974bf215546Sopenharmony_ci{ 975bf215546Sopenharmony_ci D3D12_CPU_DESCRIPTOR_HANDLE dst_handle = 976bf215546Sopenharmony_ci dzn_descriptor_heap_get_cpu_handle(dst_heap, dst_offset); 977bf215546Sopenharmony_ci D3D12_CPU_DESCRIPTOR_HANDLE src_handle = 978bf215546Sopenharmony_ci dzn_descriptor_heap_get_cpu_handle(src_heap, src_offset); 979bf215546Sopenharmony_ci 980bf215546Sopenharmony_ci ID3D12Device1_CopyDescriptorsSimple(dst_heap->dev, desc_count, 981bf215546Sopenharmony_ci dst_handle, 982bf215546Sopenharmony_ci src_handle, 983bf215546Sopenharmony_ci dst_heap->type); 984bf215546Sopenharmony_ci} 985bf215546Sopenharmony_ci 986bf215546Sopenharmony_cistruct dzn_descriptor_set_ptr { 987bf215546Sopenharmony_ci uint32_t binding, elem; 988bf215546Sopenharmony_ci}; 989bf215546Sopenharmony_ci 990bf215546Sopenharmony_cistatic void 991bf215546Sopenharmony_cidzn_descriptor_set_ptr_validate(const struct dzn_descriptor_set_layout *layout, 992bf215546Sopenharmony_ci struct dzn_descriptor_set_ptr *ptr) 993bf215546Sopenharmony_ci{ 994bf215546Sopenharmony_ci 995bf215546Sopenharmony_ci if (ptr->binding >= layout->binding_count) { 996bf215546Sopenharmony_ci ptr->binding = ~0; 997bf215546Sopenharmony_ci ptr->elem = ~0; 998bf215546Sopenharmony_ci return; 999bf215546Sopenharmony_ci } 1000bf215546Sopenharmony_ci 1001bf215546Sopenharmony_ci uint32_t desc_count = 1002bf215546Sopenharmony_ci dzn_descriptor_set_layout_get_desc_count(layout, ptr->binding); 1003bf215546Sopenharmony_ci if (ptr->elem >= desc_count) { 1004bf215546Sopenharmony_ci ptr->binding = ~0; 1005bf215546Sopenharmony_ci ptr->elem = ~0; 1006bf215546Sopenharmony_ci } 1007bf215546Sopenharmony_ci} 1008bf215546Sopenharmony_ci 1009bf215546Sopenharmony_cistatic void 1010bf215546Sopenharmony_cidzn_descriptor_set_ptr_init(const struct dzn_descriptor_set_layout *layout, 1011bf215546Sopenharmony_ci struct dzn_descriptor_set_ptr *ptr, 1012bf215546Sopenharmony_ci uint32_t binding, uint32_t elem) 1013bf215546Sopenharmony_ci{ 1014bf215546Sopenharmony_ci ptr->binding = binding; 1015bf215546Sopenharmony_ci ptr->elem = elem; 1016bf215546Sopenharmony_ci dzn_descriptor_set_ptr_validate(layout, ptr); 1017bf215546Sopenharmony_ci} 1018bf215546Sopenharmony_ci 1019bf215546Sopenharmony_cistatic void 1020bf215546Sopenharmony_cidzn_descriptor_set_ptr_move(const struct dzn_descriptor_set_layout *layout, 1021bf215546Sopenharmony_ci struct dzn_descriptor_set_ptr *ptr, 1022bf215546Sopenharmony_ci uint32_t count) 1023bf215546Sopenharmony_ci{ 1024bf215546Sopenharmony_ci if (ptr->binding == ~0) 1025bf215546Sopenharmony_ci return; 1026bf215546Sopenharmony_ci 1027bf215546Sopenharmony_ci while (count) { 1028bf215546Sopenharmony_ci uint32_t desc_count = 1029bf215546Sopenharmony_ci dzn_descriptor_set_layout_get_desc_count(layout, ptr->binding); 1030bf215546Sopenharmony_ci 1031bf215546Sopenharmony_ci if (count >= desc_count - ptr->elem) { 1032bf215546Sopenharmony_ci count -= desc_count - ptr->elem; 1033bf215546Sopenharmony_ci ptr->binding++; 1034bf215546Sopenharmony_ci ptr->elem = 0; 1035bf215546Sopenharmony_ci } else { 1036bf215546Sopenharmony_ci ptr->elem += count; 1037bf215546Sopenharmony_ci count = 0; 1038bf215546Sopenharmony_ci } 1039bf215546Sopenharmony_ci } 1040bf215546Sopenharmony_ci 1041bf215546Sopenharmony_ci dzn_descriptor_set_ptr_validate(layout, ptr); 1042bf215546Sopenharmony_ci} 1043bf215546Sopenharmony_ci 1044bf215546Sopenharmony_cistatic bool 1045bf215546Sopenharmony_cidzn_descriptor_set_ptr_is_valid(const struct dzn_descriptor_set_ptr *ptr) 1046bf215546Sopenharmony_ci{ 1047bf215546Sopenharmony_ci return ptr->binding != ~0 && ptr->elem != ~0; 1048bf215546Sopenharmony_ci} 1049bf215546Sopenharmony_ci 1050bf215546Sopenharmony_cistatic uint32_t 1051bf215546Sopenharmony_cidzn_descriptor_set_remaining_descs_in_binding(const struct dzn_descriptor_set_layout *layout, 1052bf215546Sopenharmony_ci const struct dzn_descriptor_set_ptr *ptr) 1053bf215546Sopenharmony_ci{ 1054bf215546Sopenharmony_ci if (ptr->binding >= layout->binding_count) 1055bf215546Sopenharmony_ci return 0; 1056bf215546Sopenharmony_ci 1057bf215546Sopenharmony_ci uint32_t desc_count = 1058bf215546Sopenharmony_ci dzn_descriptor_set_layout_get_desc_count(layout, ptr->binding); 1059bf215546Sopenharmony_ci 1060bf215546Sopenharmony_ci return desc_count >= ptr->elem ? desc_count - ptr->elem : 0; 1061bf215546Sopenharmony_ci} 1062bf215546Sopenharmony_ci 1063bf215546Sopenharmony_ci 1064bf215546Sopenharmony_cistatic uint32_t 1065bf215546Sopenharmony_cidzn_descriptor_set_ptr_get_heap_offset(const struct dzn_descriptor_set_layout *layout, 1066bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE type, 1067bf215546Sopenharmony_ci const struct dzn_descriptor_set_ptr *ptr, 1068bf215546Sopenharmony_ci bool writeable) 1069bf215546Sopenharmony_ci{ 1070bf215546Sopenharmony_ci if (ptr->binding == ~0) 1071bf215546Sopenharmony_ci return ~0; 1072bf215546Sopenharmony_ci 1073bf215546Sopenharmony_ci uint32_t base = 1074bf215546Sopenharmony_ci dzn_descriptor_set_layout_get_heap_offset(layout, ptr->binding, type, writeable); 1075bf215546Sopenharmony_ci if (base == ~0) 1076bf215546Sopenharmony_ci return ~0; 1077bf215546Sopenharmony_ci 1078bf215546Sopenharmony_ci return base + ptr->elem; 1079bf215546Sopenharmony_ci} 1080bf215546Sopenharmony_ci 1081bf215546Sopenharmony_cistatic void 1082bf215546Sopenharmony_cidzn_descriptor_set_write_sampler_desc(struct dzn_descriptor_set *set, 1083bf215546Sopenharmony_ci uint32_t heap_offset, 1084bf215546Sopenharmony_ci const struct dzn_sampler *sampler) 1085bf215546Sopenharmony_ci{ 1086bf215546Sopenharmony_ci if (heap_offset == ~0) 1087bf215546Sopenharmony_ci return; 1088bf215546Sopenharmony_ci 1089bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; 1090bf215546Sopenharmony_ci 1091bf215546Sopenharmony_ci mtx_lock(&set->pool->defragment_lock); 1092bf215546Sopenharmony_ci dzn_descriptor_heap_write_sampler_desc(&set->pool->heaps[type], 1093bf215546Sopenharmony_ci set->heap_offsets[type] + heap_offset, 1094bf215546Sopenharmony_ci sampler); 1095bf215546Sopenharmony_ci mtx_unlock(&set->pool->defragment_lock); 1096bf215546Sopenharmony_ci} 1097bf215546Sopenharmony_ci 1098bf215546Sopenharmony_cistatic void 1099bf215546Sopenharmony_cidzn_descriptor_set_ptr_write_sampler_desc(struct dzn_descriptor_set *set, 1100bf215546Sopenharmony_ci const struct dzn_descriptor_set_ptr *ptr, 1101bf215546Sopenharmony_ci const struct dzn_sampler *sampler) 1102bf215546Sopenharmony_ci{ 1103bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; 1104bf215546Sopenharmony_ci uint32_t heap_offset = 1105bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_heap_offset(set->layout, type, ptr, false); 1106bf215546Sopenharmony_ci 1107bf215546Sopenharmony_ci dzn_descriptor_set_write_sampler_desc(set, heap_offset, sampler); 1108bf215546Sopenharmony_ci} 1109bf215546Sopenharmony_ci 1110bf215546Sopenharmony_cistatic uint32_t 1111bf215546Sopenharmony_cidzn_descriptor_set_ptr_get_dynamic_buffer_idx(const struct dzn_descriptor_set_layout *layout, 1112bf215546Sopenharmony_ci const struct dzn_descriptor_set_ptr *ptr) 1113bf215546Sopenharmony_ci{ 1114bf215546Sopenharmony_ci if (ptr->binding == ~0) 1115bf215546Sopenharmony_ci return ~0; 1116bf215546Sopenharmony_ci 1117bf215546Sopenharmony_ci uint32_t base = layout->bindings[ptr->binding].dynamic_buffer_idx; 1118bf215546Sopenharmony_ci 1119bf215546Sopenharmony_ci if (base == ~0) 1120bf215546Sopenharmony_ci return ~0; 1121bf215546Sopenharmony_ci 1122bf215546Sopenharmony_ci return base + ptr->elem; 1123bf215546Sopenharmony_ci} 1124bf215546Sopenharmony_ci 1125bf215546Sopenharmony_cistatic void 1126bf215546Sopenharmony_cidzn_descriptor_set_write_dynamic_buffer_desc(struct dzn_descriptor_set *set, 1127bf215546Sopenharmony_ci uint32_t dynamic_buffer_idx, 1128bf215546Sopenharmony_ci const struct dzn_buffer_desc *info) 1129bf215546Sopenharmony_ci{ 1130bf215546Sopenharmony_ci if (dynamic_buffer_idx == ~0) 1131bf215546Sopenharmony_ci return; 1132bf215546Sopenharmony_ci 1133bf215546Sopenharmony_ci assert(dynamic_buffer_idx < set->layout->dynamic_buffers.count); 1134bf215546Sopenharmony_ci set->dynamic_buffers[dynamic_buffer_idx] = *info; 1135bf215546Sopenharmony_ci} 1136bf215546Sopenharmony_ci 1137bf215546Sopenharmony_cistatic void 1138bf215546Sopenharmony_cidzn_descriptor_set_ptr_write_dynamic_buffer_desc(struct dzn_descriptor_set *set, 1139bf215546Sopenharmony_ci const struct dzn_descriptor_set_ptr *ptr, 1140bf215546Sopenharmony_ci const struct dzn_buffer_desc *info) 1141bf215546Sopenharmony_ci{ 1142bf215546Sopenharmony_ci uint32_t dynamic_buffer_idx = 1143bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_dynamic_buffer_idx(set->layout, ptr); 1144bf215546Sopenharmony_ci 1145bf215546Sopenharmony_ci dzn_descriptor_set_write_dynamic_buffer_desc(set, dynamic_buffer_idx, info); 1146bf215546Sopenharmony_ci} 1147bf215546Sopenharmony_ci 1148bf215546Sopenharmony_cistatic VkDescriptorType 1149bf215546Sopenharmony_cidzn_descriptor_set_ptr_get_vk_type(const struct dzn_descriptor_set_layout *layout, 1150bf215546Sopenharmony_ci const struct dzn_descriptor_set_ptr *ptr) 1151bf215546Sopenharmony_ci{ 1152bf215546Sopenharmony_ci if (ptr->binding >= layout->binding_count) 1153bf215546Sopenharmony_ci return (VkDescriptorType)~0; 1154bf215546Sopenharmony_ci 1155bf215546Sopenharmony_ci return layout->bindings[ptr->binding].type; 1156bf215546Sopenharmony_ci} 1157bf215546Sopenharmony_ci 1158bf215546Sopenharmony_cistatic void 1159bf215546Sopenharmony_cidzn_descriptor_set_write_image_view_desc(struct dzn_descriptor_set *set, 1160bf215546Sopenharmony_ci uint32_t heap_offset, 1161bf215546Sopenharmony_ci uint32_t alt_heap_offset, 1162bf215546Sopenharmony_ci bool cube_as_2darray, 1163bf215546Sopenharmony_ci const struct dzn_image_view *iview) 1164bf215546Sopenharmony_ci{ 1165bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; 1166bf215546Sopenharmony_ci 1167bf215546Sopenharmony_ci if (heap_offset == ~0) 1168bf215546Sopenharmony_ci return; 1169bf215546Sopenharmony_ci 1170bf215546Sopenharmony_ci mtx_lock(&set->pool->defragment_lock); 1171bf215546Sopenharmony_ci dzn_descriptor_heap_write_image_view_desc(&set->pool->heaps[type], 1172bf215546Sopenharmony_ci set->heap_offsets[type] + heap_offset, 1173bf215546Sopenharmony_ci false, cube_as_2darray, 1174bf215546Sopenharmony_ci iview); 1175bf215546Sopenharmony_ci 1176bf215546Sopenharmony_ci if (alt_heap_offset != ~0) { 1177bf215546Sopenharmony_ci dzn_descriptor_heap_write_image_view_desc(&set->pool->heaps[type], 1178bf215546Sopenharmony_ci set->heap_offsets[type] + alt_heap_offset, 1179bf215546Sopenharmony_ci true, cube_as_2darray, 1180bf215546Sopenharmony_ci iview); 1181bf215546Sopenharmony_ci } 1182bf215546Sopenharmony_ci mtx_unlock(&set->pool->defragment_lock); 1183bf215546Sopenharmony_ci} 1184bf215546Sopenharmony_ci 1185bf215546Sopenharmony_cistatic void 1186bf215546Sopenharmony_cidzn_descriptor_set_ptr_write_image_view_desc(struct dzn_descriptor_set *set, 1187bf215546Sopenharmony_ci const struct dzn_descriptor_set_ptr *ptr, 1188bf215546Sopenharmony_ci bool cube_as_2darray, 1189bf215546Sopenharmony_ci const struct dzn_image_view *iview) 1190bf215546Sopenharmony_ci{ 1191bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; 1192bf215546Sopenharmony_ci uint32_t heap_offset = 1193bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_heap_offset(set->layout, type, ptr, false); 1194bf215546Sopenharmony_ci uint32_t alt_heap_offset = 1195bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_heap_offset(set->layout, type, ptr, true); 1196bf215546Sopenharmony_ci 1197bf215546Sopenharmony_ci dzn_descriptor_set_write_image_view_desc(set, heap_offset, alt_heap_offset, 1198bf215546Sopenharmony_ci cube_as_2darray, iview); 1199bf215546Sopenharmony_ci} 1200bf215546Sopenharmony_ci 1201bf215546Sopenharmony_cistatic void 1202bf215546Sopenharmony_cidzn_descriptor_set_write_buffer_view_desc(struct dzn_descriptor_set *set, 1203bf215546Sopenharmony_ci uint32_t heap_offset, 1204bf215546Sopenharmony_ci uint32_t alt_heap_offset, 1205bf215546Sopenharmony_ci const struct dzn_buffer_view *bview) 1206bf215546Sopenharmony_ci{ 1207bf215546Sopenharmony_ci if (heap_offset == ~0) 1208bf215546Sopenharmony_ci return; 1209bf215546Sopenharmony_ci 1210bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; 1211bf215546Sopenharmony_ci 1212bf215546Sopenharmony_ci mtx_lock(&set->pool->defragment_lock); 1213bf215546Sopenharmony_ci dzn_descriptor_heap_write_buffer_view_desc(&set->pool->heaps[type], 1214bf215546Sopenharmony_ci set->heap_offsets[type] + 1215bf215546Sopenharmony_ci heap_offset, 1216bf215546Sopenharmony_ci false, bview); 1217bf215546Sopenharmony_ci 1218bf215546Sopenharmony_ci if (alt_heap_offset != ~0) { 1219bf215546Sopenharmony_ci dzn_descriptor_heap_write_buffer_view_desc(&set->pool->heaps[type], 1220bf215546Sopenharmony_ci set->heap_offsets[type] + 1221bf215546Sopenharmony_ci alt_heap_offset, 1222bf215546Sopenharmony_ci true, bview); 1223bf215546Sopenharmony_ci } 1224bf215546Sopenharmony_ci mtx_unlock(&set->pool->defragment_lock); 1225bf215546Sopenharmony_ci} 1226bf215546Sopenharmony_ci 1227bf215546Sopenharmony_cistatic void 1228bf215546Sopenharmony_cidzn_descriptor_set_ptr_write_buffer_view_desc(struct dzn_descriptor_set *set, 1229bf215546Sopenharmony_ci const struct dzn_descriptor_set_ptr *ptr, 1230bf215546Sopenharmony_ci const struct dzn_buffer_view *bview) 1231bf215546Sopenharmony_ci{ 1232bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; 1233bf215546Sopenharmony_ci uint32_t heap_offset = 1234bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_heap_offset(set->layout, type, ptr, false); 1235bf215546Sopenharmony_ci uint32_t alt_heap_offset = 1236bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_heap_offset(set->layout, type, ptr, true); 1237bf215546Sopenharmony_ci 1238bf215546Sopenharmony_ci dzn_descriptor_set_write_buffer_view_desc(set, heap_offset, alt_heap_offset, bview); 1239bf215546Sopenharmony_ci} 1240bf215546Sopenharmony_ci 1241bf215546Sopenharmony_cistatic void 1242bf215546Sopenharmony_cidzn_descriptor_set_write_buffer_desc(struct dzn_descriptor_set *set, 1243bf215546Sopenharmony_ci uint32_t heap_offset, 1244bf215546Sopenharmony_ci uint32_t alt_heap_offset, 1245bf215546Sopenharmony_ci const struct dzn_buffer_desc *bdesc) 1246bf215546Sopenharmony_ci{ 1247bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; 1248bf215546Sopenharmony_ci if (heap_offset == ~0) 1249bf215546Sopenharmony_ci return; 1250bf215546Sopenharmony_ci 1251bf215546Sopenharmony_ci mtx_lock(&set->pool->defragment_lock); 1252bf215546Sopenharmony_ci dzn_descriptor_heap_write_buffer_desc(&set->pool->heaps[type], 1253bf215546Sopenharmony_ci set->heap_offsets[type] + heap_offset, 1254bf215546Sopenharmony_ci false, bdesc); 1255bf215546Sopenharmony_ci 1256bf215546Sopenharmony_ci if (alt_heap_offset != ~0) { 1257bf215546Sopenharmony_ci dzn_descriptor_heap_write_buffer_desc(&set->pool->heaps[type], 1258bf215546Sopenharmony_ci set->heap_offsets[type] + 1259bf215546Sopenharmony_ci alt_heap_offset, 1260bf215546Sopenharmony_ci true, bdesc); 1261bf215546Sopenharmony_ci } 1262bf215546Sopenharmony_ci mtx_unlock(&set->pool->defragment_lock); 1263bf215546Sopenharmony_ci} 1264bf215546Sopenharmony_ci 1265bf215546Sopenharmony_cistatic void 1266bf215546Sopenharmony_cidzn_descriptor_set_ptr_write_buffer_desc(struct dzn_descriptor_set *set, 1267bf215546Sopenharmony_ci const struct dzn_descriptor_set_ptr *ptr, 1268bf215546Sopenharmony_ci const struct dzn_buffer_desc *bdesc) 1269bf215546Sopenharmony_ci{ 1270bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; 1271bf215546Sopenharmony_ci uint32_t heap_offset = 1272bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_heap_offset(set->layout, type, ptr, false); 1273bf215546Sopenharmony_ci uint32_t alt_heap_offset = 1274bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_heap_offset(set->layout, type, ptr, true); 1275bf215546Sopenharmony_ci 1276bf215546Sopenharmony_ci dzn_descriptor_set_write_buffer_desc(set, heap_offset, alt_heap_offset, bdesc); 1277bf215546Sopenharmony_ci} 1278bf215546Sopenharmony_ci 1279bf215546Sopenharmony_cistatic void 1280bf215546Sopenharmony_cidzn_descriptor_set_init(struct dzn_descriptor_set *set, 1281bf215546Sopenharmony_ci struct dzn_device *device, 1282bf215546Sopenharmony_ci struct dzn_descriptor_pool *pool, 1283bf215546Sopenharmony_ci struct dzn_descriptor_set_layout *layout) 1284bf215546Sopenharmony_ci{ 1285bf215546Sopenharmony_ci vk_object_base_init(&device->vk, &set->base, VK_OBJECT_TYPE_DESCRIPTOR_SET); 1286bf215546Sopenharmony_ci 1287bf215546Sopenharmony_ci set->pool = pool; 1288bf215546Sopenharmony_ci set->layout = layout; 1289bf215546Sopenharmony_ci 1290bf215546Sopenharmony_ci mtx_lock(&pool->defragment_lock); 1291bf215546Sopenharmony_ci dzn_foreach_pool_type(type) { 1292bf215546Sopenharmony_ci set->heap_offsets[type] = pool->free_offset[type]; 1293bf215546Sopenharmony_ci set->heap_sizes[type] = layout->range_desc_count[type]; 1294bf215546Sopenharmony_ci set->pool->free_offset[type] += layout->range_desc_count[type]; 1295bf215546Sopenharmony_ci } 1296bf215546Sopenharmony_ci mtx_unlock(&pool->defragment_lock); 1297bf215546Sopenharmony_ci 1298bf215546Sopenharmony_ci /* Pre-fill the immutable samplers */ 1299bf215546Sopenharmony_ci if (layout->immutable_sampler_count) { 1300bf215546Sopenharmony_ci for (uint32_t b = 0; b < layout->binding_count; b++) { 1301bf215546Sopenharmony_ci bool has_samplers = 1302bf215546Sopenharmony_ci dzn_desc_type_has_sampler(layout->bindings[b].type); 1303bf215546Sopenharmony_ci 1304bf215546Sopenharmony_ci if (!has_samplers || layout->bindings[b].immutable_sampler_idx == ~0) 1305bf215546Sopenharmony_ci continue; 1306bf215546Sopenharmony_ci 1307bf215546Sopenharmony_ci struct dzn_descriptor_set_ptr ptr; 1308bf215546Sopenharmony_ci const struct dzn_sampler **sampler = 1309bf215546Sopenharmony_ci &layout->immutable_samplers[layout->bindings[b].immutable_sampler_idx]; 1310bf215546Sopenharmony_ci for (dzn_descriptor_set_ptr_init(set->layout, &ptr, b, 0); 1311bf215546Sopenharmony_ci dzn_descriptor_set_ptr_is_valid(&ptr); 1312bf215546Sopenharmony_ci dzn_descriptor_set_ptr_move(set->layout, &ptr, 1)) { 1313bf215546Sopenharmony_ci dzn_descriptor_set_ptr_write_sampler_desc(set, &ptr, *sampler); 1314bf215546Sopenharmony_ci sampler++; 1315bf215546Sopenharmony_ci } 1316bf215546Sopenharmony_ci } 1317bf215546Sopenharmony_ci } 1318bf215546Sopenharmony_ci} 1319bf215546Sopenharmony_ci 1320bf215546Sopenharmony_cistatic void 1321bf215546Sopenharmony_cidzn_descriptor_set_finish(struct dzn_descriptor_set *set) 1322bf215546Sopenharmony_ci{ 1323bf215546Sopenharmony_ci vk_object_base_finish(&set->base); 1324bf215546Sopenharmony_ci set->pool = NULL; 1325bf215546Sopenharmony_ci set->layout = NULL; 1326bf215546Sopenharmony_ci} 1327bf215546Sopenharmony_ci 1328bf215546Sopenharmony_cistatic void 1329bf215546Sopenharmony_cidzn_descriptor_pool_destroy(struct dzn_descriptor_pool *pool, 1330bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 1331bf215546Sopenharmony_ci{ 1332bf215546Sopenharmony_ci if (!pool) 1333bf215546Sopenharmony_ci return; 1334bf215546Sopenharmony_ci 1335bf215546Sopenharmony_ci struct dzn_device *device = container_of(pool->base.device, struct dzn_device, vk); 1336bf215546Sopenharmony_ci 1337bf215546Sopenharmony_ci dzn_foreach_pool_type (type) { 1338bf215546Sopenharmony_ci if (pool->desc_count[type]) 1339bf215546Sopenharmony_ci dzn_descriptor_heap_finish(&pool->heaps[type]); 1340bf215546Sopenharmony_ci } 1341bf215546Sopenharmony_ci 1342bf215546Sopenharmony_ci vk_object_base_finish(&pool->base); 1343bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, pool); 1344bf215546Sopenharmony_ci} 1345bf215546Sopenharmony_ci 1346bf215546Sopenharmony_cistatic VkResult 1347bf215546Sopenharmony_cidzn_descriptor_pool_create(struct dzn_device *device, 1348bf215546Sopenharmony_ci const VkDescriptorPoolCreateInfo *pCreateInfo, 1349bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 1350bf215546Sopenharmony_ci VkDescriptorPool *out) 1351bf215546Sopenharmony_ci{ 1352bf215546Sopenharmony_ci VK_MULTIALLOC(ma); 1353bf215546Sopenharmony_ci VK_MULTIALLOC_DECL(&ma, struct dzn_descriptor_pool, pool, 1); 1354bf215546Sopenharmony_ci VK_MULTIALLOC_DECL(&ma, struct dzn_descriptor_set, sets, pCreateInfo->maxSets); 1355bf215546Sopenharmony_ci 1356bf215546Sopenharmony_ci if (!vk_multialloc_zalloc2(&ma, &device->vk.alloc, pAllocator, 1357bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)) 1358bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 1359bf215546Sopenharmony_ci 1360bf215546Sopenharmony_ci pool->alloc = pAllocator ? *pAllocator : device->vk.alloc; 1361bf215546Sopenharmony_ci pool->sets = sets; 1362bf215546Sopenharmony_ci pool->set_count = pCreateInfo->maxSets; 1363bf215546Sopenharmony_ci mtx_init(&pool->defragment_lock, mtx_plain); 1364bf215546Sopenharmony_ci 1365bf215546Sopenharmony_ci vk_object_base_init(&device->vk, &pool->base, VK_OBJECT_TYPE_DESCRIPTOR_POOL); 1366bf215546Sopenharmony_ci 1367bf215546Sopenharmony_ci for (uint32_t p = 0; p < pCreateInfo->poolSizeCount; p++) { 1368bf215546Sopenharmony_ci VkDescriptorType type = pCreateInfo->pPoolSizes[p].type; 1369bf215546Sopenharmony_ci uint32_t num_desc = pCreateInfo->pPoolSizes[p].descriptorCount; 1370bf215546Sopenharmony_ci 1371bf215546Sopenharmony_ci switch (type) { 1372bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 1373bf215546Sopenharmony_ci pool->desc_count[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER] += num_desc; 1374bf215546Sopenharmony_ci break; 1375bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 1376bf215546Sopenharmony_ci pool->desc_count[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] += num_desc; 1377bf215546Sopenharmony_ci pool->desc_count[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER] += num_desc; 1378bf215546Sopenharmony_ci break; 1379bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 1380bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 1381bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 1382bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 1383bf215546Sopenharmony_ci pool->desc_count[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] += num_desc; 1384bf215546Sopenharmony_ci break; 1385bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 1386bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 1387bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 1388bf215546Sopenharmony_ci /* Reserve one UAV and one SRV slot for those. */ 1389bf215546Sopenharmony_ci pool->desc_count[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] += num_desc * 2; 1390bf215546Sopenharmony_ci break; 1391bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 1392bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 1393bf215546Sopenharmony_ci break; 1394bf215546Sopenharmony_ci default: 1395bf215546Sopenharmony_ci unreachable("Unsupported desc type"); 1396bf215546Sopenharmony_ci } 1397bf215546Sopenharmony_ci } 1398bf215546Sopenharmony_ci 1399bf215546Sopenharmony_ci dzn_foreach_pool_type (type) { 1400bf215546Sopenharmony_ci if (!pool->desc_count[type]) 1401bf215546Sopenharmony_ci continue; 1402bf215546Sopenharmony_ci 1403bf215546Sopenharmony_ci VkResult result = 1404bf215546Sopenharmony_ci dzn_descriptor_heap_init(&pool->heaps[type], device, type, pool->desc_count[type], false); 1405bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 1406bf215546Sopenharmony_ci dzn_descriptor_pool_destroy(pool, pAllocator); 1407bf215546Sopenharmony_ci return result; 1408bf215546Sopenharmony_ci } 1409bf215546Sopenharmony_ci } 1410bf215546Sopenharmony_ci 1411bf215546Sopenharmony_ci *out = dzn_descriptor_pool_to_handle(pool); 1412bf215546Sopenharmony_ci return VK_SUCCESS; 1413bf215546Sopenharmony_ci} 1414bf215546Sopenharmony_ci 1415bf215546Sopenharmony_cistatic VkResult 1416bf215546Sopenharmony_cidzn_descriptor_pool_defragment_heap(struct dzn_descriptor_pool *pool, 1417bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE type) 1418bf215546Sopenharmony_ci{ 1419bf215546Sopenharmony_ci struct dzn_device *device = container_of(pool->base.device, struct dzn_device, vk); 1420bf215546Sopenharmony_ci struct dzn_descriptor_heap new_heap; 1421bf215546Sopenharmony_ci 1422bf215546Sopenharmony_ci VkResult result = 1423bf215546Sopenharmony_ci dzn_descriptor_heap_init(&new_heap, device, type, 1424bf215546Sopenharmony_ci pool->heaps[type].desc_count, 1425bf215546Sopenharmony_ci false); 1426bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1427bf215546Sopenharmony_ci return result; 1428bf215546Sopenharmony_ci 1429bf215546Sopenharmony_ci mtx_lock(&pool->defragment_lock); 1430bf215546Sopenharmony_ci uint32_t heap_offset = 0; 1431bf215546Sopenharmony_ci for (uint32_t s = 0; s < pool->set_count; s++) { 1432bf215546Sopenharmony_ci if (!pool->sets[s].layout) 1433bf215546Sopenharmony_ci continue; 1434bf215546Sopenharmony_ci 1435bf215546Sopenharmony_ci dzn_descriptor_heap_copy(&new_heap, heap_offset, 1436bf215546Sopenharmony_ci &pool->heaps[type], 1437bf215546Sopenharmony_ci pool->sets[s].heap_offsets[type], 1438bf215546Sopenharmony_ci pool->sets[s].heap_sizes[type]); 1439bf215546Sopenharmony_ci pool->sets[s].heap_offsets[type] = heap_offset; 1440bf215546Sopenharmony_ci heap_offset += pool->sets[s].heap_sizes[type]; 1441bf215546Sopenharmony_ci } 1442bf215546Sopenharmony_ci mtx_unlock(&pool->defragment_lock); 1443bf215546Sopenharmony_ci 1444bf215546Sopenharmony_ci dzn_descriptor_heap_finish(&pool->heaps[type]); 1445bf215546Sopenharmony_ci pool->heaps[type] = new_heap; 1446bf215546Sopenharmony_ci 1447bf215546Sopenharmony_ci return VK_SUCCESS; 1448bf215546Sopenharmony_ci} 1449bf215546Sopenharmony_ci 1450bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 1451bf215546Sopenharmony_cidzn_CreateDescriptorPool(VkDevice device, 1452bf215546Sopenharmony_ci const VkDescriptorPoolCreateInfo *pCreateInfo, 1453bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 1454bf215546Sopenharmony_ci VkDescriptorPool *pDescriptorPool) 1455bf215546Sopenharmony_ci{ 1456bf215546Sopenharmony_ci return dzn_descriptor_pool_create(dzn_device_from_handle(device), 1457bf215546Sopenharmony_ci pCreateInfo, pAllocator, pDescriptorPool); 1458bf215546Sopenharmony_ci} 1459bf215546Sopenharmony_ci 1460bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1461bf215546Sopenharmony_cidzn_DestroyDescriptorPool(VkDevice device, 1462bf215546Sopenharmony_ci VkDescriptorPool descriptorPool, 1463bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 1464bf215546Sopenharmony_ci{ 1465bf215546Sopenharmony_ci dzn_descriptor_pool_destroy(dzn_descriptor_pool_from_handle(descriptorPool), 1466bf215546Sopenharmony_ci pAllocator); 1467bf215546Sopenharmony_ci} 1468bf215546Sopenharmony_ci 1469bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 1470bf215546Sopenharmony_cidzn_ResetDescriptorPool(VkDevice device, 1471bf215546Sopenharmony_ci VkDescriptorPool descriptorPool, 1472bf215546Sopenharmony_ci VkDescriptorPoolResetFlags flags) 1473bf215546Sopenharmony_ci{ 1474bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_pool, pool, descriptorPool); 1475bf215546Sopenharmony_ci 1476bf215546Sopenharmony_ci for (uint32_t s = 0; s < pool->set_count; s++) 1477bf215546Sopenharmony_ci dzn_descriptor_set_finish(&pool->sets[s]); 1478bf215546Sopenharmony_ci 1479bf215546Sopenharmony_ci dzn_foreach_pool_type(type) 1480bf215546Sopenharmony_ci pool->free_offset[type] = 0; 1481bf215546Sopenharmony_ci 1482bf215546Sopenharmony_ci return VK_SUCCESS; 1483bf215546Sopenharmony_ci} 1484bf215546Sopenharmony_ci 1485bf215546Sopenharmony_civoid 1486bf215546Sopenharmony_cidzn_descriptor_heap_pool_finish(struct dzn_descriptor_heap_pool *pool) 1487bf215546Sopenharmony_ci{ 1488bf215546Sopenharmony_ci list_splicetail(&pool->active_heaps, &pool->free_heaps); 1489bf215546Sopenharmony_ci list_for_each_entry_safe(struct dzn_descriptor_heap_pool_entry, entry, &pool->free_heaps, link) { 1490bf215546Sopenharmony_ci list_del(&entry->link); 1491bf215546Sopenharmony_ci dzn_descriptor_heap_finish(&entry->heap); 1492bf215546Sopenharmony_ci vk_free(pool->alloc, entry); 1493bf215546Sopenharmony_ci } 1494bf215546Sopenharmony_ci} 1495bf215546Sopenharmony_ci 1496bf215546Sopenharmony_civoid 1497bf215546Sopenharmony_cidzn_descriptor_heap_pool_init(struct dzn_descriptor_heap_pool *pool, 1498bf215546Sopenharmony_ci struct dzn_device *device, 1499bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE type, 1500bf215546Sopenharmony_ci bool shader_visible, 1501bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc) 1502bf215546Sopenharmony_ci{ 1503bf215546Sopenharmony_ci assert(!shader_visible || 1504bf215546Sopenharmony_ci type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || 1505bf215546Sopenharmony_ci type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); 1506bf215546Sopenharmony_ci 1507bf215546Sopenharmony_ci pool->alloc = alloc; 1508bf215546Sopenharmony_ci pool->type = type; 1509bf215546Sopenharmony_ci pool->shader_visible = shader_visible; 1510bf215546Sopenharmony_ci list_inithead(&pool->active_heaps); 1511bf215546Sopenharmony_ci list_inithead(&pool->free_heaps); 1512bf215546Sopenharmony_ci pool->offset = 0; 1513bf215546Sopenharmony_ci pool->desc_sz = ID3D12Device1_GetDescriptorHandleIncrementSize(device->dev, type); 1514bf215546Sopenharmony_ci} 1515bf215546Sopenharmony_ci 1516bf215546Sopenharmony_ciVkResult 1517bf215546Sopenharmony_cidzn_descriptor_heap_pool_alloc_slots(struct dzn_descriptor_heap_pool *pool, 1518bf215546Sopenharmony_ci struct dzn_device *device, uint32_t desc_count, 1519bf215546Sopenharmony_ci struct dzn_descriptor_heap **heap, 1520bf215546Sopenharmony_ci uint32_t *first_slot) 1521bf215546Sopenharmony_ci{ 1522bf215546Sopenharmony_ci struct dzn_descriptor_heap *last_heap = 1523bf215546Sopenharmony_ci list_is_empty(&pool->active_heaps) ? 1524bf215546Sopenharmony_ci NULL : 1525bf215546Sopenharmony_ci &(list_last_entry(&pool->active_heaps, struct dzn_descriptor_heap_pool_entry, link)->heap); 1526bf215546Sopenharmony_ci uint32_t last_heap_desc_count = 1527bf215546Sopenharmony_ci last_heap ? last_heap->desc_count : 0; 1528bf215546Sopenharmony_ci 1529bf215546Sopenharmony_ci if (pool->offset + desc_count > last_heap_desc_count) { 1530bf215546Sopenharmony_ci uint32_t granularity = 1531bf215546Sopenharmony_ci (pool->type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || 1532bf215546Sopenharmony_ci pool->type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) ? 1533bf215546Sopenharmony_ci 64 * 1024 : 4 * 1024; 1534bf215546Sopenharmony_ci uint32_t alloc_step = ALIGN_POT(desc_count * pool->desc_sz, granularity); 1535bf215546Sopenharmony_ci uint32_t heap_desc_count = MAX2(alloc_step / pool->desc_sz, 16); 1536bf215546Sopenharmony_ci 1537bf215546Sopenharmony_ci /* Maximum of 2048 samplers per heap when shader_visible is true. */ 1538bf215546Sopenharmony_ci if (pool->shader_visible && 1539bf215546Sopenharmony_ci pool->type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) { 1540bf215546Sopenharmony_ci assert(desc_count <= MAX_DESCS_PER_SAMPLER_HEAP); 1541bf215546Sopenharmony_ci heap_desc_count = MIN2(heap_desc_count, MAX_DESCS_PER_SAMPLER_HEAP); 1542bf215546Sopenharmony_ci } 1543bf215546Sopenharmony_ci 1544bf215546Sopenharmony_ci struct dzn_descriptor_heap_pool_entry *new_heap = NULL; 1545bf215546Sopenharmony_ci 1546bf215546Sopenharmony_ci list_for_each_entry_safe(struct dzn_descriptor_heap_pool_entry, entry, &pool->free_heaps, link) { 1547bf215546Sopenharmony_ci if (entry->heap.desc_count >= heap_desc_count) { 1548bf215546Sopenharmony_ci new_heap = entry; 1549bf215546Sopenharmony_ci list_del(&entry->link); 1550bf215546Sopenharmony_ci break; 1551bf215546Sopenharmony_ci } 1552bf215546Sopenharmony_ci } 1553bf215546Sopenharmony_ci 1554bf215546Sopenharmony_ci if (!new_heap) { 1555bf215546Sopenharmony_ci new_heap = 1556bf215546Sopenharmony_ci vk_zalloc(pool->alloc, sizeof(*new_heap), 8, 1557bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 1558bf215546Sopenharmony_ci if (!new_heap) 1559bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 1560bf215546Sopenharmony_ci 1561bf215546Sopenharmony_ci VkResult result = 1562bf215546Sopenharmony_ci dzn_descriptor_heap_init(&new_heap->heap, device, pool->type, 1563bf215546Sopenharmony_ci heap_desc_count, pool->shader_visible); 1564bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 1565bf215546Sopenharmony_ci vk_free(&device->vk.alloc, new_heap); 1566bf215546Sopenharmony_ci return result; 1567bf215546Sopenharmony_ci } 1568bf215546Sopenharmony_ci } 1569bf215546Sopenharmony_ci 1570bf215546Sopenharmony_ci list_addtail(&new_heap->link, &pool->active_heaps); 1571bf215546Sopenharmony_ci pool->offset = 0; 1572bf215546Sopenharmony_ci last_heap = &new_heap->heap; 1573bf215546Sopenharmony_ci } 1574bf215546Sopenharmony_ci 1575bf215546Sopenharmony_ci *heap = last_heap; 1576bf215546Sopenharmony_ci *first_slot = pool->offset; 1577bf215546Sopenharmony_ci pool->offset += desc_count; 1578bf215546Sopenharmony_ci return VK_SUCCESS; 1579bf215546Sopenharmony_ci} 1580bf215546Sopenharmony_ci 1581bf215546Sopenharmony_civoid 1582bf215546Sopenharmony_cidzn_descriptor_heap_pool_reset(struct dzn_descriptor_heap_pool *pool) 1583bf215546Sopenharmony_ci{ 1584bf215546Sopenharmony_ci pool->offset = 0; 1585bf215546Sopenharmony_ci list_splicetail(&pool->active_heaps, &pool->free_heaps); 1586bf215546Sopenharmony_ci list_inithead(&pool->active_heaps); 1587bf215546Sopenharmony_ci} 1588bf215546Sopenharmony_ci 1589bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 1590bf215546Sopenharmony_cidzn_AllocateDescriptorSets(VkDevice dev, 1591bf215546Sopenharmony_ci const VkDescriptorSetAllocateInfo *pAllocateInfo, 1592bf215546Sopenharmony_ci VkDescriptorSet *pDescriptorSets) 1593bf215546Sopenharmony_ci{ 1594bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_pool, pool, pAllocateInfo->descriptorPool); 1595bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_device, device, dev); 1596bf215546Sopenharmony_ci VkResult result; 1597bf215546Sopenharmony_ci unsigned i; 1598bf215546Sopenharmony_ci 1599bf215546Sopenharmony_ci if (pAllocateInfo->descriptorSetCount > (pool->set_count - pool->used_set_count)) 1600bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_POOL_MEMORY; 1601bf215546Sopenharmony_ci 1602bf215546Sopenharmony_ci uint32_t set_idx = 0; 1603bf215546Sopenharmony_ci for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) { 1604bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_set_layout, layout, pAllocateInfo->pSetLayouts[i]); 1605bf215546Sopenharmony_ci 1606bf215546Sopenharmony_ci dzn_foreach_pool_type(type) { 1607bf215546Sopenharmony_ci if (pool->used_desc_count[type] + layout->range_desc_count[type] > pool->desc_count[type]) { 1608bf215546Sopenharmony_ci dzn_FreeDescriptorSets(dev, pAllocateInfo->descriptorPool, i, pDescriptorSets); 1609bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_POOL_MEMORY); 1610bf215546Sopenharmony_ci } 1611bf215546Sopenharmony_ci 1612bf215546Sopenharmony_ci if (pool->free_offset[type] + layout->range_desc_count[type] > pool->desc_count[type]) { 1613bf215546Sopenharmony_ci result = dzn_descriptor_pool_defragment_heap(pool, type); 1614bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 1615bf215546Sopenharmony_ci dzn_FreeDescriptorSets(dev, pAllocateInfo->descriptorPool, i, pDescriptorSets); 1616bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_FRAGMENTED_POOL); 1617bf215546Sopenharmony_ci } 1618bf215546Sopenharmony_ci } 1619bf215546Sopenharmony_ci } 1620bf215546Sopenharmony_ci 1621bf215546Sopenharmony_ci struct dzn_descriptor_set *set = NULL; 1622bf215546Sopenharmony_ci for (; set_idx < pool->set_count; set_idx++) { 1623bf215546Sopenharmony_ci if (!pool->sets[set_idx].layout) { 1624bf215546Sopenharmony_ci set = &pool->sets[set_idx]; 1625bf215546Sopenharmony_ci break; 1626bf215546Sopenharmony_ci } 1627bf215546Sopenharmony_ci } 1628bf215546Sopenharmony_ci 1629bf215546Sopenharmony_ci dzn_descriptor_set_init(set, device, pool, layout); 1630bf215546Sopenharmony_ci pDescriptorSets[i] = dzn_descriptor_set_to_handle(set); 1631bf215546Sopenharmony_ci } 1632bf215546Sopenharmony_ci 1633bf215546Sopenharmony_ci return VK_SUCCESS; 1634bf215546Sopenharmony_ci} 1635bf215546Sopenharmony_ci 1636bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 1637bf215546Sopenharmony_cidzn_FreeDescriptorSets(VkDevice dev, 1638bf215546Sopenharmony_ci VkDescriptorPool descriptorPool, 1639bf215546Sopenharmony_ci uint32_t count, 1640bf215546Sopenharmony_ci const VkDescriptorSet *pDescriptorSets) 1641bf215546Sopenharmony_ci{ 1642bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_pool, pool, descriptorPool); 1643bf215546Sopenharmony_ci 1644bf215546Sopenharmony_ci for (uint32_t s = 0; s < count; s++) { 1645bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_set, set, pDescriptorSets[s]); 1646bf215546Sopenharmony_ci 1647bf215546Sopenharmony_ci if (!set) 1648bf215546Sopenharmony_ci continue; 1649bf215546Sopenharmony_ci 1650bf215546Sopenharmony_ci assert(set->pool == pool); 1651bf215546Sopenharmony_ci 1652bf215546Sopenharmony_ci dzn_descriptor_set_finish(set); 1653bf215546Sopenharmony_ci } 1654bf215546Sopenharmony_ci 1655bf215546Sopenharmony_ci mtx_lock(&pool->defragment_lock); 1656bf215546Sopenharmony_ci dzn_foreach_pool_type(type) 1657bf215546Sopenharmony_ci pool->free_offset[type] = 0; 1658bf215546Sopenharmony_ci 1659bf215546Sopenharmony_ci for (uint32_t s = 0; s < pool->set_count; s++) { 1660bf215546Sopenharmony_ci const struct dzn_descriptor_set *set = &pool->sets[s]; 1661bf215546Sopenharmony_ci 1662bf215546Sopenharmony_ci if (set->layout) { 1663bf215546Sopenharmony_ci dzn_foreach_pool_type (type) { 1664bf215546Sopenharmony_ci pool->free_offset[type] = 1665bf215546Sopenharmony_ci MAX2(pool->free_offset[type], 1666bf215546Sopenharmony_ci set->heap_offsets[type] + 1667bf215546Sopenharmony_ci set->layout->range_desc_count[type]); 1668bf215546Sopenharmony_ci } 1669bf215546Sopenharmony_ci } 1670bf215546Sopenharmony_ci } 1671bf215546Sopenharmony_ci mtx_unlock(&pool->defragment_lock); 1672bf215546Sopenharmony_ci 1673bf215546Sopenharmony_ci return VK_SUCCESS; 1674bf215546Sopenharmony_ci} 1675bf215546Sopenharmony_ci 1676bf215546Sopenharmony_cistatic void 1677bf215546Sopenharmony_cidzn_descriptor_set_write(const VkWriteDescriptorSet *pDescriptorWrite) 1678bf215546Sopenharmony_ci{ 1679bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_set, set, pDescriptorWrite->dstSet); 1680bf215546Sopenharmony_ci 1681bf215546Sopenharmony_ci struct dzn_descriptor_set_ptr ptr; 1682bf215546Sopenharmony_ci 1683bf215546Sopenharmony_ci dzn_descriptor_set_ptr_init(set->layout, &ptr, 1684bf215546Sopenharmony_ci pDescriptorWrite->dstBinding, 1685bf215546Sopenharmony_ci pDescriptorWrite->dstArrayElement); 1686bf215546Sopenharmony_ci uint32_t desc_count = pDescriptorWrite->descriptorCount; 1687bf215546Sopenharmony_ci 1688bf215546Sopenharmony_ci uint32_t d = 0; 1689bf215546Sopenharmony_ci bool cube_as_2darray = 1690bf215546Sopenharmony_ci pDescriptorWrite->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 1691bf215546Sopenharmony_ci 1692bf215546Sopenharmony_ci switch (pDescriptorWrite->descriptorType) { 1693bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 1694bf215546Sopenharmony_ci for (; dzn_descriptor_set_ptr_is_valid(&ptr) && d < desc_count; 1695bf215546Sopenharmony_ci dzn_descriptor_set_ptr_move(set->layout, &ptr, 1)) { 1696bf215546Sopenharmony_ci assert(dzn_descriptor_set_ptr_get_vk_type(set->layout, &ptr) == pDescriptorWrite->descriptorType); 1697bf215546Sopenharmony_ci const VkDescriptorImageInfo *pImageInfo = pDescriptorWrite->pImageInfo + d; 1698bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_sampler, sampler, pImageInfo->sampler); 1699bf215546Sopenharmony_ci 1700bf215546Sopenharmony_ci if (sampler) 1701bf215546Sopenharmony_ci dzn_descriptor_set_ptr_write_sampler_desc(set, &ptr, sampler); 1702bf215546Sopenharmony_ci 1703bf215546Sopenharmony_ci d++; 1704bf215546Sopenharmony_ci } 1705bf215546Sopenharmony_ci break; 1706bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 1707bf215546Sopenharmony_ci for (; dzn_descriptor_set_ptr_is_valid(&ptr) && d < desc_count; 1708bf215546Sopenharmony_ci dzn_descriptor_set_ptr_move(set->layout, &ptr, 1)) { 1709bf215546Sopenharmony_ci assert(dzn_descriptor_set_ptr_get_vk_type(set->layout, &ptr) == pDescriptorWrite->descriptorType); 1710bf215546Sopenharmony_ci const VkDescriptorImageInfo *pImageInfo = pDescriptorWrite->pImageInfo + d; 1711bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_sampler, sampler, pImageInfo->sampler); 1712bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_image_view, iview, pImageInfo->imageView); 1713bf215546Sopenharmony_ci 1714bf215546Sopenharmony_ci if (sampler) 1715bf215546Sopenharmony_ci dzn_descriptor_set_ptr_write_sampler_desc(set, &ptr, sampler); 1716bf215546Sopenharmony_ci 1717bf215546Sopenharmony_ci if (iview) 1718bf215546Sopenharmony_ci dzn_descriptor_set_ptr_write_image_view_desc(set, &ptr, cube_as_2darray, iview); 1719bf215546Sopenharmony_ci 1720bf215546Sopenharmony_ci d++; 1721bf215546Sopenharmony_ci } 1722bf215546Sopenharmony_ci break; 1723bf215546Sopenharmony_ci 1724bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 1725bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 1726bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 1727bf215546Sopenharmony_ci for (; dzn_descriptor_set_ptr_is_valid(&ptr) && d < desc_count; 1728bf215546Sopenharmony_ci dzn_descriptor_set_ptr_move(set->layout, &ptr, 1)) { 1729bf215546Sopenharmony_ci assert(dzn_descriptor_set_ptr_get_vk_type(set->layout, &ptr) == pDescriptorWrite->descriptorType); 1730bf215546Sopenharmony_ci const VkDescriptorImageInfo *pImageInfo = pDescriptorWrite->pImageInfo + d; 1731bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_image_view, iview, pImageInfo->imageView); 1732bf215546Sopenharmony_ci 1733bf215546Sopenharmony_ci if (iview) 1734bf215546Sopenharmony_ci dzn_descriptor_set_ptr_write_image_view_desc(set, &ptr, cube_as_2darray, iview); 1735bf215546Sopenharmony_ci 1736bf215546Sopenharmony_ci d++; 1737bf215546Sopenharmony_ci } 1738bf215546Sopenharmony_ci break; 1739bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 1740bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 1741bf215546Sopenharmony_ci for (; dzn_descriptor_set_ptr_is_valid(&ptr) && d < desc_count; 1742bf215546Sopenharmony_ci dzn_descriptor_set_ptr_move(set->layout, &ptr, 1)) { 1743bf215546Sopenharmony_ci assert(dzn_descriptor_set_ptr_get_vk_type(set->layout, &ptr) == pDescriptorWrite->descriptorType); 1744bf215546Sopenharmony_ci const VkDescriptorBufferInfo *binfo = &pDescriptorWrite->pBufferInfo[d]; 1745bf215546Sopenharmony_ci struct dzn_buffer_desc desc = { 1746bf215546Sopenharmony_ci pDescriptorWrite->descriptorType, 1747bf215546Sopenharmony_ci dzn_buffer_from_handle(binfo->buffer), 1748bf215546Sopenharmony_ci binfo->range, binfo->offset 1749bf215546Sopenharmony_ci }; 1750bf215546Sopenharmony_ci 1751bf215546Sopenharmony_ci if (desc.buffer) 1752bf215546Sopenharmony_ci dzn_descriptor_set_ptr_write_buffer_desc(set, &ptr, &desc); 1753bf215546Sopenharmony_ci 1754bf215546Sopenharmony_ci d++; 1755bf215546Sopenharmony_ci } 1756bf215546Sopenharmony_ci break; 1757bf215546Sopenharmony_ci 1758bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 1759bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 1760bf215546Sopenharmony_ci for (; dzn_descriptor_set_ptr_is_valid(&ptr) && d < desc_count; 1761bf215546Sopenharmony_ci dzn_descriptor_set_ptr_move(set->layout, &ptr, 1)) { 1762bf215546Sopenharmony_ci assert(dzn_descriptor_set_ptr_get_vk_type(set->layout, &ptr) == pDescriptorWrite->descriptorType); 1763bf215546Sopenharmony_ci const VkDescriptorBufferInfo *binfo = &pDescriptorWrite->pBufferInfo[d]; 1764bf215546Sopenharmony_ci struct dzn_buffer_desc desc = { 1765bf215546Sopenharmony_ci pDescriptorWrite->descriptorType, 1766bf215546Sopenharmony_ci dzn_buffer_from_handle(binfo->buffer), 1767bf215546Sopenharmony_ci binfo->range, binfo->offset 1768bf215546Sopenharmony_ci }; 1769bf215546Sopenharmony_ci 1770bf215546Sopenharmony_ci if (desc.buffer) 1771bf215546Sopenharmony_ci dzn_descriptor_set_ptr_write_dynamic_buffer_desc(set, &ptr, &desc); 1772bf215546Sopenharmony_ci 1773bf215546Sopenharmony_ci d++; 1774bf215546Sopenharmony_ci } 1775bf215546Sopenharmony_ci break; 1776bf215546Sopenharmony_ci 1777bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 1778bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 1779bf215546Sopenharmony_ci for (; dzn_descriptor_set_ptr_is_valid(&ptr) && d < desc_count; 1780bf215546Sopenharmony_ci dzn_descriptor_set_ptr_move(set->layout, &ptr, 1)) { 1781bf215546Sopenharmony_ci assert(dzn_descriptor_set_ptr_get_vk_type(set->layout, &ptr) == pDescriptorWrite->descriptorType); 1782bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_buffer_view, bview, pDescriptorWrite->pTexelBufferView[d]); 1783bf215546Sopenharmony_ci 1784bf215546Sopenharmony_ci if (bview) 1785bf215546Sopenharmony_ci dzn_descriptor_set_ptr_write_buffer_view_desc(set, &ptr, bview); 1786bf215546Sopenharmony_ci 1787bf215546Sopenharmony_ci d++; 1788bf215546Sopenharmony_ci } 1789bf215546Sopenharmony_ci break; 1790bf215546Sopenharmony_ci 1791bf215546Sopenharmony_ci default: 1792bf215546Sopenharmony_ci unreachable("invalid descriptor type"); 1793bf215546Sopenharmony_ci break; 1794bf215546Sopenharmony_ci } 1795bf215546Sopenharmony_ci 1796bf215546Sopenharmony_ci assert(d == pDescriptorWrite->descriptorCount); 1797bf215546Sopenharmony_ci} 1798bf215546Sopenharmony_ci 1799bf215546Sopenharmony_cistatic void 1800bf215546Sopenharmony_cidzn_descriptor_set_copy(const VkCopyDescriptorSet *pDescriptorCopy) 1801bf215546Sopenharmony_ci{ 1802bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_set, src_set, pDescriptorCopy->srcSet); 1803bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_set, dst_set, pDescriptorCopy->dstSet); 1804bf215546Sopenharmony_ci struct dzn_descriptor_set_ptr src_ptr, dst_ptr; 1805bf215546Sopenharmony_ci 1806bf215546Sopenharmony_ci dzn_descriptor_set_ptr_init(src_set->layout, &src_ptr, 1807bf215546Sopenharmony_ci pDescriptorCopy->srcBinding, 1808bf215546Sopenharmony_ci pDescriptorCopy->srcArrayElement); 1809bf215546Sopenharmony_ci dzn_descriptor_set_ptr_init(dst_set->layout, &dst_ptr, 1810bf215546Sopenharmony_ci pDescriptorCopy->dstBinding, 1811bf215546Sopenharmony_ci pDescriptorCopy->dstArrayElement); 1812bf215546Sopenharmony_ci 1813bf215546Sopenharmony_ci uint32_t copied_count = 0; 1814bf215546Sopenharmony_ci 1815bf215546Sopenharmony_ci while (dzn_descriptor_set_ptr_is_valid(&src_ptr) && 1816bf215546Sopenharmony_ci dzn_descriptor_set_ptr_is_valid(&dst_ptr) && 1817bf215546Sopenharmony_ci copied_count < pDescriptorCopy->descriptorCount) { 1818bf215546Sopenharmony_ci VkDescriptorType src_type = 1819bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_vk_type(src_set->layout, &src_ptr); 1820bf215546Sopenharmony_ci ASSERTED VkDescriptorType dst_type = 1821bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_vk_type(dst_set->layout, &dst_ptr); 1822bf215546Sopenharmony_ci 1823bf215546Sopenharmony_ci assert(src_type == dst_type); 1824bf215546Sopenharmony_ci uint32_t count = 1825bf215546Sopenharmony_ci MIN2(dzn_descriptor_set_remaining_descs_in_binding(src_set->layout, &src_ptr), 1826bf215546Sopenharmony_ci dzn_descriptor_set_remaining_descs_in_binding(dst_set->layout, &dst_ptr)); 1827bf215546Sopenharmony_ci 1828bf215546Sopenharmony_ci if (src_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || 1829bf215546Sopenharmony_ci src_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) { 1830bf215546Sopenharmony_ci uint32_t src_idx = 1831bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_dynamic_buffer_idx(src_set->layout, &src_ptr); 1832bf215546Sopenharmony_ci uint32_t dst_idx = 1833bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_dynamic_buffer_idx(dst_set->layout, &dst_ptr); 1834bf215546Sopenharmony_ci 1835bf215546Sopenharmony_ci memcpy(&dst_set->dynamic_buffers[dst_idx], 1836bf215546Sopenharmony_ci &src_set->dynamic_buffers[src_idx], 1837bf215546Sopenharmony_ci sizeof(*dst_set->dynamic_buffers) * count); 1838bf215546Sopenharmony_ci } else { 1839bf215546Sopenharmony_ci dzn_foreach_pool_type(type) { 1840bf215546Sopenharmony_ci uint32_t src_heap_offset = 1841bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_heap_offset(src_set->layout, type, &src_ptr, false); 1842bf215546Sopenharmony_ci uint32_t dst_heap_offset = 1843bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_heap_offset(dst_set->layout, type, &dst_ptr, false); 1844bf215546Sopenharmony_ci 1845bf215546Sopenharmony_ci if (src_heap_offset == ~0) { 1846bf215546Sopenharmony_ci assert(dst_heap_offset == ~0); 1847bf215546Sopenharmony_ci continue; 1848bf215546Sopenharmony_ci } 1849bf215546Sopenharmony_ci 1850bf215546Sopenharmony_ci mtx_lock(&src_set->pool->defragment_lock); 1851bf215546Sopenharmony_ci mtx_lock(&dst_set->pool->defragment_lock); 1852bf215546Sopenharmony_ci dzn_descriptor_heap_copy(&dst_set->pool->heaps[type], 1853bf215546Sopenharmony_ci dst_set->heap_offsets[type] + dst_heap_offset, 1854bf215546Sopenharmony_ci &src_set->pool->heaps[type], 1855bf215546Sopenharmony_ci src_set->heap_offsets[type] + src_heap_offset, 1856bf215546Sopenharmony_ci count); 1857bf215546Sopenharmony_ci 1858bf215546Sopenharmony_ci if (dzn_descriptor_type_depends_on_shader_usage(src_type)) { 1859bf215546Sopenharmony_ci src_heap_offset = 1860bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_heap_offset(src_set->layout, type, &src_ptr, true); 1861bf215546Sopenharmony_ci dst_heap_offset = 1862bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_heap_offset(dst_set->layout, type, &dst_ptr, true); 1863bf215546Sopenharmony_ci assert(src_heap_offset != ~0); 1864bf215546Sopenharmony_ci assert(dst_heap_offset != ~0); 1865bf215546Sopenharmony_ci dzn_descriptor_heap_copy(&dst_set->pool->heaps[type], 1866bf215546Sopenharmony_ci dst_set->heap_offsets[type] + dst_heap_offset, 1867bf215546Sopenharmony_ci &src_set->pool->heaps[type], 1868bf215546Sopenharmony_ci src_set->heap_offsets[type] + src_heap_offset, 1869bf215546Sopenharmony_ci count); 1870bf215546Sopenharmony_ci } 1871bf215546Sopenharmony_ci mtx_unlock(&dst_set->pool->defragment_lock); 1872bf215546Sopenharmony_ci mtx_unlock(&src_set->pool->defragment_lock); 1873bf215546Sopenharmony_ci } 1874bf215546Sopenharmony_ci } 1875bf215546Sopenharmony_ci 1876bf215546Sopenharmony_ci dzn_descriptor_set_ptr_move(src_set->layout, &src_ptr, count); 1877bf215546Sopenharmony_ci dzn_descriptor_set_ptr_move(dst_set->layout, &dst_ptr, count); 1878bf215546Sopenharmony_ci copied_count += count; 1879bf215546Sopenharmony_ci } 1880bf215546Sopenharmony_ci 1881bf215546Sopenharmony_ci assert(copied_count == pDescriptorCopy->descriptorCount); 1882bf215546Sopenharmony_ci} 1883bf215546Sopenharmony_ci 1884bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1885bf215546Sopenharmony_cidzn_UpdateDescriptorSets(VkDevice _device, 1886bf215546Sopenharmony_ci uint32_t descriptorWriteCount, 1887bf215546Sopenharmony_ci const VkWriteDescriptorSet *pDescriptorWrites, 1888bf215546Sopenharmony_ci uint32_t descriptorCopyCount, 1889bf215546Sopenharmony_ci const VkCopyDescriptorSet *pDescriptorCopies) 1890bf215546Sopenharmony_ci{ 1891bf215546Sopenharmony_ci for (unsigned i = 0; i < descriptorWriteCount; i++) 1892bf215546Sopenharmony_ci dzn_descriptor_set_write(&pDescriptorWrites[i]); 1893bf215546Sopenharmony_ci 1894bf215546Sopenharmony_ci for (unsigned i = 0; i < descriptorCopyCount; i++) 1895bf215546Sopenharmony_ci dzn_descriptor_set_copy(&pDescriptorCopies[i]); 1896bf215546Sopenharmony_ci} 1897bf215546Sopenharmony_ci 1898bf215546Sopenharmony_cistatic void 1899bf215546Sopenharmony_cidzn_descriptor_update_template_destroy(struct dzn_descriptor_update_template *templ, 1900bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc) 1901bf215546Sopenharmony_ci{ 1902bf215546Sopenharmony_ci if (!templ) 1903bf215546Sopenharmony_ci return; 1904bf215546Sopenharmony_ci 1905bf215546Sopenharmony_ci struct dzn_device *device = 1906bf215546Sopenharmony_ci container_of(templ->base.device, struct dzn_device, vk); 1907bf215546Sopenharmony_ci 1908bf215546Sopenharmony_ci vk_object_base_finish(&templ->base); 1909bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, alloc, templ); 1910bf215546Sopenharmony_ci} 1911bf215546Sopenharmony_ci 1912bf215546Sopenharmony_cistatic VkResult 1913bf215546Sopenharmony_cidzn_descriptor_update_template_create(struct dzn_device *device, 1914bf215546Sopenharmony_ci const VkDescriptorUpdateTemplateCreateInfo *info, 1915bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 1916bf215546Sopenharmony_ci VkDescriptorUpdateTemplate *out) 1917bf215546Sopenharmony_ci{ 1918bf215546Sopenharmony_ci assert(info->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET); 1919bf215546Sopenharmony_ci 1920bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_set_layout, set_layout, info->descriptorSetLayout); 1921bf215546Sopenharmony_ci 1922bf215546Sopenharmony_ci uint32_t entry_count = 0; 1923bf215546Sopenharmony_ci for (uint32_t e = 0; e < info->descriptorUpdateEntryCount; e++) { 1924bf215546Sopenharmony_ci struct dzn_descriptor_set_ptr ptr; 1925bf215546Sopenharmony_ci dzn_descriptor_set_ptr_init(set_layout, &ptr, 1926bf215546Sopenharmony_ci info->pDescriptorUpdateEntries[e].dstBinding, 1927bf215546Sopenharmony_ci info->pDescriptorUpdateEntries[e].dstArrayElement); 1928bf215546Sopenharmony_ci uint32_t desc_count = info->pDescriptorUpdateEntries[e].descriptorCount; 1929bf215546Sopenharmony_ci ASSERTED VkDescriptorType type = info->pDescriptorUpdateEntries[e].descriptorType; 1930bf215546Sopenharmony_ci uint32_t d = 0; 1931bf215546Sopenharmony_ci 1932bf215546Sopenharmony_ci while (dzn_descriptor_set_ptr_is_valid(&ptr) && d < desc_count) { 1933bf215546Sopenharmony_ci uint32_t ndescs = dzn_descriptor_set_remaining_descs_in_binding(set_layout, &ptr); 1934bf215546Sopenharmony_ci 1935bf215546Sopenharmony_ci assert(dzn_descriptor_set_ptr_get_vk_type(set_layout, &ptr) == type); 1936bf215546Sopenharmony_ci d += ndescs; 1937bf215546Sopenharmony_ci dzn_descriptor_set_ptr_move(set_layout, &ptr, ndescs); 1938bf215546Sopenharmony_ci entry_count++; 1939bf215546Sopenharmony_ci } 1940bf215546Sopenharmony_ci 1941bf215546Sopenharmony_ci assert(d >= desc_count); 1942bf215546Sopenharmony_ci } 1943bf215546Sopenharmony_ci 1944bf215546Sopenharmony_ci VK_MULTIALLOC(ma); 1945bf215546Sopenharmony_ci VK_MULTIALLOC_DECL(&ma, struct dzn_descriptor_update_template, templ, 1); 1946bf215546Sopenharmony_ci VK_MULTIALLOC_DECL(&ma, struct dzn_descriptor_update_template_entry, entries, entry_count); 1947bf215546Sopenharmony_ci 1948bf215546Sopenharmony_ci if (!vk_multialloc_zalloc2(&ma, &device->vk.alloc, alloc, 1949bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)) 1950bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 1951bf215546Sopenharmony_ci 1952bf215546Sopenharmony_ci vk_object_base_init(&device->vk, &templ->base, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE); 1953bf215546Sopenharmony_ci templ->entry_count = entry_count; 1954bf215546Sopenharmony_ci templ->entries = entries; 1955bf215546Sopenharmony_ci 1956bf215546Sopenharmony_ci struct dzn_descriptor_update_template_entry *entry = entries; 1957bf215546Sopenharmony_ci 1958bf215546Sopenharmony_ci for (uint32_t e = 0; e < info->descriptorUpdateEntryCount; e++) { 1959bf215546Sopenharmony_ci struct dzn_descriptor_set_ptr ptr; 1960bf215546Sopenharmony_ci dzn_descriptor_set_ptr_init(set_layout, &ptr, 1961bf215546Sopenharmony_ci info->pDescriptorUpdateEntries[e].dstBinding, 1962bf215546Sopenharmony_ci info->pDescriptorUpdateEntries[e].dstArrayElement); 1963bf215546Sopenharmony_ci uint32_t desc_count = info->pDescriptorUpdateEntries[e].descriptorCount; 1964bf215546Sopenharmony_ci VkDescriptorType type = info->pDescriptorUpdateEntries[e].descriptorType; 1965bf215546Sopenharmony_ci size_t user_data_offset = info->pDescriptorUpdateEntries[e].offset; 1966bf215546Sopenharmony_ci size_t user_data_stride = info->pDescriptorUpdateEntries[e].stride; 1967bf215546Sopenharmony_ci uint32_t d = 0; 1968bf215546Sopenharmony_ci 1969bf215546Sopenharmony_ci while (dzn_descriptor_set_ptr_is_valid(&ptr) && d < desc_count) { 1970bf215546Sopenharmony_ci uint32_t ndescs = dzn_descriptor_set_remaining_descs_in_binding(set_layout, &ptr); 1971bf215546Sopenharmony_ci 1972bf215546Sopenharmony_ci entry->type = type; 1973bf215546Sopenharmony_ci entry->desc_count = MIN2(desc_count - d, ndescs); 1974bf215546Sopenharmony_ci entry->user_data.stride = user_data_stride; 1975bf215546Sopenharmony_ci entry->user_data.offset = user_data_offset; 1976bf215546Sopenharmony_ci memset(&entry->heap_offsets, ~0, sizeof(entry->heap_offsets)); 1977bf215546Sopenharmony_ci 1978bf215546Sopenharmony_ci assert(dzn_descriptor_set_ptr_get_vk_type(set_layout, &ptr) == type); 1979bf215546Sopenharmony_ci if (dzn_desc_type_has_sampler(type)) { 1980bf215546Sopenharmony_ci entry->heap_offsets.sampler = 1981bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_heap_offset(set_layout, 1982bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, 1983bf215546Sopenharmony_ci &ptr, false); 1984bf215546Sopenharmony_ci } 1985bf215546Sopenharmony_ci 1986bf215546Sopenharmony_ci if (type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || 1987bf215546Sopenharmony_ci type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) { 1988bf215546Sopenharmony_ci entry->dynamic_buffer_idx = 1989bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_dynamic_buffer_idx(set_layout, &ptr); 1990bf215546Sopenharmony_ci } else if (type != VK_DESCRIPTOR_TYPE_SAMPLER) { 1991bf215546Sopenharmony_ci entry->heap_offsets.cbv_srv_uav = 1992bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_heap_offset(set_layout, 1993bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1994bf215546Sopenharmony_ci &ptr, false); 1995bf215546Sopenharmony_ci if (dzn_descriptor_type_depends_on_shader_usage(type)) { 1996bf215546Sopenharmony_ci entry->heap_offsets.extra_uav = 1997bf215546Sopenharmony_ci dzn_descriptor_set_ptr_get_heap_offset(set_layout, 1998bf215546Sopenharmony_ci D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1999bf215546Sopenharmony_ci &ptr, true); 2000bf215546Sopenharmony_ci } 2001bf215546Sopenharmony_ci } 2002bf215546Sopenharmony_ci 2003bf215546Sopenharmony_ci d += ndescs; 2004bf215546Sopenharmony_ci dzn_descriptor_set_ptr_move(set_layout, &ptr, ndescs); 2005bf215546Sopenharmony_ci user_data_offset += user_data_stride * ndescs; 2006bf215546Sopenharmony_ci ++entry; 2007bf215546Sopenharmony_ci } 2008bf215546Sopenharmony_ci } 2009bf215546Sopenharmony_ci 2010bf215546Sopenharmony_ci *out = dzn_descriptor_update_template_to_handle(templ); 2011bf215546Sopenharmony_ci return VK_SUCCESS; 2012bf215546Sopenharmony_ci} 2013bf215546Sopenharmony_ci 2014bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 2015bf215546Sopenharmony_cidzn_CreateDescriptorUpdateTemplate(VkDevice device, 2016bf215546Sopenharmony_ci const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo, 2017bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 2018bf215546Sopenharmony_ci VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate) 2019bf215546Sopenharmony_ci{ 2020bf215546Sopenharmony_ci return dzn_descriptor_update_template_create(dzn_device_from_handle(device), 2021bf215546Sopenharmony_ci pCreateInfo, pAllocator, 2022bf215546Sopenharmony_ci pDescriptorUpdateTemplate); 2023bf215546Sopenharmony_ci} 2024bf215546Sopenharmony_ci 2025bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2026bf215546Sopenharmony_cidzn_DestroyDescriptorUpdateTemplate(VkDevice device, 2027bf215546Sopenharmony_ci VkDescriptorUpdateTemplate descriptorUpdateTemplate, 2028bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 2029bf215546Sopenharmony_ci{ 2030bf215546Sopenharmony_ci dzn_descriptor_update_template_destroy(dzn_descriptor_update_template_from_handle(descriptorUpdateTemplate), 2031bf215546Sopenharmony_ci pAllocator); 2032bf215546Sopenharmony_ci} 2033bf215546Sopenharmony_ci 2034bf215546Sopenharmony_cistatic const void * 2035bf215546Sopenharmony_cidzn_descriptor_update_template_get_desc_data(const struct dzn_descriptor_update_template *templ, 2036bf215546Sopenharmony_ci uint32_t e, uint32_t d, 2037bf215546Sopenharmony_ci const void *user_data) 2038bf215546Sopenharmony_ci{ 2039bf215546Sopenharmony_ci return (const void *)((const uint8_t *)user_data + 2040bf215546Sopenharmony_ci templ->entries[e].user_data.offset + 2041bf215546Sopenharmony_ci (d * templ->entries[e].user_data.stride)); 2042bf215546Sopenharmony_ci} 2043bf215546Sopenharmony_ci 2044bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2045bf215546Sopenharmony_cidzn_UpdateDescriptorSetWithTemplate(VkDevice device, 2046bf215546Sopenharmony_ci VkDescriptorSet descriptorSet, 2047bf215546Sopenharmony_ci VkDescriptorUpdateTemplate descriptorUpdateTemplate, 2048bf215546Sopenharmony_ci const void *pData) 2049bf215546Sopenharmony_ci{ 2050bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_set, set, descriptorSet); 2051bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_descriptor_update_template, templ, descriptorUpdateTemplate); 2052bf215546Sopenharmony_ci 2053bf215546Sopenharmony_ci for (uint32_t e = 0; e < templ->entry_count; e++) { 2054bf215546Sopenharmony_ci const struct dzn_descriptor_update_template_entry *entry = &templ->entries[e]; 2055bf215546Sopenharmony_ci bool cube_as_2darray = 2056bf215546Sopenharmony_ci entry->type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 2057bf215546Sopenharmony_ci 2058bf215546Sopenharmony_ci switch (entry->type) { 2059bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 2060bf215546Sopenharmony_ci for (uint32_t d = 0; d < entry->desc_count; d++) { 2061bf215546Sopenharmony_ci const VkDescriptorImageInfo *info = (const VkDescriptorImageInfo *) 2062bf215546Sopenharmony_ci dzn_descriptor_update_template_get_desc_data(templ, e, d, pData); 2063bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_sampler, sampler, info->sampler); 2064bf215546Sopenharmony_ci 2065bf215546Sopenharmony_ci if (sampler) 2066bf215546Sopenharmony_ci dzn_descriptor_set_write_sampler_desc(set, entry->heap_offsets.sampler + d, sampler); 2067bf215546Sopenharmony_ci } 2068bf215546Sopenharmony_ci break; 2069bf215546Sopenharmony_ci 2070bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 2071bf215546Sopenharmony_ci for (uint32_t d = 0; d < entry->desc_count; d++) { 2072bf215546Sopenharmony_ci const VkDescriptorImageInfo *info = (const VkDescriptorImageInfo *) 2073bf215546Sopenharmony_ci dzn_descriptor_update_template_get_desc_data(templ, e, d, pData); 2074bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_sampler, sampler, info->sampler); 2075bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_image_view, iview, info->imageView); 2076bf215546Sopenharmony_ci 2077bf215546Sopenharmony_ci if (sampler) 2078bf215546Sopenharmony_ci dzn_descriptor_set_write_sampler_desc(set, entry->heap_offsets.sampler + d, sampler); 2079bf215546Sopenharmony_ci 2080bf215546Sopenharmony_ci if (iview) 2081bf215546Sopenharmony_ci dzn_descriptor_set_write_image_view_desc(set, entry->heap_offsets.cbv_srv_uav + d, ~0, cube_as_2darray, iview); 2082bf215546Sopenharmony_ci } 2083bf215546Sopenharmony_ci break; 2084bf215546Sopenharmony_ci 2085bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 2086bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 2087bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 2088bf215546Sopenharmony_ci for (uint32_t d = 0; d < entry->desc_count; d++) { 2089bf215546Sopenharmony_ci const VkDescriptorImageInfo *info = (const VkDescriptorImageInfo *) 2090bf215546Sopenharmony_ci dzn_descriptor_update_template_get_desc_data(templ, e, d, pData); 2091bf215546Sopenharmony_ci uint32_t srv_heap_offset = entry->heap_offsets.cbv_srv_uav + d; 2092bf215546Sopenharmony_ci uint32_t uav_heap_offset = 2093bf215546Sopenharmony_ci entry->type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? 2094bf215546Sopenharmony_ci entry->heap_offsets.extra_uav + d : ~0; 2095bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_image_view, iview, info->imageView); 2096bf215546Sopenharmony_ci 2097bf215546Sopenharmony_ci if (iview) 2098bf215546Sopenharmony_ci dzn_descriptor_set_write_image_view_desc(set, srv_heap_offset, uav_heap_offset, cube_as_2darray, iview); 2099bf215546Sopenharmony_ci } 2100bf215546Sopenharmony_ci break; 2101bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 2102bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 2103bf215546Sopenharmony_ci for (uint32_t d = 0; d < entry->desc_count; d++) { 2104bf215546Sopenharmony_ci const VkDescriptorBufferInfo *info = (const VkDescriptorBufferInfo *) 2105bf215546Sopenharmony_ci dzn_descriptor_update_template_get_desc_data(templ, e, d, pData); 2106bf215546Sopenharmony_ci uint32_t cbv_srv_heap_offset = entry->heap_offsets.cbv_srv_uav + d; 2107bf215546Sopenharmony_ci uint32_t uav_heap_offset = 2108bf215546Sopenharmony_ci entry->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ? 2109bf215546Sopenharmony_ci entry->heap_offsets.extra_uav + d : ~0; 2110bf215546Sopenharmony_ci 2111bf215546Sopenharmony_ci struct dzn_buffer_desc desc = { 2112bf215546Sopenharmony_ci entry->type, 2113bf215546Sopenharmony_ci dzn_buffer_from_handle(info->buffer), 2114bf215546Sopenharmony_ci info->range, info->offset 2115bf215546Sopenharmony_ci }; 2116bf215546Sopenharmony_ci 2117bf215546Sopenharmony_ci if (desc.buffer) 2118bf215546Sopenharmony_ci dzn_descriptor_set_write_buffer_desc(set, cbv_srv_heap_offset, uav_heap_offset, &desc); 2119bf215546Sopenharmony_ci } 2120bf215546Sopenharmony_ci break; 2121bf215546Sopenharmony_ci 2122bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 2123bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 2124bf215546Sopenharmony_ci for (uint32_t d = 0; d < entry->desc_count; d++) { 2125bf215546Sopenharmony_ci const VkDescriptorBufferInfo *info = (const VkDescriptorBufferInfo *) 2126bf215546Sopenharmony_ci dzn_descriptor_update_template_get_desc_data(templ, e, d, pData); 2127bf215546Sopenharmony_ci uint32_t dyn_buf_idx = entry->dynamic_buffer_idx + d; 2128bf215546Sopenharmony_ci 2129bf215546Sopenharmony_ci struct dzn_buffer_desc desc = { 2130bf215546Sopenharmony_ci entry->type, 2131bf215546Sopenharmony_ci dzn_buffer_from_handle(info->buffer), 2132bf215546Sopenharmony_ci info->range, info->offset 2133bf215546Sopenharmony_ci }; 2134bf215546Sopenharmony_ci 2135bf215546Sopenharmony_ci if (desc.buffer) 2136bf215546Sopenharmony_ci dzn_descriptor_set_write_dynamic_buffer_desc(set, dyn_buf_idx, &desc); 2137bf215546Sopenharmony_ci } 2138bf215546Sopenharmony_ci break; 2139bf215546Sopenharmony_ci 2140bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 2141bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 2142bf215546Sopenharmony_ci for (uint32_t d = 0; d < entry->desc_count; d++) { 2143bf215546Sopenharmony_ci VkBufferView *info = (VkBufferView *) 2144bf215546Sopenharmony_ci dzn_descriptor_update_template_get_desc_data(templ, e, d, pData); 2145bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_buffer_view, bview, *info); 2146bf215546Sopenharmony_ci uint32_t srv_heap_offset = entry->heap_offsets.cbv_srv_uav + d; 2147bf215546Sopenharmony_ci uint32_t uav_heap_offset = 2148bf215546Sopenharmony_ci entry->type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER ? 2149bf215546Sopenharmony_ci entry->heap_offsets.extra_uav + d : ~0; 2150bf215546Sopenharmony_ci 2151bf215546Sopenharmony_ci if (bview) 2152bf215546Sopenharmony_ci dzn_descriptor_set_write_buffer_view_desc(set, srv_heap_offset, uav_heap_offset, bview); 2153bf215546Sopenharmony_ci } 2154bf215546Sopenharmony_ci break; 2155bf215546Sopenharmony_ci 2156bf215546Sopenharmony_ci default: 2157bf215546Sopenharmony_ci unreachable("invalid descriptor type"); 2158bf215546Sopenharmony_ci } 2159bf215546Sopenharmony_ci } 2160bf215546Sopenharmony_ci} 2161