vkd3d: Create bindless descriptor set layouts.

Don't enable any bindless features for now so that we don't
introduce regressions as features get added.

Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
This commit is contained in:
Philip Rebohle 2020-03-06 13:39:42 +01:00 committed by Hans-Kristian Arntzen
parent c4a173ddca
commit 01cbbaea81
3 changed files with 189 additions and 1 deletions

View File

@ -2208,6 +2208,7 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface)
vkd3d_cleanup_format_info(device);
vkd3d_uav_clear_state_cleanup(&device->uav_clear_state, device);
vkd3d_bindless_state_cleanup(&device->bindless_state, device);
vkd3d_destroy_null_resources(&device->null_resources, device);
vkd3d_gpu_va_allocator_cleanup(&device->gpu_va_allocator);
vkd3d_render_pass_cache_cleanup(&device->render_pass_cache, device);
@ -3471,9 +3472,12 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
if (FAILED(hr = vkd3d_init_null_resources(&device->null_resources, device)))
goto out_cleanup_format_info;
if (FAILED(hr = vkd3d_uav_clear_state_init(&device->uav_clear_state, device)))
if (FAILED(hr = vkd3d_bindless_state_init(&device->bindless_state, device)))
goto out_destroy_null_resources;
if (FAILED(hr = vkd3d_uav_clear_state_init(&device->uav_clear_state, device)))
goto out_cleanup_bindless_state;
vkd3d_render_pass_cache_init(&device->render_pass_cache);
vkd3d_gpu_va_allocator_init(&device->gpu_va_allocator);
@ -3485,6 +3489,8 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
return S_OK;
out_cleanup_bindless_state:
vkd3d_bindless_state_cleanup(&device->bindless_state, device);
out_destroy_null_resources:
vkd3d_destroy_null_resources(&device->null_resources, device);
out_cleanup_format_info:

View File

@ -2580,6 +2580,154 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta
return vk_pipeline;
}
static D3D12_DESCRIPTOR_HEAP_TYPE d3d12_descriptor_heap_type_from_range_type(D3D12_DESCRIPTOR_RANGE_TYPE range_type)
{
switch (range_type)
{
case D3D12_DESCRIPTOR_RANGE_TYPE_CBV:
case D3D12_DESCRIPTOR_RANGE_TYPE_SRV:
case D3D12_DESCRIPTOR_RANGE_TYPE_UAV:
return D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
case D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER:
return D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
default:
ERR("Invalid descriptor range type %d.\n", range_type);
return D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
}
}
static uint32_t d3d12_max_descriptor_count_from_range_type(D3D12_DESCRIPTOR_RANGE_TYPE range_type)
{
switch (range_type)
{
case D3D12_DESCRIPTOR_RANGE_TYPE_CBV:
case D3D12_DESCRIPTOR_RANGE_TYPE_SRV:
case D3D12_DESCRIPTOR_RANGE_TYPE_UAV:
return 1000000;
case D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER:
return 2048;
default:
ERR("Invalid descriptor range type %d.\n", range_type);
return 0;
}
}
static HRESULT vkd3d_bindless_state_add_binding(struct vkd3d_bindless_state *bindless_state,
struct d3d12_device *device, D3D12_DESCRIPTOR_RANGE_TYPE range_type,
enum vkd3d_shader_binding_flag binding_flag)
{
struct vkd3d_bindless_set_info *set_info = &bindless_state->set_info[bindless_state->set_count++];
VkDescriptorSetLayoutBindingFlagsCreateInfoEXT vk_binding_flags_info;
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
VkDescriptorSetLayoutCreateInfo vk_set_layout_info;
VkDescriptorSetLayoutBinding vk_binding_info;
VkDescriptorBindingFlagsEXT vk_binding_flags;
VkResult vr;
set_info->heap_type = d3d12_descriptor_heap_type_from_range_type(range_type);
set_info->range_type = range_type;
set_info->binding_flag = binding_flag;
vk_binding_flags = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT |
VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT |
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT |
VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT;
vk_binding_flags_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT;
vk_binding_flags_info.pNext = NULL;
vk_binding_flags_info.bindingCount = 1;
vk_binding_flags_info.pBindingFlags = &vk_binding_flags;
vk_binding_info.binding = 0;
vk_binding_info.descriptorType = vk_descriptor_type_from_d3d12_range_type(range_type,
binding_flag & VKD3D_SHADER_BINDING_FLAG_BUFFER);
vk_binding_info.descriptorCount = d3d12_max_descriptor_count_from_range_type(range_type);
vk_binding_info.stageFlags = VK_SHADER_STAGE_ALL;
vk_binding_info.pImmutableSamplers = NULL;
vk_set_layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
vk_set_layout_info.pNext = &vk_binding_flags_info;
vk_set_layout_info.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT;
vk_set_layout_info.bindingCount = 1;
vk_set_layout_info.pBindings = &vk_binding_info;
if ((vr = VK_CALL(vkCreateDescriptorSetLayout(device->vk_device,
&vk_set_layout_info, NULL, &set_info->vk_set_layout))) < 0)
ERR("Failed to create descriptor set layout, vr %d.\n", vr);
return hresult_from_vk_result(vr);
}
static uint32_t vkd3d_bindless_state_get_bindless_flags(struct d3d12_device *device)
{
/* FIXME implement proper feature check */
return 0;
}
HRESULT vkd3d_bindless_state_init(struct vkd3d_bindless_state *bindless_state,
struct d3d12_device *device)
{
HRESULT hr;
memset(bindless_state, 0, sizeof(*bindless_state));
bindless_state->flags = vkd3d_bindless_state_get_bindless_flags(device);
if (!bindless_state->flags)
return S_OK;
if (bindless_state->flags & VKD3D_BINDLESS_SAMPLER)
{
if (FAILED(hr = vkd3d_bindless_state_add_binding(bindless_state, device,
D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, VKD3D_SHADER_BINDING_FLAG_IMAGE)))
goto fail;
}
if (bindless_state->flags & VKD3D_BINDLESS_CBV)
{
if (FAILED(hr = vkd3d_bindless_state_add_binding(bindless_state, device,
D3D12_DESCRIPTOR_RANGE_TYPE_CBV, VKD3D_SHADER_BINDING_FLAG_BUFFER)))
goto fail;
}
if (bindless_state->flags & VKD3D_BINDLESS_SRV)
{
if (FAILED(hr = vkd3d_bindless_state_add_binding(bindless_state, device,
D3D12_DESCRIPTOR_RANGE_TYPE_SRV, VKD3D_SHADER_BINDING_FLAG_BUFFER)) ||
FAILED(hr = vkd3d_bindless_state_add_binding(bindless_state, device,
D3D12_DESCRIPTOR_RANGE_TYPE_SRV, VKD3D_SHADER_BINDING_FLAG_IMAGE)))
goto fail;
}
if (bindless_state->flags & VKD3D_BINDLESS_UAV)
{
if (FAILED(hr = vkd3d_bindless_state_add_binding(bindless_state, device,
D3D12_DESCRIPTOR_RANGE_TYPE_UAV, VKD3D_SHADER_BINDING_FLAG_BUFFER)) ||
FAILED(hr = vkd3d_bindless_state_add_binding(bindless_state, device,
D3D12_DESCRIPTOR_RANGE_TYPE_UAV, VKD3D_SHADER_BINDING_FLAG_IMAGE)))
goto fail;
}
return S_OK;
fail:
vkd3d_bindless_state_cleanup(bindless_state, device);
return hr;
}
void vkd3d_bindless_state_cleanup(struct vkd3d_bindless_state *bindless_state,
struct d3d12_device *device)
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
unsigned int i;
for (i = 0; i < bindless_state->set_count; i++)
VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, bindless_state->set_info[i].vk_set_layout, NULL));
}
static void vkd3d_uav_clear_pipelines_cleanup(struct vkd3d_uav_clear_pipelines *pipelines,
struct d3d12_device *device)
{

View File

@ -54,6 +54,8 @@
#define VKD3D_MAX_SHADER_STAGES 5u
#define VKD3D_MAX_VK_SYNC_OBJECTS 4u
#define VKD3D_MAX_BINDLESS_DESCRIPTOR_SETS 6u
struct d3d12_command_list;
struct d3d12_device;
struct d3d12_resource;
@ -1078,6 +1080,37 @@ HRESULT vkd3d_init_null_resources(struct vkd3d_null_resources *null_resources,
void vkd3d_destroy_null_resources(struct vkd3d_null_resources *null_resources,
struct d3d12_device *device) DECLSPEC_HIDDEN;
/* Bindless */
enum vkd3d_bindless_flags
{
VKD3D_BINDLESS_SAMPLER = (1u << 0),
VKD3D_BINDLESS_CBV = (1u << 1),
VKD3D_BINDLESS_SRV = (1u << 2),
VKD3D_BINDLESS_UAV = (1u << 3),
};
struct vkd3d_bindless_set_info
{
D3D12_DESCRIPTOR_HEAP_TYPE heap_type;
D3D12_DESCRIPTOR_RANGE_TYPE range_type;
enum vkd3d_shader_binding_flag binding_flag;
VkDescriptorSetLayout vk_set_layout;
};
struct vkd3d_bindless_state
{
uint32_t flags; /* vkd3d_bindless_flags */
struct vkd3d_bindless_set_info set_info[VKD3D_MAX_BINDLESS_DESCRIPTOR_SETS];
unsigned int set_count;
};
HRESULT vkd3d_bindless_state_init(struct vkd3d_bindless_state *bindless_state,
struct d3d12_device *device) DECLSPEC_HIDDEN;
void vkd3d_bindless_state_cleanup(struct vkd3d_bindless_state *bindless_state,
struct d3d12_device *device) DECLSPEC_HIDDEN;
struct vkd3d_format_compatibility_list
{
DXGI_FORMAT typeless_format;
@ -1163,6 +1196,7 @@ struct d3d12_device
unsigned int format_compatibility_list_count;
const struct vkd3d_format_compatibility_list *format_compatibility_lists;
struct vkd3d_null_resources null_resources;
struct vkd3d_bindless_state bindless_state;
struct vkd3d_uav_clear_state uav_clear_state;
};