vkd3d: Separate root VA use for CBV and SRV/UAV.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
Hans-Kristian Arntzen 2020-11-16 16:20:28 +01:00 committed by Philip Rebohle
parent 5a288b7d0f
commit 52ee2edc3d
3 changed files with 75 additions and 45 deletions

View File

@ -2428,7 +2428,9 @@ static void d3d12_command_list_invalidate_root_parameters(struct d3d12_command_l
if (bindings->root_signature->descriptor_table_count)
bindings->dirty_flags |= VKD3D_PIPELINE_DIRTY_DESCRIPTOR_TABLE_OFFSETS;
bindings->root_descriptor_dirty_mask = bindings->root_signature->root_descriptor_mask;
bindings->root_descriptor_dirty_mask =
bindings->root_signature->root_descriptor_raw_va_mask |
bindings->root_signature->root_descriptor_push_mask;
bindings->root_constant_dirty_mask = bindings->root_signature->root_constant_mask;
if (invalidate_descriptor_heaps)
@ -2541,7 +2543,7 @@ static void vk_access_and_stage_flags_from_d3d12_resource_state(const struct d3d
*stages |= queue_shader_stages;
*access |= VK_ACCESS_UNIFORM_READ_BIT;
if (device->bindless_state.flags & (VKD3D_BINDLESS_CBV_AS_SSBO | VKD3D_RAW_VA_ROOT_DESCRIPTOR))
if (device->bindless_state.flags & (VKD3D_BINDLESS_CBV_AS_SSBO | VKD3D_RAW_VA_ROOT_DESCRIPTOR_CBV))
*access |= VK_ACCESS_SHADER_READ_BIT;
if (vk_queue_flags & VK_QUEUE_GRAPHICS_BIT)
@ -3337,7 +3339,7 @@ static unsigned int d3d12_command_list_fetch_root_descriptor_vas(struct d3d12_co
{
struct vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point];
const struct d3d12_root_signature *root_signature = bindings->root_signature;
uint64_t root_descriptor_mask = root_signature->root_descriptor_mask;
uint64_t root_descriptor_mask = root_signature->root_descriptor_raw_va_mask;
unsigned int va_idx = 0;
/* Ignore dirty mask. We'll always update all VAs either via push constants
@ -3349,7 +3351,6 @@ static unsigned int d3d12_command_list_fetch_root_descriptor_vas(struct d3d12_co
dst_data->root_descriptor_vas[va_idx++] = bindings->root_descriptors[root_parameter_index].info.va;
}
bindings->root_descriptor_dirty_mask = 0;
return va_idx;
}
@ -3367,8 +3368,7 @@ static void d3d12_command_list_fetch_inline_uniform_block_data(struct d3d12_comm
uint64_t descriptor_table_mask;
uint32_t first_table_offset;
if (list->device->bindless_state.flags & VKD3D_RAW_VA_ROOT_DESCRIPTOR)
d3d12_command_list_fetch_root_descriptor_vas(list, bind_point, dst_data);
/* Root descriptors are already filled in dst_data. */
while (root_constant_mask)
{
@ -3409,26 +3409,37 @@ static void d3d12_command_list_update_root_descriptors(struct d3d12_command_list
const struct d3d12_root_parameter *root_parameter;
VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
union root_parameter_data root_parameter_data;
unsigned int root_parameter_index, va_count;
unsigned int descriptor_write_count = 0;
unsigned int root_parameter_index;
unsigned int va_count = 0;
uint64_t dirty_push_mask;
if (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_ROOT_DESCRIPTOR_SET)
{
/* Ensure that we populate all descriptors if push descriptors cannot be used */
bindings->root_descriptor_dirty_mask |= bindings->root_descriptor_active_mask & root_signature->root_descriptor_mask;
bindings->root_descriptor_dirty_mask |=
bindings->root_descriptor_active_mask &
(root_signature->root_descriptor_raw_va_mask | root_signature->root_descriptor_push_mask);
descriptor_set = d3d12_command_allocator_allocate_descriptor_set(
list->allocator, root_signature->vk_root_descriptor_layout, VKD3D_DESCRIPTOR_POOL_TYPE_STATIC);
}
if (!(list->device->bindless_state.flags & VKD3D_RAW_VA_ROOT_DESCRIPTOR))
if (bindings->root_descriptor_dirty_mask)
{
/* TODO bind null descriptors for inactive root descriptors */
bindings->root_descriptor_dirty_mask &= bindings->root_descriptor_active_mask;
/* If any raw VA descriptor is dirty, we need to update all of them. */
if (root_signature->root_descriptor_raw_va_mask & bindings->root_descriptor_dirty_mask)
va_count = d3d12_command_list_fetch_root_descriptor_vas(list, bind_point, &root_parameter_data);
while (bindings->root_descriptor_dirty_mask)
/* TODO bind null descriptors for inactive root descriptors. */
dirty_push_mask =
bindings->root_descriptor_dirty_mask &
root_signature->root_descriptor_push_mask &
bindings->root_descriptor_active_mask;
while (dirty_push_mask)
{
root_parameter_index = vkd3d_bitmask_iter64(&bindings->root_descriptor_dirty_mask);
root_parameter_index = vkd3d_bitmask_iter64(&dirty_push_mask);
root_parameter = root_signature_get_root_descriptor(root_signature, root_parameter_index);
if (!vk_write_descriptor_set_from_root_descriptor(list,
@ -3438,6 +3449,8 @@ static void d3d12_command_list_update_root_descriptors(struct d3d12_command_list
descriptor_write_count += 1;
}
bindings->root_descriptor_dirty_mask = 0;
}
if (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_INLINE_UNIFORM_BLOCK)
@ -3449,10 +3462,8 @@ static void d3d12_command_list_update_root_descriptors(struct d3d12_command_list
descriptor_write_count += 1;
}
else if (bindings->root_descriptor_dirty_mask)
else if (va_count)
{
va_count = d3d12_command_list_fetch_root_descriptor_vas(list, bind_point, &root_parameter_data);
VK_CALL(vkCmdPushConstants(list->vk_command_buffer,
root_signature->vk_pipeline_layout, VK_SHADER_STAGE_ALL,
0, va_count * sizeof(*root_parameter_data.root_descriptor_vas),
@ -5367,7 +5378,7 @@ static void d3d12_command_list_set_root_descriptor(struct d3d12_command_list *li
struct vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point];
struct vkd3d_root_descriptor_info *descriptor = &bindings->root_descriptors[index];
if (list->device->bindless_state.flags & VKD3D_RAW_VA_ROOT_DESCRIPTOR)
if (bindings->root_signature->root_descriptor_raw_va_mask & (1ull << index))
d3d12_command_list_set_root_descriptor_va(list, descriptor, gpu_address);
else
d3d12_command_list_set_push_descriptor_info(list, bind_point, index, gpu_address);

View File

@ -403,9 +403,16 @@ static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_i
break;
case D3D12_ROOT_PARAMETER_TYPE_CBV:
if (!(device->bindless_state.flags & VKD3D_RAW_VA_ROOT_DESCRIPTOR_CBV))
info->push_descriptor_count += 1;
info->binding_count += 1;
info->cost += 2;
break;
case D3D12_ROOT_PARAMETER_TYPE_SRV:
case D3D12_ROOT_PARAMETER_TYPE_UAV:
if (!(device->bindless_state.flags & VKD3D_RAW_VA_ROOT_DESCRIPTOR))
if (!(device->bindless_state.flags & VKD3D_RAW_VA_ROOT_DESCRIPTOR_SRV_UAV))
info->push_descriptor_count += 1;
info->binding_count += 1;
@ -427,6 +434,17 @@ static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_i
return S_OK;
}
static bool d3d12_root_signature_parameter_is_raw_va(struct d3d12_root_signature *root_signature,
D3D12_ROOT_PARAMETER_TYPE type)
{
if (type == D3D12_ROOT_PARAMETER_TYPE_CBV)
return !!(root_signature->device->bindless_state.flags & VKD3D_RAW_VA_ROOT_DESCRIPTOR_CBV);
else if (type == D3D12_ROOT_PARAMETER_TYPE_SRV || type == D3D12_ROOT_PARAMETER_TYPE_UAV)
return !!(root_signature->device->bindless_state.flags & VKD3D_RAW_VA_ROOT_DESCRIPTOR_SRV_UAV);
else
return false;
}
static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signature *root_signature,
const D3D12_ROOT_SIGNATURE_DESC *desc, const struct d3d12_root_signature_info *info,
struct VkPushConstantRange *push_constant_range)
@ -438,17 +456,11 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat
push_constant_range->size = 0;
/* Put root descriptor VAs at the start to avoid alignment issues */
if (root_signature->device->bindless_state.flags & VKD3D_RAW_VA_ROOT_DESCRIPTOR)
for (i = 0; i < desc->NumParameters; ++i)
{
for (i = 0; i < desc->NumParameters; ++i)
{
const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i];
if (p->ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV ||
p->ParameterType == D3D12_ROOT_PARAMETER_TYPE_SRV ||
p->ParameterType == D3D12_ROOT_PARAMETER_TYPE_UAV)
push_constant_range->size += sizeof(VkDeviceSize);
}
const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i];
if (d3d12_root_signature_parameter_is_raw_va(root_signature, p->ParameterType))
push_constant_range->size += sizeof(VkDeviceSize);
}
/* Append actual root constants */
@ -639,27 +651,29 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign
struct d3d12_root_parameter *param;
unsigned int i, j;
HRESULT hr = S_OK;
bool raw_va;
raw_va = !!(root_signature->device->bindless_state.flags & VKD3D_RAW_VA_ROOT_DESCRIPTOR);
if (info->push_descriptor_count || (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_INLINE_UNIFORM_BLOCK))
{
if (!(vk_binding_info = vkd3d_malloc(sizeof(*vk_binding_info) * (info->push_descriptor_count + 1))))
return E_OUTOFMEMORY;
}
else if (!raw_va)
else if (!(root_signature->device->bindless_state.flags &
(VKD3D_RAW_VA_ROOT_DESCRIPTOR_CBV | VKD3D_RAW_VA_ROOT_DESCRIPTOR_SRV_UAV)))
{
return S_OK;
}
for (i = 0, j = 0; i < desc->NumParameters; ++i)
{
const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i];
bool raw_va;
if (p->ParameterType != D3D12_ROOT_PARAMETER_TYPE_CBV
&& p->ParameterType != D3D12_ROOT_PARAMETER_TYPE_SRV
&& p->ParameterType != D3D12_ROOT_PARAMETER_TYPE_UAV)
continue;
root_signature->root_descriptor_mask |= 1ull << i;
raw_va = d3d12_root_signature_parameter_is_raw_va(root_signature, p->ParameterType);
if (!raw_va)
{
@ -669,7 +683,10 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign
vk_binding->descriptorCount = 1;
vk_binding->stageFlags = stage_flags_from_visibility(p->ShaderVisibility);
vk_binding->pImmutableSamplers = NULL;
root_signature->root_descriptor_push_mask |= 1ull << i;
}
else
root_signature->root_descriptor_raw_va_mask |= 1ull << i;
binding = &root_signature->bindings[context->binding_index];
binding->type = vkd3d_descriptor_type_from_d3d12_root_parameter_type(p->ParameterType);
@ -3546,7 +3563,7 @@ static uint32_t vkd3d_bindless_state_get_bindless_flags(struct d3d12_device *dev
flags |= VKD3D_RAW_VA_UAV_COUNTER;
if (device_info->buffer_device_address_features.bufferDeviceAddress)
flags |= VKD3D_RAW_VA_ROOT_DESCRIPTOR;
flags |= VKD3D_RAW_VA_ROOT_DESCRIPTOR_CBV | VKD3D_RAW_VA_ROOT_DESCRIPTOR_SRV_UAV;
return flags;
}

View File

@ -835,7 +835,8 @@ struct d3d12_root_signature
uint64_t descriptor_table_mask;
uint64_t root_constant_mask;
uint64_t root_descriptor_mask;
uint64_t root_descriptor_raw_va_mask;
uint64_t root_descriptor_push_mask;
D3D12_ROOT_SIGNATURE_FLAGS d3d12_flags;
unsigned int flags; /* vkd3d_root_signature_flag */
@ -1563,16 +1564,17 @@ void vkd3d_destroy_null_resources(struct vkd3d_null_resources *null_resources,
/* 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),
VKD3D_RAW_VA_UAV_COUNTER = (1u << 4),
VKD3D_BINDLESS_CBV_AS_SSBO = (1u << 5),
VKD3D_BINDLESS_RAW_SSBO = (1u << 6),
VKD3D_SSBO_OFFSET_BUFFER = (1u << 7),
VKD3D_TYPED_OFFSET_BUFFER = (1u << 8),
VKD3D_RAW_VA_ROOT_DESCRIPTOR = (1u << 9),
VKD3D_BINDLESS_SAMPLER = (1u << 0),
VKD3D_BINDLESS_CBV = (1u << 1),
VKD3D_BINDLESS_SRV = (1u << 2),
VKD3D_BINDLESS_UAV = (1u << 3),
VKD3D_RAW_VA_UAV_COUNTER = (1u << 4),
VKD3D_BINDLESS_CBV_AS_SSBO = (1u << 5),
VKD3D_BINDLESS_RAW_SSBO = (1u << 6),
VKD3D_SSBO_OFFSET_BUFFER = (1u << 7),
VKD3D_TYPED_OFFSET_BUFFER = (1u << 8),
VKD3D_RAW_VA_ROOT_DESCRIPTOR_CBV = (1u << 9),
VKD3D_RAW_VA_ROOT_DESCRIPTOR_SRV_UAV = (1u << 10),
};
#define VKD3D_BINDLESS_SET_MAX_EXTRA_BINDINGS 8