vkd3d: Support offset buffers for raw/structured texel buffers.

Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Co-authored-by: Hans-Kristian Arntzen <post@arntzen-software.no>
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
Philip Rebohle 2020-11-17 16:57:03 +01:00 committed by Hans-Kristian Arntzen
parent 3e15a3f06a
commit bab9b0af92
4 changed files with 50 additions and 27 deletions

View File

@ -183,8 +183,7 @@ static dxil_spv_bool dxil_srv_remap(void *userdata, const dxil_spv_d3d_binding *
else
{
vk_binding->buffer_binding.descriptor_type = DXIL_SPV_VULKAN_DESCRIPTOR_TYPE_TEXEL_BUFFER;
if (d3d_binding->kind == DXIL_SPV_RESOURCE_KIND_TYPED_BUFFER &&
(shader_interface_info->flags & VKD3D_SHADER_INTERFACE_TYPED_OFFSET_BUFFER))
if (shader_interface_info->flags & VKD3D_SHADER_INTERFACE_TYPED_OFFSET_BUFFER)
{
vk_binding->offset_binding.set = shader_interface_info->offset_buffer_binding->set;
vk_binding->offset_binding.binding = shader_interface_info->offset_buffer_binding->binding;
@ -299,6 +298,11 @@ static dxil_spv_bool dxil_uav_remap(void *userdata, const dxil_spv_uav_d3d_bindi
/* By default, we use TEXEL_BUFFER unless dxil_remap remaps it to BDA.
* We won't trigger SSBO path when using BDA. */
vk_binding->buffer_binding.descriptor_type = DXIL_SPV_VULKAN_DESCRIPTOR_TYPE_TEXEL_BUFFER;
if (shader_interface_info->flags & VKD3D_SHADER_INTERFACE_TYPED_OFFSET_BUFFER)
{
vk_binding->offset_binding.set = shader_interface_info->offset_buffer_binding->set;
vk_binding->offset_binding.binding = shader_interface_info->offset_buffer_binding->binding;
}
}
}
else
@ -310,8 +314,7 @@ static dxil_spv_bool dxil_uav_remap(void *userdata, const dxil_spv_uav_d3d_bindi
return DXIL_SPV_FALSE;
}
if (d3d_binding->d3d_binding.kind == DXIL_SPV_RESOURCE_KIND_TYPED_BUFFER &&
(shader_interface_info->flags & VKD3D_SHADER_INTERFACE_TYPED_OFFSET_BUFFER))
if (shader_interface_info->flags & VKD3D_SHADER_INTERFACE_TYPED_OFFSET_BUFFER)
{
vk_binding->offset_binding.set = shader_interface_info->offset_buffer_binding->set;
vk_binding->offset_binding.binding = shader_interface_info->offset_buffer_binding->binding;

View File

@ -8381,7 +8381,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_texel_offset(struct vkd3d_dxbc_compiler
}
static uint32_t vkd3d_dxbc_compiler_adjust_typed_buffer_offset(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg, uint32_t coordinate_id);
const struct vkd3d_shader_register *reg, uint32_t coordinate_id, bool raw_u32);
static void vkd3d_dxbc_compiler_emit_ld(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
@ -8412,7 +8412,7 @@ static void vkd3d_dxbc_compiler_emit_ld(struct vkd3d_dxbc_compiler *compiler,
coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], coordinate_mask);
if (image.resource_type_info->dim == SpvDimBuffer)
coordinate_id = vkd3d_dxbc_compiler_adjust_typed_buffer_offset(compiler, &src[1].reg, coordinate_id);
coordinate_id = vkd3d_dxbc_compiler_adjust_typed_buffer_offset(compiler, &src[1].reg, coordinate_id, false);
if (image.resource_type_info->resource_type != VKD3D_SHADER_RESOURCE_BUFFER && !multisample)
{
@ -8837,7 +8837,7 @@ static uint32_t vkd3d_dxbc_compiler_adjust_ssbo_offset(struct vkd3d_dxbc_compile
}
static uint32_t vkd3d_dxbc_compiler_adjust_typed_buffer_offset(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg, uint32_t coordinate_id)
const struct vkd3d_shader_register *reg, uint32_t coordinate_id, bool raw_u32)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t bounds_id, offset_id, length_id;
@ -8864,7 +8864,7 @@ static uint32_t vkd3d_dxbc_compiler_adjust_typed_buffer_offset(struct vkd3d_dxbc
* expect to be out-of-bounds of the actual Vulkan resource as well. */
coordinate_id = vkd3d_spirv_build_op_select(builder, uint_type_id, cond_id,
vkd3d_spirv_build_op_iadd(builder, uint_type_id, coordinate_id, offset_id),
vkd3d_dxbc_compiler_get_constant_uint(compiler, 0xffffffffu));
vkd3d_dxbc_compiler_get_constant_uint(compiler, raw_u32 ? 0x3ffffffcu : 0xffffffffu));
return coordinate_id;
}
@ -8921,8 +8921,8 @@ static void vkd3d_dxbc_compiler_emit_ld_raw_structured_srv_uav(struct vkd3d_dxbc
access_mask = SpvMemoryAccessAlignedMask;
else if (image.ssbo)
base_coordinate_id = vkd3d_dxbc_compiler_adjust_ssbo_offset(compiler, &resource->reg, base_coordinate_id);
else if (!image.raw && !image.structure_stride)
base_coordinate_id = vkd3d_dxbc_compiler_adjust_typed_buffer_offset(compiler, &resource->reg, base_coordinate_id);
else
base_coordinate_id = vkd3d_dxbc_compiler_adjust_typed_buffer_offset(compiler, &resource->reg, base_coordinate_id, true);
texel_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE);
result_type_id = is_sparse_op ? vkd3d_spirv_get_sparse_result_type(builder, texel_type_id) : texel_type_id;
@ -9062,8 +9062,8 @@ static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_
access_mask = SpvMemoryAccessAlignedMask;
else if (image.ssbo)
base_coordinate_id = vkd3d_dxbc_compiler_adjust_ssbo_offset(compiler, &dst->reg, base_coordinate_id);
else if (!image.raw && !image.structure_stride)
base_coordinate_id = vkd3d_dxbc_compiler_adjust_typed_buffer_offset(compiler, &dst->reg, base_coordinate_id);
else
base_coordinate_id = vkd3d_dxbc_compiler_adjust_typed_buffer_offset(compiler, &dst->reg, base_coordinate_id, true);
texel = &src[instruction->src_count - 1];
assert(texel->reg.data_type == VKD3D_DATA_UINT);
@ -9188,7 +9188,7 @@ static void vkd3d_dxbc_compiler_emit_ld_uav_typed(struct vkd3d_dxbc_compiler *co
coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], coordinate_mask);
if (image.resource_type_info->dim == SpvDimBuffer)
coordinate_id = vkd3d_dxbc_compiler_adjust_typed_buffer_offset(compiler, &src[1].reg, coordinate_id);
coordinate_id = vkd3d_dxbc_compiler_adjust_typed_buffer_offset(compiler, &src[1].reg, coordinate_id, false);
val_id = vkd3d_spirv_build_op_image_read(builder, op, result_type_id,
image.image_id, coordinate_id, SpvImageOperandsMaskNone, NULL, 0);
@ -9222,7 +9222,7 @@ static void vkd3d_dxbc_compiler_emit_store_uav_typed(struct vkd3d_dxbc_compiler
coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1;
coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], coordinate_mask);
if (image.resource_type_info->dim == SpvDimBuffer)
coordinate_id = vkd3d_dxbc_compiler_adjust_typed_buffer_offset(compiler, &dst->reg, coordinate_id);
coordinate_id = vkd3d_dxbc_compiler_adjust_typed_buffer_offset(compiler, &dst->reg, coordinate_id, false);
texel_id = vkd3d_dxbc_compiler_emit_load_src_with_type(compiler, &src[1], dst->write_mask, image.sampled_type);
vkd3d_spirv_build_op_image_write(builder, image.image_id, coordinate_id, texel_id,
@ -9413,15 +9413,26 @@ static void vkd3d_dxbc_compiler_emit_atomic_instruction(struct vkd3d_dxbc_compil
type_id, structure_stride, &src[0], VKD3DSP_WRITEMASK_0,
&src[0], VKD3DSP_WRITEMASK_1);
if (resource->reg.type != VKD3DSPR_GROUPSHAREDMEM && image.ssbo && reg_info.storage_class != SpvStorageClassPhysicalStorageBuffer)
coordinate_id = vkd3d_dxbc_compiler_adjust_ssbo_offset(compiler, &resource->reg, coordinate_id);
if (resource->reg.type != VKD3DSPR_GROUPSHAREDMEM && reg_info.storage_class != SpvStorageClassPhysicalStorageBuffer)
{
if (image.ssbo)
coordinate_id = vkd3d_dxbc_compiler_adjust_ssbo_offset(compiler, &resource->reg, coordinate_id);
else
{
coordinate_id = vkd3d_dxbc_compiler_adjust_typed_buffer_offset(compiler, &resource->reg, coordinate_id,
image.raw || image.structure_stride);
}
}
}
else
{
assert(resource->reg.type != VKD3DSPR_GROUPSHAREDMEM);
coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], coordinate_mask);
if (image.resource_type_info->dim == SpvDimBuffer)
coordinate_id = vkd3d_dxbc_compiler_adjust_typed_buffer_offset(compiler, &resource->reg, coordinate_id);
{
coordinate_id = vkd3d_dxbc_compiler_adjust_typed_buffer_offset(compiler, &resource->reg, coordinate_id,
image.raw || image.structure_stride);
}
}
if (resource->reg.type == VKD3DSPR_GROUPSHAREDMEM)

View File

@ -3988,7 +3988,6 @@ static bool vkd3d_buffer_view_get_aligned_view(struct d3d12_desc *descriptor,
VkDeviceSize structured_stride, struct vkd3d_view **view)
{
struct vkd3d_bound_buffer_range typed_range = { 0, 0 };
bool is_untyped_buffer, is_typed_buffer;
const struct vkd3d_format *vkd3d_format;
VkDeviceSize max_resource_elements;
VkDeviceSize max_element_headroom;
@ -3997,19 +3996,29 @@ static bool vkd3d_buffer_view_get_aligned_view(struct d3d12_desc *descriptor,
VkDeviceSize begin_range;
VkDeviceSize end_range;
is_untyped_buffer =
(structured_stride && format == DXGI_FORMAT_UNKNOWN) ||
(vk_flags & VKD3D_VIEW_RAW_BUFFER) != 0;
is_typed_buffer = !is_untyped_buffer;
if (is_typed_buffer && (device->bindless_state.flags & VKD3D_TYPED_OFFSET_BUFFER))
if (device->bindless_state.flags & VKD3D_TYPED_OFFSET_BUFFER)
{
/* For typed buffers, we will try to remove two cases of extreme hashmap contention, i.e.
* first_element and num_elements. By quantizing these two and relying on offset buffers,
* we should achieve a bounded value for number of possible views we can create for a given resource. */
max_elements = device->device_info.properties2.properties.limits.maxTexelBufferElements;
vkd3d_format = vkd3d_get_format(device, format, false);
max_resource_elements = resource->desc.Width / vkd3d_format->byte_count;
if (format)
{
vkd3d_format = vkd3d_get_format(device, format, false);
max_resource_elements = resource->desc.Width / vkd3d_format->byte_count;
}
else
{
/* For structured buffers, we need to rescale input parameters to
* be in terms of u32 since the offset buffer must be in terms of words.
* When using typed buffers, the offset buffer is in format of u32
* (element offset, element size). */
first_element = (first_element * structured_stride) / sizeof(uint32_t);
num_elements = (num_elements * structured_stride) / sizeof(uint32_t);
structured_stride = sizeof(uint32_t);
max_resource_elements = resource->desc.Width / sizeof(uint32_t);
}
/* Requantizing the typed offset is shaky business if we overflow max_elements when doing so.
* We can always fall back to 0 offset for the difficult and rare cases. */

@ -1 +1 @@
Subproject commit 2b972e5ab27e074d806af59a350b0ec2f5d13486
Subproject commit 6310e750e648559a1eebf099c44e01fa59274413