vkd3d: Store both byte range and element range in offset buffer.

The first range will store the byte offset, the second one will
be the typed buffer range. Typed descriptors should write both.

Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Co-authored-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
Philip Rebohle 2020-12-10 13:27:29 +01:00 committed by Hans-Kristian Arntzen
parent dbbde3c6f1
commit 6bddcb4352
5 changed files with 59 additions and 27 deletions

View File

@ -545,6 +545,18 @@ int vkd3d_shader_compile_dxil(const struct vkd3d_shader_code *dxbc,
}
}
{
const struct dxil_spv_option_bindless_offset_buffer_layout helper =
{ { DXIL_SPV_OPTION_BINDLESS_OFFSET_BUFFER_LAYOUT },
0, 1, 2 };
if (dxil_spv_converter_add_option(converter, &helper.base) != DXIL_SPV_SUCCESS)
{
ERR("dxil-spirv does not support BINDLESS_OFFSET_BUFFER_LAYOUT.\n");
ret = VKD3D_ERROR_NOT_IMPLEMENTED;
goto end;
}
}
{
char buffer[16 + 5 + 1];
const struct dxil_spv_option_shader_source_file helper =

View File

@ -5685,13 +5685,20 @@ static void vkd3d_dxbc_compiler_emit_offset_buffer(struct vkd3d_dxbc_compiler *c
const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t array_id, struct_id, pointer_id, var_id;
uint32_t member_ids[2];
if (!(shader_interface->flags & (VKD3D_SHADER_INTERFACE_SSBO_OFFSET_BUFFER | VKD3D_SHADER_INTERFACE_TYPED_OFFSET_BUFFER)))
return;
array_id = vkd3d_spirv_build_op_type_runtime_array(builder,
vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_UINT, 2));
vkd3d_spirv_build_op_decorate1(builder, array_id, SpvDecorationArrayStride, 8);
member_ids[0] = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_UINT, 2);
member_ids[1] = member_ids[0];
struct_id = vkd3d_spirv_build_op_type_struct(builder, member_ids, ARRAY_SIZE(member_ids));
vkd3d_spirv_build_op_member_decorate1(builder, struct_id, 0, SpvDecorationOffset, 0);
vkd3d_spirv_build_op_member_decorate1(builder, struct_id, 1, SpvDecorationOffset, 8);
array_id = vkd3d_spirv_build_op_type_runtime_array(builder, struct_id);
vkd3d_spirv_build_op_decorate1(builder, array_id, SpvDecorationArrayStride, 16);
struct_id = vkd3d_spirv_build_op_type_struct(builder, &array_id, 1);
vkd3d_spirv_build_op_decorate(builder, struct_id, SpvDecorationBufferBlock, NULL, 0);
@ -8819,17 +8826,19 @@ static uint32_t vkd3d_dxbc_compiler_emit_raw_structured_addressing(
}
static uint32_t vkd3d_dxbc_compiler_get_buffer_bounds(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg, const struct vkd3d_shader_resource_binding *binding)
const struct vkd3d_shader_register *reg, bool texel_buffer,
const struct vkd3d_shader_resource_binding *binding)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t bounds_id, vec2_ptr_id, vec2_type_id;
uint32_t indices[2];
uint32_t indices[3];
vec2_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_UINT, 2);
vec2_ptr_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, vec2_type_id);
indices[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0);
indices[1] = vkd3d_dxbc_compiler_get_resource_index(compiler, reg, binding);
indices[2] = vkd3d_dxbc_compiler_get_constant_uint(compiler, texel_buffer ? 1 : 0);
/* returns (offset, length) in bytes, or (elem offset, count) for typed buffers. */
bounds_id = vkd3d_spirv_build_op_load(builder, vec2_type_id,
@ -8866,7 +8875,7 @@ static uint32_t vkd3d_dxbc_compiler_adjust_ssbo_offset(struct vkd3d_dxbc_compile
bool_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_BOOL, 1);
uint_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_UINT, 1);
bounds_id = vkd3d_dxbc_compiler_get_buffer_bounds(compiler, reg, symbol->info.resource.resource_binding);
bounds_id = vkd3d_dxbc_compiler_get_buffer_bounds(compiler, reg, false, symbol->info.resource.resource_binding);
shift_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, 2);
offset_id = vkd3d_spirv_build_op_shift_right_logical(builder, uint_type_id,
@ -8902,7 +8911,7 @@ static uint32_t vkd3d_dxbc_compiler_adjust_typed_buffer_offset(struct vkd3d_dxbc
return coordinate_id;
symbol = vkd3d_dxbc_compiler_find_resource(compiler, reg);
bounds_id = vkd3d_dxbc_compiler_get_buffer_bounds(compiler, reg, symbol->info.resource.resource_binding);
bounds_id = vkd3d_dxbc_compiler_get_buffer_bounds(compiler, reg, true, symbol->info.resource.resource_binding);
bool_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_BOOL, 1);
uint_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_UINT, 1);
@ -9559,7 +9568,7 @@ static void vkd3d_dxbc_compiler_emit_bufinfo(struct vkd3d_dxbc_compiler *compile
{
const struct vkd3d_symbol *symbol = vkd3d_dxbc_compiler_find_resource(compiler, &src->reg);
bounds_id = vkd3d_dxbc_compiler_get_buffer_bounds(compiler, &src->reg,
symbol->info.resource.resource_binding);
false, symbol->info.resource.resource_binding);
val_id = vkd3d_spirv_build_op_shift_right_logical(builder, type_id,
vkd3d_spirv_build_op_composite_extract1(builder, type_id, bounds_id, 1),
@ -9577,7 +9586,7 @@ static void vkd3d_dxbc_compiler_emit_bufinfo(struct vkd3d_dxbc_compiler *compile
{
const struct vkd3d_symbol *symbol = vkd3d_dxbc_compiler_find_resource(compiler, &src->reg);
bounds_id = vkd3d_dxbc_compiler_get_buffer_bounds(compiler, &src->reg,
symbol->info.resource.resource_binding);
true, symbol->info.resource.resource_binding);
val_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, bounds_id, 1);
}
else

View File

@ -6566,8 +6566,8 @@ static void d3d12_command_list_clear_uav(struct d3d12_command_list *list, const
{
if (list->device->bindless_state.flags & VKD3D_TYPED_OFFSET_BUFFER)
{
extra_offset = ranges[desc->heap_offset].offset;
full_rect.right = ranges[desc->heap_offset].length;
extra_offset = ranges[desc->heap_offset].element_offset;
full_rect.right = ranges[desc->heap_offset].element_count;
}
else
{
@ -6579,8 +6579,8 @@ static void d3d12_command_list_clear_uav(struct d3d12_command_list *list, const
}
else if (list->device->bindless_state.flags & VKD3D_SSBO_OFFSET_BUFFER)
{
extra_offset = ranges[desc->heap_offset].offset / sizeof(uint32_t);
full_rect.right = ranges[desc->heap_offset].length / sizeof(uint32_t);
extra_offset = ranges[desc->heap_offset].byte_offset / sizeof(uint32_t);
full_rect.right = ranges[desc->heap_offset].byte_count / sizeof(uint32_t);
}
else
full_rect.right = args->u.buffer.range / sizeof(uint32_t);

View File

@ -4112,8 +4112,8 @@ static void vkd3d_buffer_view_get_bound_range_ssbo(struct d3d12_desc *descriptor
vk_buffer->offset = resource->heap_offset + aligned_begin;
vk_buffer->range = aligned_end - aligned_begin;
ssbo_range.offset = offset - aligned_begin;
ssbo_range.length = range;
ssbo_range.byte_offset = offset - aligned_begin;
ssbo_range.byte_count = range;
}
else
{
@ -4121,10 +4121,13 @@ static void vkd3d_buffer_view_get_bound_range_ssbo(struct d3d12_desc *descriptor
vk_buffer->offset = 0;
vk_buffer->range = VK_WHOLE_SIZE;
ssbo_range.offset = 0;
ssbo_range.length = 0;
ssbo_range.byte_offset = 0;
ssbo_range.byte_count = 0;
}
ssbo_range.element_offset = 0;
ssbo_range.element_count = 0;
if (device->bindless_state.flags & VKD3D_SSBO_OFFSET_BUFFER)
{
struct vkd3d_bound_buffer_range *buffer_ranges = descriptor->heap->buffer_ranges.host_ptr;
@ -4138,12 +4141,13 @@ static bool vkd3d_buffer_view_get_aligned_view(struct d3d12_desc *descriptor,
VkDeviceSize first_element, VkDeviceSize num_elements,
VkDeviceSize structured_stride, struct vkd3d_view **view)
{
struct vkd3d_bound_buffer_range typed_range = { 0, 0 };
struct vkd3d_bound_buffer_range typed_range = { 0, 0, 0, 0 };
const struct vkd3d_format *vkd3d_format;
VkDeviceSize max_resource_elements;
VkDeviceSize max_element_headroom;
VkDeviceSize element_align;
VkDeviceSize max_elements;
VkDeviceSize element_size;
VkDeviceSize begin_range;
VkDeviceSize end_range;
@ -4157,7 +4161,8 @@ static bool vkd3d_buffer_view_get_aligned_view(struct d3d12_desc *descriptor,
if (format)
{
vkd3d_format = vkd3d_get_format(device, format, false);
max_resource_elements = resource->desc.Width / vkd3d_format->byte_count;
element_size = vkd3d_format->byte_count;
max_resource_elements = resource->desc.Width / element_size;
}
else
{
@ -4165,6 +4170,7 @@ static bool vkd3d_buffer_view_get_aligned_view(struct d3d12_desc *descriptor,
* 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). */
element_size = sizeof(uint32_t);
first_element = (first_element * structured_stride) / sizeof(uint32_t);
num_elements = (num_elements * structured_stride) / sizeof(uint32_t);
structured_stride = sizeof(uint32_t);
@ -4178,13 +4184,13 @@ static bool vkd3d_buffer_view_get_aligned_view(struct d3d12_desc *descriptor,
{
FIXME("Application is attempting to use more elements in a typed buffer (%llu) than supported by device (%llu).\n",
(unsigned long long)num_elements, (unsigned long long)max_elements);
typed_range.offset = 0;
typed_range.length = num_elements;
typed_range.element_offset = 0;
typed_range.element_count = num_elements;
}
else if (num_elements >= max_resource_elements)
{
typed_range.offset = 0;
typed_range.length = num_elements;
typed_range.element_offset = 0;
typed_range.element_count = num_elements;
}
else
{
@ -4198,12 +4204,15 @@ static bool vkd3d_buffer_view_get_aligned_view(struct d3d12_desc *descriptor,
end_range = (first_element + num_elements + element_align - 1) & ~(element_align - 1);
end_range = min(end_range, max_resource_elements);
typed_range.offset = first_element - begin_range;
typed_range.length = num_elements;
typed_range.element_offset = first_element - begin_range;
typed_range.element_count = num_elements;
first_element = begin_range;
num_elements = end_range - begin_range;
}
typed_range.byte_offset = typed_range.element_offset * element_size;
typed_range.byte_count = typed_range.element_count * element_size;
}
if (!vkd3d_create_buffer_view_for_resource(device, resource, format,

View File

@ -717,8 +717,10 @@ void d3d12_rtv_desc_create_dsv(struct d3d12_rtv_desc *dsv_desc, struct d3d12_dev
struct vkd3d_bound_buffer_range
{
uint32_t offset; /* offset to first byte for SSBO, or offset in elements for typed views. */
uint32_t length; /* bound size in bytes, or size in elements for typed views. */
uint32_t byte_offset;
uint32_t byte_count;
uint32_t element_offset;
uint32_t element_count;
};
struct vkd3d_host_visible_buffer_range