From: Conor McCarthy Subject: [PATCH vkd3d 4/4] vkd3d: Add a helper function to calculate variable binding upper bound. Message-Id: <20210526080437.19137-4-cmccarthy@codeweavers.com> Date: Wed, 26 May 2021 18:04:37 +1000 In-Reply-To: <20210526080437.19137-1-cmccarthy@codeweavers.com> References: <20210526080437.19137-1-cmccarthy@codeweavers.com> Signed-off-by: Conor McCarthy --- libs/vkd3d/state.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 749d3763..03684264 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -749,6 +749,62 @@ static uint32_t vkd3d_descriptor_magic_from_d3d12(D3D12_DESCRIPTOR_RANGE_TYPE ty } } +static uint32_t vk_max_unbounded_range_descriptor_count(D3D12_SHADER_VISIBILITY visibility, + const uint32_t stage_count[5], uint32_t max_descriptors, uint32_t binding_count) +{ + static const unsigned int stages[5] = { + D3D12_SHADER_VISIBILITY_VERTEX, + D3D12_SHADER_VISIBILITY_HULL, + D3D12_SHADER_VISIBILITY_DOMAIN, + D3D12_SHADER_VISIBILITY_GEOMETRY, + D3D12_SHADER_VISIBILITY_PIXEL}; + uint32_t count = max_descriptors / binding_count; + unsigned int i; + + for (i = 0; i < 5; ++i) + if (visibility == D3D12_SHADER_VISIBILITY_ALL || visibility == stages[i]) + count = (max_descriptors > stage_count[i]) + ? min(count, (max_descriptors - stage_count[i]) / binding_count) + : 0; + if (!count) + ERR("Exceeded maximum bindless descriptor count for shader visibility %u.\n", visibility); + + return count; +} + +static unsigned int vk_descriptor_count_from_d3d12_desc_range_type(D3D12_DESCRIPTOR_RANGE_TYPE type, + D3D12_SHADER_VISIBILITY visibility, const struct d3d12_root_signature_info *info, + const struct d3d12_device *device) +{ + unsigned int all_max = vk_max_unbounded_range_descriptor_count(visibility, info->total_stage_count, + device->vk_info.device_limits.maxPerStageResources, info->total_unbounded_set_count); + unsigned int type_max; + + switch (type) + { + case D3D12_DESCRIPTOR_RANGE_TYPE_SRV: + type_max = vk_max_unbounded_range_descriptor_count(visibility, info->srv_stage_count, + device->vk_info.device_limits.maxPerStageDescriptorSampledImages, info->srv_unbounded_set_count); + break; + case D3D12_DESCRIPTOR_RANGE_TYPE_UAV: + type_max = vk_max_unbounded_range_descriptor_count(visibility, info->uav_stage_count, + device->vk_info.device_limits.maxPerStageDescriptorStorageImages, info->uav_unbounded_set_count); + break; + case D3D12_DESCRIPTOR_RANGE_TYPE_CBV: + type_max = vk_max_unbounded_range_descriptor_count(visibility, info->cbv_stage_count, + device->vk_info.device_limits.maxPerStageDescriptorUniformBuffers, info->cbv_unbounded_set_count); + break; + case D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER: + type_max = vk_max_unbounded_range_descriptor_count(visibility, info->sampler_stage_count, + device->vk_info.device_limits.maxPerStageDescriptorSamplers, info->sampler_unbounded_set_count); + break; + default: + ERR("Invalid range type %#x.\n", type); + return 0; + } + return min(type_max, all_max); +} + static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_root_signature *root_signature, const D3D12_ROOT_SIGNATURE_DESC *desc, struct vkd3d_descriptor_set_context *context) { -- 2.31.1