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