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];
105 VkDescriptorSetLayoutBinding
*bindings
=
106 create_sorted_bindings(pCreateInfo
->pBindings
, pCreateInfo
->bindingCount
);
108 vk_free2(&device
->alloc
, pAllocator
, set_layout
);
109 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
112 set_layout
->binding_count
= max_binding
+ 1;
113 set_layout
->shader_stages
= 0;
114 set_layout
->dynamic_shader_stages
= 0;
115 set_layout
->has_immutable_samplers
= false;
116 set_layout
->size
= 0;
119 set_layout
->binding
, 0, size
- sizeof(struct tu_descriptor_set_layout
));
121 uint32_t buffer_count
= 0;
122 uint32_t dynamic_offset_count
= 0;
124 for (uint32_t j
= 0; j
< pCreateInfo
->bindingCount
; j
++) {
125 const VkDescriptorSetLayoutBinding
*binding
= bindings
+ j
;
126 uint32_t b
= binding
->binding
;
128 unsigned binding_buffer_count
= 0;
130 switch (binding
->descriptorType
) {
131 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
132 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
133 assert(!(pCreateInfo
->flags
&
134 VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR
));
135 set_layout
->binding
[b
].dynamic_offset_count
= 1;
136 set_layout
->dynamic_shader_stages
|= binding
->stageFlags
;
137 set_layout
->binding
[b
].size
= 0;
138 binding_buffer_count
= 1;
141 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
142 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
143 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
144 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
145 set_layout
->binding
[b
].size
= 16;
146 binding_buffer_count
= 1;
149 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
150 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
151 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
:
152 /* main descriptor + fmask descriptor */
153 set_layout
->binding
[b
].size
= 64;
154 binding_buffer_count
= 1;
157 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
158 /* main descriptor + fmask descriptor + sampler */
159 set_layout
->binding
[b
].size
= 96;
160 binding_buffer_count
= 1;
163 case VK_DESCRIPTOR_TYPE_SAMPLER
:
164 set_layout
->binding
[b
].size
= 16;
168 unreachable("unknown descriptor type\n");
172 set_layout
->size
= align(set_layout
->size
, alignment
);
173 set_layout
->binding
[b
].type
= binding
->descriptorType
;
174 set_layout
->binding
[b
].array_size
= binding
->descriptorCount
;
175 set_layout
->binding
[b
].offset
= set_layout
->size
;
176 set_layout
->binding
[b
].buffer_offset
= buffer_count
;
177 set_layout
->binding
[b
].dynamic_offset_offset
= dynamic_offset_count
;
179 if (variable_flags
&& binding
->binding
< variable_flags
->bindingCount
&&
180 (variable_flags
->pBindingFlags
[binding
->binding
] &
181 VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT
)) {
182 assert(!binding
->pImmutableSamplers
); /* Terribly ill defined how many
183 samplers are valid */
184 assert(binding
->binding
== max_binding
);
186 set_layout
->has_variable_descriptors
= true;
189 if (binding
->pImmutableSamplers
) {
190 set_layout
->binding
[b
].immutable_samplers_offset
= samplers_offset
;
191 set_layout
->has_immutable_samplers
= true;
195 binding
->descriptorCount
* set_layout
->binding
[b
].size
;
196 buffer_count
+= binding
->descriptorCount
* binding_buffer_count
;
197 dynamic_offset_count
+=
198 binding
->descriptorCount
* set_layout
->binding
[b
].dynamic_offset_count
;
199 set_layout
->shader_stages
|= binding
->stageFlags
;
204 set_layout
->buffer_count
= buffer_count
;
205 set_layout
->dynamic_offset_count
= dynamic_offset_count
;
207 *pSetLayout
= tu_descriptor_set_layout_to_handle(set_layout
);
213 tu_DestroyDescriptorSetLayout(VkDevice _device
,
214 VkDescriptorSetLayout _set_layout
,
215 const VkAllocationCallbacks
*pAllocator
)
217 TU_FROM_HANDLE(tu_device
, device
, _device
);
218 TU_FROM_HANDLE(tu_descriptor_set_layout
, set_layout
, _set_layout
);
223 vk_free2(&device
->alloc
, pAllocator
, set_layout
);
227 tu_GetDescriptorSetLayoutSupport(
229 const VkDescriptorSetLayoutCreateInfo
*pCreateInfo
,
230 VkDescriptorSetLayoutSupport
*pSupport
)
232 VkDescriptorSetLayoutBinding
*bindings
=
233 create_sorted_bindings(pCreateInfo
->pBindings
, pCreateInfo
->bindingCount
);
235 pSupport
->supported
= false;
239 const VkDescriptorSetLayoutBindingFlagsCreateInfoEXT
*variable_flags
=
240 vk_find_struct_const(pCreateInfo
->pNext
,
241 DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT
);
242 VkDescriptorSetVariableDescriptorCountLayoutSupportEXT
*variable_count
=
244 (void *)pCreateInfo
->pNext
,
245 DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT
);
246 if (variable_count
) {
247 variable_count
->maxVariableDescriptorCount
= 0;
250 bool supported
= true;
252 for (uint32_t i
= 0; i
< pCreateInfo
->bindingCount
; i
++) {
253 const VkDescriptorSetLayoutBinding
*binding
= bindings
+ i
;
255 uint64_t descriptor_size
= 0;
256 uint64_t descriptor_alignment
= 1;
257 switch (binding
->descriptorType
) {
258 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
259 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
261 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
262 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
263 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
264 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
265 descriptor_size
= 16;
266 descriptor_alignment
= 16;
268 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
269 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
270 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
:
271 descriptor_size
= 64;
272 descriptor_alignment
= 32;
274 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
275 descriptor_size
= 96;
276 descriptor_alignment
= 32;
278 case VK_DESCRIPTOR_TYPE_SAMPLER
:
279 descriptor_size
= 16;
280 descriptor_alignment
= 16;
283 unreachable("unknown descriptor type\n");
287 if (size
&& !align_u64(size
, descriptor_alignment
)) {
290 size
= align_u64(size
, descriptor_alignment
);
292 uint64_t max_count
= UINT64_MAX
;
294 max_count
= (UINT64_MAX
- size
) / descriptor_size
;
296 if (max_count
< binding
->descriptorCount
) {
299 if (variable_flags
&& binding
->binding
< variable_flags
->bindingCount
&&
301 (variable_flags
->pBindingFlags
[binding
->binding
] &
302 VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT
)) {
303 variable_count
->maxVariableDescriptorCount
=
304 MIN2(UINT32_MAX
, max_count
);
306 size
+= binding
->descriptorCount
* descriptor_size
;
311 pSupport
->supported
= supported
;
315 * Pipeline layouts. These have nothing to do with the pipeline. They are
316 * just multiple descriptor set layouts pasted together.
320 tu_CreatePipelineLayout(VkDevice _device
,
321 const VkPipelineLayoutCreateInfo
*pCreateInfo
,
322 const VkAllocationCallbacks
*pAllocator
,
323 VkPipelineLayout
*pPipelineLayout
)
325 TU_FROM_HANDLE(tu_device
, device
, _device
);
326 struct tu_pipeline_layout
*layout
;
327 struct mesa_sha1 ctx
;
329 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
);
331 layout
= vk_alloc2(&device
->alloc
,
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
++) {
346 tu_descriptor_set_layout
, set_layout
, 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));
359 _mesa_sha1_update(&ctx
,
361 sizeof(set_layout
->binding
[0]) *
362 set_layout
->binding_count
);
365 layout
->dynamic_offset_count
= dynamic_offset_count
;
366 layout
->push_constant_size
= 0;
368 for (unsigned i
= 0; i
< pCreateInfo
->pushConstantRangeCount
; ++i
) {
369 const VkPushConstantRange
*range
= pCreateInfo
->pPushConstantRanges
+ i
;
370 layout
->push_constant_size
=
371 MAX2(layout
->push_constant_size
, range
->offset
+ range
->size
);
374 layout
->push_constant_size
= align(layout
->push_constant_size
, 16);
376 &ctx
, &layout
->push_constant_size
, sizeof(layout
->push_constant_size
));
377 _mesa_sha1_final(&ctx
, layout
->sha1
);
378 *pPipelineLayout
= tu_pipeline_layout_to_handle(layout
);
384 tu_DestroyPipelineLayout(VkDevice _device
,
385 VkPipelineLayout _pipelineLayout
,
386 const VkAllocationCallbacks
*pAllocator
)
388 TU_FROM_HANDLE(tu_device
, device
, _device
);
389 TU_FROM_HANDLE(tu_pipeline_layout
, pipeline_layout
, _pipelineLayout
);
391 if (!pipeline_layout
)
393 vk_free2(&device
->alloc
, pAllocator
, pipeline_layout
);
399 tu_CreateDescriptorPool(VkDevice _device
,
400 const VkDescriptorPoolCreateInfo
*pCreateInfo
,
401 const VkAllocationCallbacks
*pAllocator
,
402 VkDescriptorPool
*pDescriptorPool
)
404 TU_FROM_HANDLE(tu_device
, device
, _device
);
405 struct tu_descriptor_pool
*pool
;
411 tu_DestroyDescriptorPool(VkDevice _device
,
412 VkDescriptorPool _pool
,
413 const VkAllocationCallbacks
*pAllocator
)
418 tu_ResetDescriptorPool(VkDevice _device
,
419 VkDescriptorPool descriptorPool
,
420 VkDescriptorPoolResetFlags flags
)
422 TU_FROM_HANDLE(tu_device
, device
, _device
);
423 TU_FROM_HANDLE(tu_descriptor_pool
, pool
, descriptorPool
);
429 tu_AllocateDescriptorSets(VkDevice _device
,
430 const VkDescriptorSetAllocateInfo
*pAllocateInfo
,
431 VkDescriptorSet
*pDescriptorSets
)
433 TU_FROM_HANDLE(tu_device
, device
, _device
);
434 TU_FROM_HANDLE(tu_descriptor_pool
, pool
, pAllocateInfo
->descriptorPool
);
440 tu_FreeDescriptorSets(VkDevice _device
,
441 VkDescriptorPool descriptorPool
,
443 const VkDescriptorSet
*pDescriptorSets
)
445 TU_FROM_HANDLE(tu_device
, device
, _device
);
446 TU_FROM_HANDLE(tu_descriptor_pool
, pool
, descriptorPool
);
452 tu_update_descriptor_sets(struct tu_device
*device
,
453 struct tu_cmd_buffer
*cmd_buffer
,
454 VkDescriptorSet dstSetOverride
,
455 uint32_t descriptorWriteCount
,
456 const VkWriteDescriptorSet
*pDescriptorWrites
,
457 uint32_t descriptorCopyCount
,
458 const VkCopyDescriptorSet
*pDescriptorCopies
)
463 tu_UpdateDescriptorSets(VkDevice _device
,
464 uint32_t descriptorWriteCount
,
465 const VkWriteDescriptorSet
*pDescriptorWrites
,
466 uint32_t descriptorCopyCount
,
467 const VkCopyDescriptorSet
*pDescriptorCopies
)
469 TU_FROM_HANDLE(tu_device
, device
, _device
);
471 tu_update_descriptor_sets(device
,
474 descriptorWriteCount
,
481 tu_CreateDescriptorUpdateTemplate(
483 const VkDescriptorUpdateTemplateCreateInfoKHR
*pCreateInfo
,
484 const VkAllocationCallbacks
*pAllocator
,
485 VkDescriptorUpdateTemplateKHR
*pDescriptorUpdateTemplate
)
487 TU_FROM_HANDLE(tu_device
, device
, _device
);
489 tu_descriptor_set_layout
, set_layout
, pCreateInfo
->descriptorSetLayout
);
490 const uint32_t entry_count
= pCreateInfo
->descriptorUpdateEntryCount
;
492 sizeof(struct tu_descriptor_update_template
) +
493 sizeof(struct tu_descriptor_update_template_entry
) * entry_count
;
494 struct tu_descriptor_update_template
*templ
;
498 &device
->alloc
, pAllocator
, size
, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
500 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
502 *pDescriptorUpdateTemplate
= tu_descriptor_update_template_to_handle(templ
);
507 tu_DestroyDescriptorUpdateTemplate(
509 VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate
,
510 const VkAllocationCallbacks
*pAllocator
)
512 TU_FROM_HANDLE(tu_device
, device
, _device
);
514 tu_descriptor_update_template
, templ
, descriptorUpdateTemplate
);
519 vk_free2(&device
->alloc
, pAllocator
, templ
);
523 tu_update_descriptor_set_with_template(
524 struct tu_device
*device
,
525 struct tu_cmd_buffer
*cmd_buffer
,
526 struct tu_descriptor_set
*set
,
527 VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate
,
531 tu_descriptor_update_template
, templ
, descriptorUpdateTemplate
);
535 tu_UpdateDescriptorSetWithTemplate(
537 VkDescriptorSet descriptorSet
,
538 VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate
,
541 TU_FROM_HANDLE(tu_device
, device
, _device
);
542 TU_FROM_HANDLE(tu_descriptor_set
, set
, descriptorSet
);
544 tu_update_descriptor_set_with_template(
545 device
, NULL
, set
, descriptorUpdateTemplate
, pData
);
549 tu_CreateSamplerYcbcrConversion(
551 const VkSamplerYcbcrConversionCreateInfo
*pCreateInfo
,
552 const VkAllocationCallbacks
*pAllocator
,
553 VkSamplerYcbcrConversion
*pYcbcrConversion
)
555 *pYcbcrConversion
= VK_NULL_HANDLE
;
560 tu_DestroySamplerYcbcrConversion(VkDevice device
,
561 VkSamplerYcbcrConversion ycbcrConversion
,
562 const VkAllocationCallbacks
*pAllocator
)