mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
libs/vkd3d: Unroll descriptor tables and fill in push constants
This commit is contained in:
parent
ac9abe7740
commit
3328be8c87
@ -173,7 +173,7 @@ static VkShaderStageFlags stage_flags_from_visibility(D3D12_SHADER_VISIBILITY vi
|
||||
}
|
||||
}
|
||||
|
||||
static VkDescriptorType vk_descriptor_type_from_d3d12(D3D12_DESCRIPTOR_RANGE_TYPE type)
|
||||
static VkDescriptorType vk_descriptor_type_from_d3d12_range_type(D3D12_DESCRIPTOR_RANGE_TYPE type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@ -186,32 +186,65 @@ static VkDescriptorType vk_descriptor_type_from_d3d12(D3D12_DESCRIPTOR_RANGE_TYP
|
||||
case D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER:
|
||||
return VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||
default:
|
||||
FIXME("Unhandled descriptor type %#x.\n", type);
|
||||
FIXME("Unhandled descriptor range type type %#x.\n", type);
|
||||
return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||
}
|
||||
}
|
||||
|
||||
static VkDescriptorType vk_descriptor_type_from_d3d12_root_parameter(D3D12_ROOT_PARAMETER_TYPE type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case D3D12_ROOT_PARAMETER_TYPE_SRV:
|
||||
return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||
case D3D12_DESCRIPTOR_RANGE_TYPE_UAV:
|
||||
return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; /* FIXME: Add support for images. */
|
||||
case D3D12_ROOT_PARAMETER_TYPE_CBV:
|
||||
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
default:
|
||||
FIXME("Unhandled descriptor root parameter type %#x.\n", type);
|
||||
return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||
}
|
||||
}
|
||||
|
||||
static bool vk_binding_from_d3d12_descriptor_range(struct VkDescriptorSetLayoutBinding *binding_desc,
|
||||
const D3D12_DESCRIPTOR_RANGE *descriptor_range)
|
||||
const D3D12_DESCRIPTOR_RANGE *descriptor_range, unsigned int n)
|
||||
{
|
||||
binding_desc->binding = descriptor_range->BaseShaderRegister;
|
||||
binding_desc->descriptorType = vk_descriptor_type_from_d3d12(descriptor_range->RangeType);
|
||||
binding_desc->binding = descriptor_range->BaseShaderRegister + n;
|
||||
binding_desc->descriptorType = vk_descriptor_type_from_d3d12_range_type(descriptor_range->RangeType);
|
||||
binding_desc->descriptorCount = 1;
|
||||
|
||||
if (descriptor_range->NumDescriptors != 1)
|
||||
{
|
||||
FIXME("Unhandled descriptor count %u.\n", descriptor_range->NumDescriptors);
|
||||
return false;
|
||||
}
|
||||
if (descriptor_range->RegisterSpace)
|
||||
{
|
||||
FIXME("Unhandled register space %u.\n", descriptor_range->RegisterSpace);
|
||||
return false;
|
||||
}
|
||||
if (descriptor_range->OffsetInDescriptorsFromTableStart)
|
||||
if (descriptor_range->OffsetInDescriptorsFromTableStart != D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND)
|
||||
FIXME("Unhandled offset %#x.\n", descriptor_range->OffsetInDescriptorsFromTableStart);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool vk_count_descriptor_types(const VkDescriptorSetLayoutBinding *binding,
|
||||
size_t *cbv_count, size_t *uav_buffer_count, size_t *srv_count, size_t *sampler_count)
|
||||
{
|
||||
switch (binding->descriptorType)
|
||||
{
|
||||
FIXME("Unhandled offset %u.\n", descriptor_range->OffsetInDescriptorsFromTableStart);
|
||||
return false;
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
*sampler_count += binding->descriptorCount;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
*cbv_count += binding->descriptorCount;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
*srv_count += binding->descriptorCount;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
*uav_buffer_count += binding->descriptorCount;
|
||||
break;
|
||||
default:
|
||||
FIXME("Unhandled descriptor type %#x.\n", binding->descriptorType);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -220,12 +253,14 @@ static bool vk_binding_from_d3d12_descriptor_range(struct VkDescriptorSetLayoutB
|
||||
static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signature,
|
||||
struct d3d12_device *device, const D3D12_ROOT_SIGNATURE_DESC *desc)
|
||||
{
|
||||
size_t push_count = 0, descriptor_count = 0;
|
||||
size_t cbv_count = 0, srv_count = 0, uav_buffer_count = 0, sampler_count = 0;
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
struct VkPipelineLayoutCreateInfo pipeline_layout_info;
|
||||
struct VkDescriptorSetLayoutBinding *binding_desc;
|
||||
struct VkDescriptorSetLayoutBinding *binding_desc = NULL, *cur_binding;
|
||||
struct VkDescriptorSetLayoutCreateInfo set_desc;
|
||||
unsigned int i, j;
|
||||
struct VkPushConstantRange *push_constants = NULL;
|
||||
unsigned int i, j, k;
|
||||
VkResult vr;
|
||||
HRESULT hr;
|
||||
|
||||
@ -235,9 +270,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
|
||||
if (desc->Flags)
|
||||
FIXME("Ignoring root signature flags %#x.\n", desc->Flags);
|
||||
|
||||
if (!(binding_desc = vkd3d_calloc(desc->NumParameters + desc->NumStaticSamplers, sizeof(*binding_desc))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
/* Count the binding descriptors and push constants. */
|
||||
for (i = 0; i < desc->NumParameters; ++i)
|
||||
{
|
||||
const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i];
|
||||
@ -245,61 +278,118 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
|
||||
switch (p->ParameterType)
|
||||
{
|
||||
case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
|
||||
if (p->u.DescriptorTable.NumDescriptorRanges != 1)
|
||||
for (j = 0; j < p->u.DescriptorTable.NumDescriptorRanges; j++)
|
||||
{
|
||||
FIXME("Unhandled %u descriptor ranges.\n", p->u.DescriptorTable.NumDescriptorRanges);
|
||||
vkd3d_free(binding_desc);
|
||||
return E_NOTIMPL;
|
||||
if (p->u.DescriptorTable.pDescriptorRanges[j].NumDescriptors == 0xffffffff)
|
||||
{
|
||||
FIXME("Unhandled unbound descriptor range for parameter %u.\n", i);
|
||||
goto not_implemented;
|
||||
}
|
||||
descriptor_count += p->u.DescriptorTable.pDescriptorRanges[j].NumDescriptors;
|
||||
}
|
||||
if (!vk_binding_from_d3d12_descriptor_range(&binding_desc[i],
|
||||
p->u.DescriptorTable.pDescriptorRanges))
|
||||
{
|
||||
vkd3d_free(binding_desc);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
binding_desc[i].stageFlags = stage_flags_from_visibility(p->ShaderVisibility);
|
||||
binding_desc[i].pImmutableSamplers = NULL;
|
||||
break;
|
||||
|
||||
case D3D12_ROOT_PARAMETER_TYPE_CBV:
|
||||
/* FIXME: Register spaces should map to set layouts. */
|
||||
if (p->u.Descriptor.RegisterSpace)
|
||||
{
|
||||
FIXME("Unhandled register space %u for parameter %u.\n", p->u.Descriptor.RegisterSpace, i);
|
||||
vkd3d_free(binding_desc);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
binding_desc[i].binding = p->u.Descriptor.ShaderRegister;
|
||||
binding_desc[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
binding_desc[i].descriptorCount = 1;
|
||||
binding_desc[i].stageFlags = stage_flags_from_visibility(p->ShaderVisibility);
|
||||
binding_desc[i].pImmutableSamplers = NULL;
|
||||
case D3D12_ROOT_PARAMETER_TYPE_SRV:
|
||||
case D3D12_ROOT_PARAMETER_TYPE_UAV:
|
||||
descriptor_count++;
|
||||
break;
|
||||
|
||||
case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS:
|
||||
push_count++;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unhandled type %#x for parameter %u.\n", p->ParameterType, i);
|
||||
vkd3d_free(binding_desc);
|
||||
return E_NOTIMPL;
|
||||
goto not_implemented;
|
||||
}
|
||||
|
||||
switch (binding_desc[i].descriptorType)
|
||||
}
|
||||
|
||||
descriptor_count += desc->NumStaticSamplers;
|
||||
|
||||
if (!(binding_desc = vkd3d_calloc(descriptor_count, sizeof(*binding_desc))))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!(push_constants = vkd3d_calloc(push_count, sizeof(*push_constants))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
/* Map root constants to push constants. */
|
||||
for (i = 0, j = 0; i < desc->NumParameters; ++i)
|
||||
{
|
||||
const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i];
|
||||
if (p->ParameterType != D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS)
|
||||
continue;
|
||||
|
||||
/* FIXME: Register spaces should map to set layouts. */
|
||||
if (p->u.Constants.RegisterSpace)
|
||||
{
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
sampler_count += binding_desc[i].descriptorCount;
|
||||
FIXME("Unhandled register space %u for parameter %u.\n", p->u.Constants.RegisterSpace, i);
|
||||
goto not_implemented;
|
||||
}
|
||||
|
||||
push_constants[j].stageFlags = stage_flags_from_visibility(p->ShaderVisibility);
|
||||
push_constants[j].offset = 0;
|
||||
push_constants[j].size = 4 * p->u.Constants.Num32BitValues;
|
||||
j++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
cur_binding = binding_desc;
|
||||
for (i = 0; i < desc->NumParameters; ++i)
|
||||
{
|
||||
const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i];
|
||||
if (p->ParameterType == D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS)
|
||||
continue;
|
||||
|
||||
switch (p->ParameterType)
|
||||
{
|
||||
case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
|
||||
for (j = 0; j < p->u.DescriptorTable.NumDescriptorRanges; j++)
|
||||
{
|
||||
for (k = 0; k < p->u.DescriptorTable.pDescriptorRanges[j].NumDescriptors; ++k)
|
||||
{
|
||||
if (!vk_binding_from_d3d12_descriptor_range(cur_binding,
|
||||
&p->u.DescriptorTable.pDescriptorRanges[j], k))
|
||||
goto not_implemented;
|
||||
|
||||
cur_binding->stageFlags = stage_flags_from_visibility(p->ShaderVisibility);
|
||||
cur_binding->pImmutableSamplers = NULL;
|
||||
|
||||
if (!vk_count_descriptor_types(cur_binding, &cbv_count, &uav_buffer_count,
|
||||
&srv_count, &sampler_count))
|
||||
goto not_implemented;
|
||||
|
||||
cur_binding++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
cbv_count += binding_desc[i].descriptorCount;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
srv_count += binding_desc[i].descriptorCount;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
uav_buffer_count += binding_desc[i].descriptorCount;
|
||||
|
||||
case D3D12_ROOT_PARAMETER_TYPE_CBV:
|
||||
case D3D12_ROOT_PARAMETER_TYPE_SRV:
|
||||
case D3D12_ROOT_PARAMETER_TYPE_UAV:
|
||||
/* FIXME: Register spaces should map to set layouts. */
|
||||
if (p->u.Descriptor.RegisterSpace)
|
||||
{
|
||||
FIXME("Unhandled register space %u for parameter %u.\n", p->u.Descriptor.RegisterSpace, i);
|
||||
goto not_implemented;
|
||||
}
|
||||
cur_binding->binding = p->u.Descriptor.ShaderRegister;
|
||||
cur_binding->descriptorType = vk_descriptor_type_from_d3d12_root_parameter(p->ParameterType);
|
||||
cur_binding->descriptorCount = 1;
|
||||
cur_binding->stageFlags = stage_flags_from_visibility(p->ShaderVisibility);
|
||||
cur_binding->pImmutableSamplers = NULL;
|
||||
|
||||
if (!vk_count_descriptor_types(cur_binding, &cbv_count, &uav_buffer_count,
|
||||
&srv_count, &sampler_count))
|
||||
goto not_implemented;
|
||||
|
||||
cur_binding++;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unhandled descriptor type %#x.\n", binding_desc[i].descriptorType);
|
||||
vkd3d_free(binding_desc);
|
||||
return E_NOTIMPL;
|
||||
FIXME("Unhandled type %#x for parameter %u.\n", p->ParameterType, i);
|
||||
goto not_implemented;
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,43 +398,48 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
|
||||
sizeof(*root_signature->static_samplers))))
|
||||
{
|
||||
vkd3d_free(binding_desc);
|
||||
vkd3d_free(push_constants);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
sampler_count += desc->NumStaticSamplers;
|
||||
for (j = 0; j < desc->NumStaticSamplers; ++i, ++j)
|
||||
for (i = 0; i < desc->NumStaticSamplers; ++i)
|
||||
{
|
||||
const D3D12_STATIC_SAMPLER_DESC *s = &desc->pStaticSamplers[j];
|
||||
const D3D12_STATIC_SAMPLER_DESC *s = &desc->pStaticSamplers[i];
|
||||
|
||||
if (s->RegisterSpace)
|
||||
FIXME("Unhandled register space %u for static sampler %u.\n", s->RegisterSpace, j);
|
||||
FIXME("Unhandled register space %u for static sampler %u.\n", s->RegisterSpace, i);
|
||||
|
||||
if (FAILED(hr = d3d12_device_create_static_sampler(device, s, &root_signature->static_samplers[j])))
|
||||
if (FAILED(hr = d3d12_device_create_static_sampler(device, s, &root_signature->static_samplers[i])))
|
||||
{
|
||||
for (i = 0; i < j; ++i)
|
||||
VK_CALL(vkDestroySampler(device->vk_device, root_signature->static_samplers[i], NULL));
|
||||
for (j = 0; j < i; ++j)
|
||||
VK_CALL(vkDestroySampler(device->vk_device, root_signature->static_samplers[j], NULL));
|
||||
vkd3d_free(root_signature->static_samplers);
|
||||
vkd3d_free(binding_desc);
|
||||
vkd3d_free(push_constants);
|
||||
return hr;
|
||||
}
|
||||
|
||||
binding_desc[i].binding = s->ShaderRegister;
|
||||
binding_desc[i].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||
binding_desc[i].descriptorCount = 1;
|
||||
binding_desc[i].stageFlags = stage_flags_from_visibility(s->ShaderVisibility);
|
||||
binding_desc[i].pImmutableSamplers = &root_signature->static_samplers[j];
|
||||
cur_binding->binding = s->ShaderRegister;
|
||||
cur_binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||
cur_binding->descriptorCount = 1;
|
||||
cur_binding->stageFlags = stage_flags_from_visibility(s->ShaderVisibility);
|
||||
cur_binding->pImmutableSamplers = &root_signature->static_samplers[i];
|
||||
|
||||
cur_binding++;
|
||||
}
|
||||
|
||||
set_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
set_desc.pNext = NULL;
|
||||
set_desc.flags = 0;
|
||||
set_desc.bindingCount = desc->NumParameters + desc->NumStaticSamplers;
|
||||
set_desc.bindingCount = descriptor_count;
|
||||
set_desc.pBindings = binding_desc;
|
||||
vr = VK_CALL(vkCreateDescriptorSetLayout(device->vk_device, &set_desc, NULL, &root_signature->vk_set_layout));
|
||||
vkd3d_free(binding_desc);
|
||||
if (vr < 0)
|
||||
{
|
||||
WARN("Failed to create Vulkan descriptor set layout, vr %d.\n", vr);
|
||||
vkd3d_free(push_constants);
|
||||
return hresult_from_vk_result(vr);
|
||||
}
|
||||
|
||||
@ -366,6 +461,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
|
||||
for (i = 0; i < root_signature->static_sampler_count; ++i)
|
||||
VK_CALL(vkDestroySampler(device->vk_device, root_signature->static_samplers[i], NULL));
|
||||
vkd3d_free(root_signature->static_samplers);
|
||||
vkd3d_free(push_constants);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
@ -402,8 +498,8 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
|
||||
pipeline_layout_info.flags = 0;
|
||||
pipeline_layout_info.setLayoutCount = 1;
|
||||
pipeline_layout_info.pSetLayouts = &root_signature->vk_set_layout;
|
||||
pipeline_layout_info.pushConstantRangeCount = 0;
|
||||
pipeline_layout_info.pPushConstantRanges = NULL;
|
||||
pipeline_layout_info.pushConstantRangeCount = push_count;
|
||||
pipeline_layout_info.pPushConstantRanges = push_constants;
|
||||
if ((vr = VK_CALL(vkCreatePipelineLayout(device->vk_device, &pipeline_layout_info, NULL,
|
||||
&root_signature->vk_pipeline_layout))) < 0)
|
||||
{
|
||||
@ -413,13 +509,21 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
|
||||
for (i = 0; i < root_signature->static_sampler_count; ++i)
|
||||
VK_CALL(vkDestroySampler(device->vk_device, root_signature->static_samplers[i], NULL));
|
||||
vkd3d_free(root_signature->static_samplers);
|
||||
vkd3d_free(push_constants);
|
||||
return hresult_from_vk_result(vr);
|
||||
}
|
||||
|
||||
vkd3d_free(push_constants);
|
||||
|
||||
root_signature->device = device;
|
||||
ID3D12Device_AddRef(&device->ID3D12Device_iface);
|
||||
|
||||
return S_OK;
|
||||
|
||||
not_implemented:
|
||||
vkd3d_free(binding_desc);
|
||||
vkd3d_free(push_constants);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT d3d12_root_signature_create(struct d3d12_device *device,
|
||||
|
Loading…
Reference in New Issue
Block a user