mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-22 10:58:08 +02:00
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35708>
131 lines
4 KiB
C
131 lines
4 KiB
C
/*
|
|
* Copyright © 2016 Red Hat.
|
|
* Copyright © 2016 Bas Nieuwenhuizen
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include "radv_pipeline_layout.h"
|
|
#include "radv_descriptor_set.h"
|
|
#include "radv_device.h"
|
|
#include "radv_entrypoints.h"
|
|
|
|
#include "vk_alloc.h"
|
|
#include "vk_log.h"
|
|
|
|
void
|
|
radv_pipeline_layout_init(struct radv_device *device, struct radv_pipeline_layout *layout, bool independent_sets)
|
|
{
|
|
memset(layout, 0, sizeof(*layout));
|
|
|
|
vk_object_base_init(&device->vk, &layout->base, VK_OBJECT_TYPE_PIPELINE_LAYOUT);
|
|
|
|
layout->independent_sets = independent_sets;
|
|
}
|
|
|
|
void
|
|
radv_pipeline_layout_add_set(struct radv_pipeline_layout *layout, uint32_t set_idx,
|
|
struct radv_descriptor_set_layout *set_layout)
|
|
{
|
|
if (layout->set[set_idx].layout)
|
|
return;
|
|
|
|
layout->num_sets = MAX2(set_idx + 1, layout->num_sets);
|
|
|
|
layout->set[set_idx].layout = set_layout;
|
|
vk_descriptor_set_layout_ref(&set_layout->vk);
|
|
|
|
layout->set[set_idx].dynamic_offset_start = layout->dynamic_offset_count;
|
|
|
|
layout->dynamic_offset_count += set_layout->dynamic_offset_count;
|
|
layout->dynamic_shader_stages |= set_layout->dynamic_shader_stages;
|
|
}
|
|
|
|
void
|
|
radv_pipeline_layout_hash(struct radv_pipeline_layout *layout)
|
|
{
|
|
struct mesa_blake3 ctx;
|
|
|
|
_mesa_blake3_init(&ctx);
|
|
for (uint32_t i = 0; i < layout->num_sets; i++) {
|
|
struct radv_descriptor_set_layout *set_layout = layout->set[i].layout;
|
|
|
|
if (!set_layout)
|
|
continue;
|
|
|
|
_mesa_blake3_update(&ctx, set_layout->hash, sizeof(set_layout->hash));
|
|
}
|
|
_mesa_blake3_update(&ctx, &layout->push_constant_size, sizeof(layout->push_constant_size));
|
|
_mesa_blake3_final(&ctx, layout->hash);
|
|
}
|
|
|
|
void
|
|
radv_pipeline_layout_finish(struct radv_device *device, struct radv_pipeline_layout *layout)
|
|
{
|
|
for (uint32_t i = 0; i < layout->num_sets; i++) {
|
|
if (!layout->set[i].layout)
|
|
continue;
|
|
|
|
vk_descriptor_set_layout_unref(&device->vk, &layout->set[i].layout->vk);
|
|
}
|
|
|
|
vk_object_base_finish(&layout->base);
|
|
}
|
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
|
radv_CreatePipelineLayout(VkDevice _device, const VkPipelineLayoutCreateInfo *pCreateInfo,
|
|
const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout)
|
|
{
|
|
VK_FROM_HANDLE(radv_device, device, _device);
|
|
struct radv_pipeline_layout *layout;
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
|
|
|
|
layout = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*layout), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
|
if (layout == NULL)
|
|
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
radv_pipeline_layout_init(device, layout, pCreateInfo->flags & VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
|
|
|
|
layout->num_sets = pCreateInfo->setLayoutCount;
|
|
|
|
for (uint32_t set = 0; set < pCreateInfo->setLayoutCount; set++) {
|
|
VK_FROM_HANDLE(radv_descriptor_set_layout, set_layout, pCreateInfo->pSetLayouts[set]);
|
|
|
|
if (set_layout == NULL) {
|
|
layout->set[set].layout = NULL;
|
|
continue;
|
|
}
|
|
|
|
radv_pipeline_layout_add_set(layout, set, set_layout);
|
|
}
|
|
|
|
layout->push_constant_size = 0;
|
|
|
|
for (unsigned i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) {
|
|
const VkPushConstantRange *range = pCreateInfo->pPushConstantRanges + i;
|
|
layout->push_constant_size = MAX2(layout->push_constant_size, range->offset + range->size);
|
|
}
|
|
|
|
layout->push_constant_size = align(layout->push_constant_size, 16);
|
|
|
|
radv_pipeline_layout_hash(layout);
|
|
|
|
*pPipelineLayout = radv_pipeline_layout_to_handle(layout);
|
|
|
|
return VK_SUCCESS;
|
|
}
|
|
|
|
VKAPI_ATTR void VKAPI_CALL
|
|
radv_DestroyPipelineLayout(VkDevice _device, VkPipelineLayout _pipelineLayout, const VkAllocationCallbacks *pAllocator)
|
|
{
|
|
VK_FROM_HANDLE(radv_device, device, _device);
|
|
VK_FROM_HANDLE(radv_pipeline_layout, pipeline_layout, _pipelineLayout);
|
|
|
|
if (!pipeline_layout)
|
|
return;
|
|
|
|
radv_pipeline_layout_finish(device, pipeline_layout);
|
|
|
|
vk_free2(&device->vk.alloc, pAllocator, pipeline_layout);
|
|
}
|