vkd3d: Rework static samplers.

Static samplers are embedded in the root signature, so we can create
a separate descriptor set layout and descriptor set which we only
need to rebind when the root signature itself changes.

Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
This commit is contained in:
Philip Rebohle 2020-03-03 20:28:38 +01:00 committed by Hans-Kristian Arntzen
parent ae12e22187
commit 28bf2eec3e
3 changed files with 86 additions and 19 deletions

View File

@ -1873,6 +1873,7 @@ static void d3d12_command_list_invalidate_root_parameters(struct d3d12_command_l
bindings->root_descriptor_dirty_mask = bindings->root_signature->root_descriptor_mask;
bindings->root_constant_dirty_mask = bindings->root_signature->root_constant_mask;
bindings->static_sampler_set_dirty = bindings->static_sampler_set != VK_NULL_HANDLE;
}
static bool vk_barrier_parameters_from_d3d12_resource_state(unsigned int state, unsigned int stencil_state,
@ -2745,6 +2746,21 @@ static bool vk_write_descriptor_set_from_root_descriptor(VkWriteDescriptorSet *v
return true;
}
static void d3d12_command_list_update_static_samplers(struct d3d12_command_list *list,
VkPipelineBindPoint bind_point)
{
struct vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point];
const struct d3d12_root_signature *root_signature = bindings->root_signature;
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
VK_CALL(vkCmdBindDescriptorSets(list->vk_command_buffer, bind_point,
root_signature->vk_pipeline_layout,
root_signature->sampler_descriptor_set,
1, &bindings->static_sampler_set, 0, NULL));
bindings->static_sampler_set_dirty = false;
}
static void d3d12_command_list_update_root_constants(struct d3d12_command_list *list,
VkPipelineBindPoint bind_point)
{
@ -2835,6 +2851,9 @@ static void d3d12_command_list_update_descriptors(struct d3d12_command_list *lis
if (!rs)
return;
if (bindings->static_sampler_set_dirty)
d3d12_command_list_update_static_samplers(list, bind_point);
if (bindings->descriptor_table_dirty_mask)
d3d12_command_list_prepare_descriptors(list, bind_point);
@ -4016,6 +4035,14 @@ static void d3d12_command_list_set_root_signature(struct d3d12_command_list *lis
return;
bindings->root_signature = root_signature;
bindings->static_sampler_set = VK_NULL_HANDLE;
if (root_signature && root_signature->vk_sampler_descriptor_layout)
{
/* FIXME allocate static sampler sets globally */
bindings->static_sampler_set = d3d12_command_allocator_allocate_descriptor_set(
list->allocator, root_signature->vk_sampler_descriptor_layout);
}
d3d12_command_list_invalidate_root_parameters(list, bind_point);
}

View File

@ -64,6 +64,7 @@ static void d3d12_root_signature_cleanup(struct d3d12_root_signature *root_signa
unsigned int i;
VK_CALL(vkDestroyPipelineLayout(device->vk_device, root_signature->vk_pipeline_layout, NULL));
VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, root_signature->vk_sampler_descriptor_layout, NULL));
VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, root_signature->vk_packed_descriptor_layout, NULL));
VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, root_signature->vk_root_descriptor_layout, NULL));
@ -712,34 +713,56 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign
}
static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signature *root_signature,
struct d3d12_device *device, const D3D12_ROOT_SIGNATURE_DESC *desc,
struct vkd3d_descriptor_set_context *context)
const D3D12_ROOT_SIGNATURE_DESC *desc, struct vkd3d_descriptor_set_context *context,
VkDescriptorSetLayout *vk_set_layout)
{
VkDescriptorSetLayoutBinding *cur_binding = context->current_binding;
VkDescriptorSetLayoutBinding *vk_binding_info, *vk_binding;
struct vkd3d_shader_resource_binding *binding;
unsigned int i;
HRESULT hr;
assert(root_signature->static_sampler_count == desc->NumStaticSamplers);
if (!desc->NumStaticSamplers)
return S_OK;
if (!(vk_binding_info = malloc(desc->NumStaticSamplers * sizeof(*vk_binding_info))))
return E_OUTOFMEMORY;
for (i = 0; i < desc->NumStaticSamplers; ++i)
{
const D3D12_STATIC_SAMPLER_DESC *s = &desc->pStaticSamplers[i];
if (FAILED(hr = vkd3d_create_static_sampler(device, s, &root_signature->static_samplers[i])))
return hr;
if (FAILED(hr = vkd3d_create_static_sampler(root_signature->device, s, &root_signature->static_samplers[i])))
goto cleanup;
cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature,
VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, s->RegisterSpace, s->ShaderRegister, 1, false, false, false,
vkd3d_shader_visibility_from_d3d12(s->ShaderVisibility), context);
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];
vk_binding = &vk_binding_info[i];
vk_binding->binding = context->vk_binding;
vk_binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
vk_binding->descriptorCount = 1;
vk_binding->stageFlags = stage_flags_from_visibility(s->ShaderVisibility);
vk_binding->pImmutableSamplers = &root_signature->static_samplers[i];
++cur_binding;
binding = &root_signature->bindings[context->binding_index];
binding->type = VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER;
binding->register_space = s->RegisterSpace;
binding->register_index = s->ShaderRegister;
binding->register_count = 1;
binding->descriptor_table = 0; /* ignored */
binding->descriptor_offset = 0; /* ignored */
binding->shader_visibility = vkd3d_shader_visibility_from_d3d12(s->ShaderVisibility);
binding->flags = VKD3D_SHADER_BINDING_FLAG_IMAGE;
binding->binding.binding = context->vk_binding;
binding->binding.set = context->vk_set;
context->binding_index += 1;
context->vk_binding += 1;
}
context->current_binding = cur_binding;
return S_OK;
hr = vkd3d_create_descriptor_set_layout(root_signature->device, 0,
desc->NumStaticSamplers, vk_binding_info, vk_set_layout);
cleanup:
vkd3d_free(vk_binding_info);
return hr;
}
static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signature,
@ -748,7 +771,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
struct vkd3d_descriptor_set_context context;
VkDescriptorSetLayoutBinding *binding_desc;
struct d3d12_root_signature_info info;
VkDescriptorSetLayout set_layouts[2];
VkDescriptorSetLayout set_layouts[3];
HRESULT hr;
memset(&context, 0, sizeof(context));
@ -799,6 +822,21 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
goto fail;
context.current_binding = binding_desc;
if (FAILED(hr = d3d12_root_signature_init_static_samplers(root_signature, desc,
&context, &root_signature->vk_sampler_descriptor_layout)))
goto fail;
if (root_signature->vk_sampler_descriptor_layout)
{
set_layouts[context.vk_set] = root_signature->vk_sampler_descriptor_layout;
root_signature->sampler_descriptor_set = context.vk_set;
context.current_binding = binding_desc;
context.packed_descriptor_index = 0;
context.vk_binding = 0;
context.vk_set += 1;
}
if (FAILED(hr = d3d12_root_signature_init_root_descriptors(root_signature, desc,
&info, &context, &root_signature->vk_root_descriptor_layout)))
goto fail;
@ -819,8 +857,6 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
goto fail;
if (FAILED(hr = d3d12_root_signature_init_root_descriptor_tables(root_signature, desc, &context)))
goto fail;
if (FAILED(hr = d3d12_root_signature_init_static_samplers(root_signature, device, desc, &context)))
goto fail;
if (context.vk_binding)
{

View File

@ -703,12 +703,14 @@ struct d3d12_root_signature
LONG refcount;
VkPipelineLayout vk_pipeline_layout;
VkDescriptorSetLayout vk_sampler_descriptor_layout;
VkDescriptorSetLayout vk_packed_descriptor_layout;
VkDescriptorSetLayout vk_root_descriptor_layout;
struct d3d12_root_parameter *parameters;
unsigned int parameter_count;
uint32_t sampler_descriptor_set;
uint32_t packed_descriptor_set;
uint32_t root_descriptor_set;
@ -908,7 +910,9 @@ struct vkd3d_pipeline_bindings
{
const struct d3d12_root_signature *root_signature;
VkDescriptorSet static_sampler_set;
VkDescriptorSet descriptor_set;
bool static_sampler_set_dirty;
bool in_use;
D3D12_GPU_DESCRIPTOR_HANDLE descriptor_tables[D3D12_MAX_ROOT_COST];