2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
24 #include "tu_private.h"
32 #include "util/mesa-sha1.h"
36 binding_compare(const void *av
, const void *bv
)
38 const VkDescriptorSetLayoutBinding
*a
=
39 (const VkDescriptorSetLayoutBinding
*) av
;
40 const VkDescriptorSetLayoutBinding
*b
=
41 (const VkDescriptorSetLayoutBinding
*) bv
;
43 return (a
->binding
< b
->binding
) ? -1 : (a
->binding
> b
->binding
) ? 1 : 0;
46 static VkDescriptorSetLayoutBinding
*
47 create_sorted_bindings(const VkDescriptorSetLayoutBinding
*bindings
,
50 VkDescriptorSetLayoutBinding
*sorted_bindings
=
51 malloc(count
* sizeof(VkDescriptorSetLayoutBinding
));
55 memcpy(sorted_bindings
, bindings
,
56 count
* sizeof(VkDescriptorSetLayoutBinding
));
58 qsort(sorted_bindings
, count
, sizeof(VkDescriptorSetLayoutBinding
),
61 return sorted_bindings
;
65 tu_CreateDescriptorSetLayout(
67 const VkDescriptorSetLayoutCreateInfo
*pCreateInfo
,
68 const VkAllocationCallbacks
*pAllocator
,
69 VkDescriptorSetLayout
*pSetLayout
)
71 TU_FROM_HANDLE(tu_device
, device
, _device
);
72 struct tu_descriptor_set_layout
*set_layout
;
74 assert(pCreateInfo
->sType
==
75 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
);
76 const VkDescriptorSetLayoutBindingFlagsCreateInfoEXT
*variable_flags
=
79 DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT
);
81 uint32_t max_binding
= 0;
82 uint32_t immutable_sampler_count
= 0;
83 for (uint32_t j
= 0; j
< pCreateInfo
->bindingCount
; j
++) {
84 max_binding
= MAX2(max_binding
, pCreateInfo
->pBindings
[j
].binding
);
85 if (pCreateInfo
->pBindings
[j
].pImmutableSamplers
)
86 immutable_sampler_count
+= pCreateInfo
->pBindings
[j
].descriptorCount
;
89 uint32_t samplers_offset
=
90 sizeof(struct tu_descriptor_set_layout
) +
91 (max_binding
+ 1) * sizeof(set_layout
->binding
[0]);
93 samplers_offset
+ immutable_sampler_count
* 4 * sizeof(uint32_t);
95 set_layout
= vk_alloc2(&device
->alloc
, pAllocator
, size
, 8,
96 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
98 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
100 set_layout
->flags
= pCreateInfo
->flags
;
102 /* We just allocate all the samplers at the end of the struct */
103 uint32_t *samplers
= (uint32_t *) &set_layout
->binding
[max_binding
+ 1];
104 (void) samplers
; /* TODO: Use me */
106 VkDescriptorSetLayoutBinding
*bindings
= create_sorted_bindings(
107 pCreateInfo
->pBindings
, pCreateInfo
->bindingCount
);
109 vk_free2(&device
->alloc
, pAllocator
, set_layout
);
110 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
113 set_layout
->binding_count
= max_binding
+ 1;
114 set_layout
->shader_stages
= 0;
115 set_layout
->dynamic_shader_stages
= 0;
116 set_layout
->has_immutable_samplers
= false;
117 set_layout
->size
= 0;
119 memset(set_layout
->binding
, 0,
120 size
- sizeof(struct tu_descriptor_set_layout
));
122 uint32_t buffer_count
= 0;
123 uint32_t dynamic_offset_count
= 0;
125 for (uint32_t j
= 0; j
< pCreateInfo
->bindingCount
; j
++) {
126 const VkDescriptorSetLayoutBinding
*binding
= bindings
+ j
;
127 uint32_t b
= binding
->binding
;
129 unsigned binding_buffer_count
= 0;
131 switch (binding
->descriptorType
) {
132 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
133 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
134 assert(!(pCreateInfo
->flags
&
135 VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR
));
136 set_layout
->binding
[b
].dynamic_offset_count
= 1;
137 set_layout
->dynamic_shader_stages
|= binding
->stageFlags
;
138 set_layout
->binding
[b
].size
= 0;
139 binding_buffer_count
= 1;
142 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
143 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
144 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
145 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
146 set_layout
->binding
[b
].size
= 16;
147 binding_buffer_count
= 1;
150 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
151 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
152 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
:
153 /* main descriptor + fmask descriptor */
154 set_layout
->binding
[b
].size
= 64;
155 binding_buffer_count
= 1;
158 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
159 /* main descriptor + fmask descriptor + sampler */
160 set_layout
->binding
[b
].size
= 96;
161 binding_buffer_count
= 1;
164 case VK_DESCRIPTOR_TYPE_SAMPLER
:
165 set_layout
->binding
[b
].size
= 16;
169 unreachable("unknown descriptor type\n");
173 set_layout
->size
= align(set_layout
->size
, alignment
);
174 set_layout
->binding
[b
].type
= binding
->descriptorType
;
175 set_layout
->binding
[b
].array_size
= binding
->descriptorCount
;
176 set_layout
->binding
[b
].offset
= set_layout
->size
;
177 set_layout
->binding
[b
].buffer_offset
= buffer_count
;
178 set_layout
->binding
[b
].dynamic_offset_offset
= dynamic_offset_count
;
180 if (variable_flags
&& binding
->binding
< variable_flags
->bindingCount
&&
181 (variable_flags
->pBindingFlags
[binding
->binding
] &
182 VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT
)) {
183 assert(!binding
->pImmutableSamplers
); /* Terribly ill defined how
184 many samplers are valid */
185 assert(binding
->binding
== max_binding
);
187 set_layout
->has_variable_descriptors
= true;
190 if (binding
->pImmutableSamplers
) {
191 set_layout
->binding
[b
].immutable_samplers_offset
= samplers_offset
;
192 set_layout
->has_immutable_samplers
= true;
196 binding
->descriptorCount
* set_layout
->binding
[b
].size
;
197 buffer_count
+= binding
->descriptorCount
* binding_buffer_count
;
198 dynamic_offset_count
+= binding
->descriptorCount
*
199 set_layout
->binding
[b
].dynamic_offset_count
;
200 set_layout
->shader_stages
|= binding
->stageFlags
;
205 set_layout
->buffer_count
= buffer_count
;
206 set_layout
->dynamic_offset_count
= dynamic_offset_count
;
208 *pSetLayout
= tu_descriptor_set_layout_to_handle(set_layout
);
214 tu_DestroyDescriptorSetLayout(VkDevice _device
,
215 VkDescriptorSetLayout _set_layout
,
216 const VkAllocationCallbacks
*pAllocator
)
218 TU_FROM_HANDLE(tu_device
, device
, _device
);
219 TU_FROM_HANDLE(tu_descriptor_set_layout
, set_layout
, _set_layout
);
224 vk_free2(&device
->alloc
, pAllocator
, set_layout
);
228 tu_GetDescriptorSetLayoutSupport(
230 const VkDescriptorSetLayoutCreateInfo
*pCreateInfo
,
231 VkDescriptorSetLayoutSupport
*pSupport
)
233 VkDescriptorSetLayoutBinding
*bindings
= create_sorted_bindings(
234 pCreateInfo
->pBindings
, pCreateInfo
->bindingCount
);
236 pSupport
->supported
= false;
240 const VkDescriptorSetLayoutBindingFlagsCreateInfoEXT
*variable_flags
=
241 vk_find_struct_const(
243 DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT
);
244 VkDescriptorSetVariableDescriptorCountLayoutSupportEXT
*variable_count
=
246 (void *) pCreateInfo
->pNext
,
247 DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT
);
248 if (variable_count
) {
249 variable_count
->maxVariableDescriptorCount
= 0;
252 bool supported
= true;
254 for (uint32_t i
= 0; i
< pCreateInfo
->bindingCount
; i
++) {
255 const VkDescriptorSetLayoutBinding
*binding
= bindings
+ i
;
257 uint64_t descriptor_size
= 0;
258 uint64_t descriptor_alignment
= 1;
259 switch (binding
->descriptorType
) {
260 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
261 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
263 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
264 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
265 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
266 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
267 descriptor_size
= 16;
268 descriptor_alignment
= 16;
270 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
271 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
272 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
:
273 descriptor_size
= 64;
274 descriptor_alignment
= 32;
276 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
277 descriptor_size
= 96;
278 descriptor_alignment
= 32;
280 case VK_DESCRIPTOR_TYPE_SAMPLER
:
281 descriptor_size
= 16;
282 descriptor_alignment
= 16;
285 unreachable("unknown descriptor type\n");
289 if (size
&& !align_u64(size
, descriptor_alignment
)) {
292 size
= align_u64(size
, descriptor_alignment
);
294 uint64_t max_count
= UINT64_MAX
;
296 max_count
= (UINT64_MAX
- size
) / descriptor_size
;
298 if (max_count
< binding
->descriptorCount
) {
301 if (variable_flags
&& binding
->binding
< variable_flags
->bindingCount
&&
303 (variable_flags
->pBindingFlags
[binding
->binding
] &
304 VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT
)) {
305 variable_count
->maxVariableDescriptorCount
=
306 MIN2(UINT32_MAX
, max_count
);
308 size
+= binding
->descriptorCount
* descriptor_size
;
313 pSupport
->supported
= supported
;
317 * Pipeline layouts. These have nothing to do with the pipeline. They are
318 * just multiple descriptor set layouts pasted together.
322 tu_CreatePipelineLayout(VkDevice _device
,
323 const VkPipelineLayoutCreateInfo
*pCreateInfo
,
324 const VkAllocationCallbacks
*pAllocator
,
325 VkPipelineLayout
*pPipelineLayout
)
327 TU_FROM_HANDLE(tu_device
, device
, _device
);
328 struct tu_pipeline_layout
*layout
;
329 struct mesa_sha1 ctx
;
331 assert(pCreateInfo
->sType
==
332 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
);
334 layout
= vk_alloc2(&device
->alloc
, pAllocator
, sizeof(*layout
), 8,
335 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
337 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
339 layout
->num_sets
= pCreateInfo
->setLayoutCount
;
341 unsigned dynamic_offset_count
= 0;
343 _mesa_sha1_init(&ctx
);
344 for (uint32_t set
= 0; set
< pCreateInfo
->setLayoutCount
; set
++) {
345 TU_FROM_HANDLE(tu_descriptor_set_layout
, set_layout
,
346 pCreateInfo
->pSetLayouts
[set
]);
347 layout
->set
[set
].layout
= set_layout
;
349 layout
->set
[set
].dynamic_offset_start
= dynamic_offset_count
;
350 for (uint32_t b
= 0; b
< set_layout
->binding_count
; b
++) {
351 dynamic_offset_count
+= set_layout
->binding
[b
].array_size
*
352 set_layout
->binding
[b
].dynamic_offset_count
;
353 if (set_layout
->binding
[b
].immutable_samplers_offset
)
356 tu_immutable_samplers(set_layout
, set_layout
->binding
+ b
),
357 set_layout
->binding
[b
].array_size
* 4 * sizeof(uint32_t));
360 &ctx
, set_layout
->binding
,
361 sizeof(set_layout
->binding
[0]) * set_layout
->binding_count
);
364 layout
->dynamic_offset_count
= dynamic_offset_count
;
365 layout
->push_constant_size
= 0;
367 for (unsigned i
= 0; i
< pCreateInfo
->pushConstantRangeCount
; ++i
) {
368 const VkPushConstantRange
*range
= pCreateInfo
->pPushConstantRanges
+ i
;
369 layout
->push_constant_size
=
370 MAX2(layout
->push_constant_size
, range
->offset
+ range
->size
);
373 layout
->push_constant_size
= align(layout
->push_constant_size
, 16);
374 _mesa_sha1_update(&ctx
, &layout
->push_constant_size
,
375 sizeof(layout
->push_constant_size
));
376 _mesa_sha1_final(&ctx
, layout
->sha1
);
377 *pPipelineLayout
= tu_pipeline_layout_to_handle(layout
);
383 tu_DestroyPipelineLayout(VkDevice _device
,
384 VkPipelineLayout _pipelineLayout
,
385 const VkAllocationCallbacks
*pAllocator
)
387 TU_FROM_HANDLE(tu_device
, device
, _device
);
388 TU_FROM_HANDLE(tu_pipeline_layout
, pipeline_layout
, _pipelineLayout
);
390 if (!pipeline_layout
)
392 vk_free2(&device
->alloc
, pAllocator
, pipeline_layout
);
398 tu_CreateDescriptorPool(VkDevice _device
,
399 const VkDescriptorPoolCreateInfo
*pCreateInfo
,
400 const VkAllocationCallbacks
*pAllocator
,
401 VkDescriptorPool
*pDescriptorPool
)
403 TU_FROM_HANDLE(tu_device
, device
, _device
);
410 tu_DestroyDescriptorPool(VkDevice _device
,
411 VkDescriptorPool _pool
,
412 const VkAllocationCallbacks
*pAllocator
)
417 tu_ResetDescriptorPool(VkDevice _device
,
418 VkDescriptorPool descriptorPool
,
419 VkDescriptorPoolResetFlags flags
)
421 TU_FROM_HANDLE(tu_device
, device
, _device
);
422 TU_FROM_HANDLE(tu_descriptor_pool
, pool
, descriptorPool
);
424 tu_use_args(device
, pool
);
430 tu_AllocateDescriptorSets(VkDevice _device
,
431 const VkDescriptorSetAllocateInfo
*pAllocateInfo
,
432 VkDescriptorSet
*pDescriptorSets
)
434 TU_FROM_HANDLE(tu_device
, device
, _device
);
435 TU_FROM_HANDLE(tu_descriptor_pool
, pool
, pAllocateInfo
->descriptorPool
);
437 tu_use_args(device
, pool
);
443 tu_FreeDescriptorSets(VkDevice _device
,
444 VkDescriptorPool descriptorPool
,
446 const VkDescriptorSet
*pDescriptorSets
)
448 TU_FROM_HANDLE(tu_device
, device
, _device
);
449 TU_FROM_HANDLE(tu_descriptor_pool
, pool
, descriptorPool
);
451 tu_use_args(device
, pool
);
457 tu_update_descriptor_sets(struct tu_device
*device
,
458 struct tu_cmd_buffer
*cmd_buffer
,
459 VkDescriptorSet dstSetOverride
,
460 uint32_t descriptorWriteCount
,
461 const VkWriteDescriptorSet
*pDescriptorWrites
,
462 uint32_t descriptorCopyCount
,
463 const VkCopyDescriptorSet
*pDescriptorCopies
)
468 tu_UpdateDescriptorSets(VkDevice _device
,
469 uint32_t descriptorWriteCount
,
470 const VkWriteDescriptorSet
*pDescriptorWrites
,
471 uint32_t descriptorCopyCount
,
472 const VkCopyDescriptorSet
*pDescriptorCopies
)
474 TU_FROM_HANDLE(tu_device
, device
, _device
);
476 tu_update_descriptor_sets(device
, NULL
, VK_NULL_HANDLE
,
477 descriptorWriteCount
, pDescriptorWrites
,
478 descriptorCopyCount
, pDescriptorCopies
);
482 tu_CreateDescriptorUpdateTemplate(
484 const VkDescriptorUpdateTemplateCreateInfo
*pCreateInfo
,
485 const VkAllocationCallbacks
*pAllocator
,
486 VkDescriptorUpdateTemplate
*pDescriptorUpdateTemplate
)
488 TU_FROM_HANDLE(tu_device
, device
, _device
);
489 TU_FROM_HANDLE(tu_descriptor_set_layout
, set_layout
,
490 pCreateInfo
->descriptorSetLayout
);
491 const uint32_t entry_count
= pCreateInfo
->descriptorUpdateEntryCount
;
493 sizeof(struct tu_descriptor_update_template
) +
494 sizeof(struct tu_descriptor_update_template_entry
) * entry_count
;
495 struct tu_descriptor_update_template
*templ
;
497 templ
= vk_alloc2(&device
->alloc
, pAllocator
, size
, 8,
498 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
500 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
502 *pDescriptorUpdateTemplate
=
503 tu_descriptor_update_template_to_handle(templ
);
505 tu_use_args(set_layout
);
511 tu_DestroyDescriptorUpdateTemplate(
513 VkDescriptorUpdateTemplate descriptorUpdateTemplate
,
514 const VkAllocationCallbacks
*pAllocator
)
516 TU_FROM_HANDLE(tu_device
, device
, _device
);
517 TU_FROM_HANDLE(tu_descriptor_update_template
, templ
,
518 descriptorUpdateTemplate
);
523 vk_free2(&device
->alloc
, pAllocator
, templ
);
527 tu_update_descriptor_set_with_template(
528 struct tu_device
*device
,
529 struct tu_cmd_buffer
*cmd_buffer
,
530 struct tu_descriptor_set
*set
,
531 VkDescriptorUpdateTemplate descriptorUpdateTemplate
,
534 TU_FROM_HANDLE(tu_descriptor_update_template
, templ
,
535 descriptorUpdateTemplate
);
540 tu_UpdateDescriptorSetWithTemplate(
542 VkDescriptorSet descriptorSet
,
543 VkDescriptorUpdateTemplate descriptorUpdateTemplate
,
546 TU_FROM_HANDLE(tu_device
, device
, _device
);
547 TU_FROM_HANDLE(tu_descriptor_set
, set
, descriptorSet
);
549 tu_update_descriptor_set_with_template(device
, NULL
, set
,
550 descriptorUpdateTemplate
, pData
);
554 tu_CreateSamplerYcbcrConversion(
556 const VkSamplerYcbcrConversionCreateInfo
*pCreateInfo
,
557 const VkAllocationCallbacks
*pAllocator
,
558 VkSamplerYcbcrConversion
*pYcbcrConversion
)
560 *pYcbcrConversion
= VK_NULL_HANDLE
;
565 tu_DestroySamplerYcbcrConversion(VkDevice device
,
566 VkSamplerYcbcrConversion ycbcrConversion
,
567 const VkAllocationCallbacks
*pAllocator
)