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 DEALINGS
30 #include "tu_private.h"
31 #include "util/mesa-sha1.h"
35 binding_compare(const void *av
, const void *bv
)
37 const VkDescriptorSetLayoutBinding
*a
=
38 (const VkDescriptorSetLayoutBinding
*)av
;
39 const VkDescriptorSetLayoutBinding
*b
=
40 (const VkDescriptorSetLayoutBinding
*)bv
;
42 return (a
->binding
< b
->binding
) ? -1 : (a
->binding
> b
->binding
) ? 1 : 0;
45 static VkDescriptorSetLayoutBinding
*
46 create_sorted_bindings(const VkDescriptorSetLayoutBinding
*bindings
,
49 VkDescriptorSetLayoutBinding
*sorted_bindings
=
50 malloc(count
* sizeof(VkDescriptorSetLayoutBinding
));
55 sorted_bindings
, bindings
, count
* sizeof(VkDescriptorSetLayoutBinding
));
57 qsort(sorted_bindings
,
59 sizeof(VkDescriptorSetLayoutBinding
),
62 return sorted_bindings
;
66 tu_CreateDescriptorSetLayout(
68 const VkDescriptorSetLayoutCreateInfo
*pCreateInfo
,
69 const VkAllocationCallbacks
*pAllocator
,
70 VkDescriptorSetLayout
*pSetLayout
)
72 TU_FROM_HANDLE(tu_device
, device
, _device
);
73 struct tu_descriptor_set_layout
*set_layout
;
75 assert(pCreateInfo
->sType
==
76 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
);
77 const VkDescriptorSetLayoutBindingFlagsCreateInfoEXT
*variable_flags
=
78 vk_find_struct_const(pCreateInfo
->pNext
,
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(
96 &device
->alloc
, pAllocator
, size
, 8, 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
=
107 create_sorted_bindings(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;
120 set_layout
->binding
, 0, 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 many
184 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
+=
199 binding
->descriptorCount
* 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
=
234 create_sorted_bindings(pCreateInfo
->pBindings
, pCreateInfo
->bindingCount
);
236 pSupport
->supported
= false;
240 const VkDescriptorSetLayoutBindingFlagsCreateInfoEXT
*variable_flags
=
241 vk_find_struct_const(pCreateInfo
->pNext
,
242 DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT
);
243 VkDescriptorSetVariableDescriptorCountLayoutSupportEXT
*variable_count
=
245 (void *)pCreateInfo
->pNext
,
246 DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT
);
247 if (variable_count
) {
248 variable_count
->maxVariableDescriptorCount
= 0;
251 bool supported
= true;
253 for (uint32_t i
= 0; i
< pCreateInfo
->bindingCount
; i
++) {
254 const VkDescriptorSetLayoutBinding
*binding
= bindings
+ i
;
256 uint64_t descriptor_size
= 0;
257 uint64_t descriptor_alignment
= 1;
258 switch (binding
->descriptorType
) {
259 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
260 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
262 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
263 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
264 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
265 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
266 descriptor_size
= 16;
267 descriptor_alignment
= 16;
269 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
270 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
271 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
:
272 descriptor_size
= 64;
273 descriptor_alignment
= 32;
275 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
276 descriptor_size
= 96;
277 descriptor_alignment
= 32;
279 case VK_DESCRIPTOR_TYPE_SAMPLER
:
280 descriptor_size
= 16;
281 descriptor_alignment
= 16;
284 unreachable("unknown descriptor type\n");
288 if (size
&& !align_u64(size
, descriptor_alignment
)) {
291 size
= align_u64(size
, descriptor_alignment
);
293 uint64_t max_count
= UINT64_MAX
;
295 max_count
= (UINT64_MAX
- size
) / descriptor_size
;
297 if (max_count
< binding
->descriptorCount
) {
300 if (variable_flags
&& binding
->binding
< variable_flags
->bindingCount
&&
302 (variable_flags
->pBindingFlags
[binding
->binding
] &
303 VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT
)) {
304 variable_count
->maxVariableDescriptorCount
=
305 MIN2(UINT32_MAX
, max_count
);
307 size
+= binding
->descriptorCount
* descriptor_size
;
312 pSupport
->supported
= supported
;
316 * Pipeline layouts. These have nothing to do with the pipeline. They are
317 * just multiple descriptor set layouts pasted together.
321 tu_CreatePipelineLayout(VkDevice _device
,
322 const VkPipelineLayoutCreateInfo
*pCreateInfo
,
323 const VkAllocationCallbacks
*pAllocator
,
324 VkPipelineLayout
*pPipelineLayout
)
326 TU_FROM_HANDLE(tu_device
, device
, _device
);
327 struct tu_pipeline_layout
*layout
;
328 struct mesa_sha1 ctx
;
330 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
);
332 layout
= vk_alloc2(&device
->alloc
,
336 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
338 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
340 layout
->num_sets
= pCreateInfo
->setLayoutCount
;
342 unsigned dynamic_offset_count
= 0;
344 _mesa_sha1_init(&ctx
);
345 for (uint32_t set
= 0; set
< pCreateInfo
->setLayoutCount
; set
++) {
347 tu_descriptor_set_layout
, set_layout
, pCreateInfo
->pSetLayouts
[set
]);
348 layout
->set
[set
].layout
= set_layout
;
350 layout
->set
[set
].dynamic_offset_start
= dynamic_offset_count
;
351 for (uint32_t b
= 0; b
< set_layout
->binding_count
; b
++) {
352 dynamic_offset_count
+= set_layout
->binding
[b
].array_size
*
353 set_layout
->binding
[b
].dynamic_offset_count
;
354 if (set_layout
->binding
[b
].immutable_samplers_offset
)
357 tu_immutable_samplers(set_layout
, set_layout
->binding
+ b
),
358 set_layout
->binding
[b
].array_size
* 4 * sizeof(uint32_t));
360 _mesa_sha1_update(&ctx
,
362 sizeof(set_layout
->binding
[0]) *
363 set_layout
->binding_count
);
366 layout
->dynamic_offset_count
= dynamic_offset_count
;
367 layout
->push_constant_size
= 0;
369 for (unsigned i
= 0; i
< pCreateInfo
->pushConstantRangeCount
; ++i
) {
370 const VkPushConstantRange
*range
= pCreateInfo
->pPushConstantRanges
+ i
;
371 layout
->push_constant_size
=
372 MAX2(layout
->push_constant_size
, range
->offset
+ range
->size
);
375 layout
->push_constant_size
= align(layout
->push_constant_size
, 16);
377 &ctx
, &layout
->push_constant_size
, sizeof(layout
->push_constant_size
));
378 _mesa_sha1_final(&ctx
, layout
->sha1
);
379 *pPipelineLayout
= tu_pipeline_layout_to_handle(layout
);
385 tu_DestroyPipelineLayout(VkDevice _device
,
386 VkPipelineLayout _pipelineLayout
,
387 const VkAllocationCallbacks
*pAllocator
)
389 TU_FROM_HANDLE(tu_device
, device
, _device
);
390 TU_FROM_HANDLE(tu_pipeline_layout
, pipeline_layout
, _pipelineLayout
);
392 if (!pipeline_layout
)
394 vk_free2(&device
->alloc
, pAllocator
, pipeline_layout
);
400 tu_CreateDescriptorPool(VkDevice _device
,
401 const VkDescriptorPoolCreateInfo
*pCreateInfo
,
402 const VkAllocationCallbacks
*pAllocator
,
403 VkDescriptorPool
*pDescriptorPool
)
405 TU_FROM_HANDLE(tu_device
, device
, _device
);
412 tu_DestroyDescriptorPool(VkDevice _device
,
413 VkDescriptorPool _pool
,
414 const VkAllocationCallbacks
*pAllocator
)
419 tu_ResetDescriptorPool(VkDevice _device
,
420 VkDescriptorPool descriptorPool
,
421 VkDescriptorPoolResetFlags flags
)
423 TU_FROM_HANDLE(tu_device
, device
, _device
);
424 TU_FROM_HANDLE(tu_descriptor_pool
, pool
, descriptorPool
);
426 tu_use_args(device
, pool
);
432 tu_AllocateDescriptorSets(VkDevice _device
,
433 const VkDescriptorSetAllocateInfo
*pAllocateInfo
,
434 VkDescriptorSet
*pDescriptorSets
)
436 TU_FROM_HANDLE(tu_device
, device
, _device
);
437 TU_FROM_HANDLE(tu_descriptor_pool
, pool
, pAllocateInfo
->descriptorPool
);
439 tu_use_args(device
, pool
);
445 tu_FreeDescriptorSets(VkDevice _device
,
446 VkDescriptorPool descriptorPool
,
448 const VkDescriptorSet
*pDescriptorSets
)
450 TU_FROM_HANDLE(tu_device
, device
, _device
);
451 TU_FROM_HANDLE(tu_descriptor_pool
, pool
, descriptorPool
);
453 tu_use_args(device
, pool
);
459 tu_update_descriptor_sets(struct tu_device
*device
,
460 struct tu_cmd_buffer
*cmd_buffer
,
461 VkDescriptorSet dstSetOverride
,
462 uint32_t descriptorWriteCount
,
463 const VkWriteDescriptorSet
*pDescriptorWrites
,
464 uint32_t descriptorCopyCount
,
465 const VkCopyDescriptorSet
*pDescriptorCopies
)
470 tu_UpdateDescriptorSets(VkDevice _device
,
471 uint32_t descriptorWriteCount
,
472 const VkWriteDescriptorSet
*pDescriptorWrites
,
473 uint32_t descriptorCopyCount
,
474 const VkCopyDescriptorSet
*pDescriptorCopies
)
476 TU_FROM_HANDLE(tu_device
, device
, _device
);
478 tu_update_descriptor_sets(device
,
481 descriptorWriteCount
,
488 tu_CreateDescriptorUpdateTemplate(
490 const VkDescriptorUpdateTemplateCreateInfoKHR
*pCreateInfo
,
491 const VkAllocationCallbacks
*pAllocator
,
492 VkDescriptorUpdateTemplateKHR
*pDescriptorUpdateTemplate
)
494 TU_FROM_HANDLE(tu_device
, device
, _device
);
496 tu_descriptor_set_layout
, set_layout
, pCreateInfo
->descriptorSetLayout
);
497 const uint32_t entry_count
= pCreateInfo
->descriptorUpdateEntryCount
;
499 sizeof(struct tu_descriptor_update_template
) +
500 sizeof(struct tu_descriptor_update_template_entry
) * entry_count
;
501 struct tu_descriptor_update_template
*templ
;
504 &device
->alloc
, pAllocator
, size
, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
506 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
508 *pDescriptorUpdateTemplate
= tu_descriptor_update_template_to_handle(templ
);
510 tu_use_args(set_layout
);
516 tu_DestroyDescriptorUpdateTemplate(
518 VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate
,
519 const VkAllocationCallbacks
*pAllocator
)
521 TU_FROM_HANDLE(tu_device
, device
, _device
);
523 tu_descriptor_update_template
, templ
, descriptorUpdateTemplate
);
528 vk_free2(&device
->alloc
, pAllocator
, templ
);
532 tu_update_descriptor_set_with_template(
533 struct tu_device
*device
,
534 struct tu_cmd_buffer
*cmd_buffer
,
535 struct tu_descriptor_set
*set
,
536 VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate
,
540 tu_descriptor_update_template
, templ
, descriptorUpdateTemplate
);
545 tu_UpdateDescriptorSetWithTemplate(
547 VkDescriptorSet descriptorSet
,
548 VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate
,
551 TU_FROM_HANDLE(tu_device
, device
, _device
);
552 TU_FROM_HANDLE(tu_descriptor_set
, set
, descriptorSet
);
554 tu_update_descriptor_set_with_template(
555 device
, NULL
, set
, descriptorUpdateTemplate
, pData
);
559 tu_CreateSamplerYcbcrConversion(
561 const VkSamplerYcbcrConversionCreateInfo
*pCreateInfo
,
562 const VkAllocationCallbacks
*pAllocator
,
563 VkSamplerYcbcrConversion
*pYcbcrConversion
)
565 *pYcbcrConversion
= VK_NULL_HANDLE
;
570 tu_DestroySamplerYcbcrConversion(VkDevice device
,
571 VkSamplerYcbcrConversion ycbcrConversion
,
572 const VkAllocationCallbacks
*pAllocator
)