[PATCH vkd3d 4/4] vkd3d-shader/spirv: Support UAV counter descriptor arrays.
Conor McCarthy
cmccarthy at codeweavers.com
Tue Nov 9 22:42:19 CST 2021
Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
include/vkd3d_shader.h | 4 +-
libs/vkd3d-shader/spirv.c | 83 ++++++++++++++++++---------------------
2 files changed, 39 insertions(+), 48 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 791ac037..1eae0bbe 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -537,9 +537,7 @@ struct vkd3d_shader_descriptor_offset_info
/**
* Pointer to an array of offsets into the descriptor arrays referenced by
* the 'uav_counters' array in struct vkd3d_shader_interface_info. This
- * works the same way as \ref binding_offsets above. UAV counter arrays are
- * not supported in this version of vkd3d-shader, and therefore this field
- * must either be NULL or specify 0 offsets.
+ * works the same way as \ref binding_offsets above.
*/
const struct vkd3d_shader_descriptor_offset *uav_counter_offsets;
};
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 9d21cb46..68eb16ec 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -1990,6 +1990,7 @@ struct vkd3d_symbol_resource_data
unsigned int structure_stride;
bool raw;
uint32_t uav_counter_id;
+ struct vkd3d_descriptor_array_symbol uav_counter_array;
};
struct vkd3d_symbol_sampler_data
@@ -2410,8 +2411,6 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
if ((offset_info = vkd3d_find_struct(shader_interface->next, DESCRIPTOR_OFFSET_INFO)))
{
compiler->offset_info = *offset_info;
- if (offset_info->uav_counter_offsets)
- WARN("Ignoring UAV counter offsets %p.\n", offset_info->uav_counter_offsets);
}
}
@@ -2602,6 +2601,7 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
if (is_uav_counter)
{
assert(descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV);
+ binding_offsets = compiler->offset_info.uav_counter_offsets;
for (i = 0; i < shader_interface->uav_counter_count; ++i)
{
const struct vkd3d_shader_uav_counter_binding *current = &shader_interface->uav_counters[i];
@@ -2609,7 +2609,8 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, current->shader_visibility))
continue;
- if (current->register_space != range->space || current->register_index != range->first)
+ if (current->register_space != range->space || current->register_index > range->first
+ || current->binding.count <= register_last - current->register_index)
continue;
if (current->offset)
@@ -2620,16 +2621,9 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
range->first, range->space, current->offset);
}
- if (current->binding.count != 1)
- {
- FIXME("Descriptor arrays are not supported.\n");
- vkd3d_dxbc_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_DESCRIPTOR_BINDING,
- "Descriptor binding for UAV counter %u, space %u has unsupported ‘count’ %u.",
- range->first, range->space, current->binding.count);
- }
-
- binding_address->binding_base_idx = current->register_index;
- binding_address->push_constant_index = ~0u;
+ binding_address->binding_base_idx = current->register_index
+ - (binding_offsets ? binding_offsets[i].static_offset : 0);
+ binding_address->push_constant_index = binding_offsets ? binding_offsets[i].dynamic_offset_index : ~0u;
return current->binding;
}
if (shader_interface->uav_counter_count)
@@ -2692,18 +2686,6 @@ static void vkd3d_dxbc_compiler_emit_descriptor_binding(struct vkd3d_dxbc_compil
vkd3d_spirv_build_op_decorate1(builder, variable_id, SpvDecorationBinding, binding->binding);
}
-static void vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(struct vkd3d_dxbc_compiler *compiler,
- uint32_t variable_id, const struct vkd3d_shader_register *reg, const struct vkd3d_shader_register_range *range,
- enum vkd3d_shader_resource_type resource_type, bool is_uav_counter)
-{
- struct vkd3d_shader_descriptor_binding binding;
- struct vkd3d_descriptor_binding_address binding_address; /* Values not used. */
-
- binding = vkd3d_dxbc_compiler_get_descriptor_binding(compiler, reg, range, resource_type, is_uav_counter,
- &binding_address);
- vkd3d_dxbc_compiler_emit_descriptor_binding(compiler, variable_id, &binding);
-}
-
static void vkd3d_dxbc_compiler_decorate_nonuniform(struct vkd3d_dxbc_compiler *compiler,
uint32_t expression_id)
{
@@ -2938,6 +2920,7 @@ static bool vkd3d_dxbc_compiler_get_register_name(char *buffer, unsigned int buf
return true;
}
+/* TODO: UAV counters: vkd3d_spirv_build_op_name(builder, counter_var_id, "u%u_counter", reg->idx[0].offset); */
static void vkd3d_dxbc_compiler_emit_register_debug_name(struct vkd3d_spirv_builder *builder,
uint32_t id, const struct vkd3d_shader_register *reg)
{
@@ -5596,7 +5579,7 @@ static void vkd3d_dxbc_compiler_emit_push_constant_buffers(struct vkd3d_dxbc_com
static uint32_t vkd3d_dxbc_compiler_build_descriptor_variable(struct vkd3d_dxbc_compiler *compiler,
SpvStorageClass storage_class, uint32_t type_id, const struct vkd3d_shader_register *reg,
const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type,
- struct vkd3d_descriptor_array_symbol *array_symbol)
+ bool is_uav_counter, struct vkd3d_descriptor_array_symbol *array_symbol)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
struct vkd3d_descriptor_binding_address binding_address;
@@ -5606,7 +5589,7 @@ static uint32_t vkd3d_dxbc_compiler_build_descriptor_variable(struct vkd3d_dxbc_
struct rb_entry *entry;
binding = vkd3d_dxbc_compiler_get_descriptor_binding(compiler, reg, range,
- resource_type, false, &binding_address);
+ resource_type, is_uav_counter, &binding_address);
array_symbol->binding_base_idx = binding_address.binding_base_idx;
if (binding.count == 1 && range->first == binding_address.binding_base_idx && range->last != ~0u)
@@ -5696,7 +5679,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi
vkd3d_spirv_build_op_name(builder, struct_id, "cb%u_struct", cb->size);
var_id = vkd3d_dxbc_compiler_build_descriptor_variable(compiler, storage_class, struct_id,
- reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, &array_symbol);
+ reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, false, &array_symbol);
vkd3d_symbol_make_register(®_symbol, reg);
vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class,
@@ -5758,7 +5741,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_sampler(struct vkd3d_dxbc_compiler *com
type_id = vkd3d_spirv_get_op_type_sampler(builder);
var_id = vkd3d_dxbc_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg,
- &sampler->range, VKD3D_SHADER_RESOURCE_NONE, &array_symbol);
+ &sampler->range, VKD3D_SHADER_RESOURCE_NONE, false, &array_symbol);
vkd3d_symbol_make_register(®_symbol, reg);
vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class,
@@ -5929,6 +5912,8 @@ static void vkd3d_dxbc_compiler_emit_combined_sampler_declarations(struct vkd3d_
symbol.info.resource.structure_stride = structure_stride;
symbol.info.resource.raw = raw;
symbol.info.resource.uav_counter_id = 0;
+ symbol.info.resource.uav_counter_array.symbol = NULL;
+ symbol.info.resource.uav_counter_array.binding_base_idx = 0;
vkd3d_dxbc_compiler_put_symbol(compiler, &symbol);
}
}
@@ -5937,12 +5922,12 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type,
enum vkd3d_data_type resource_data_type, unsigned int structure_stride, bool raw)
{
- uint32_t counter_type_id, type_id, ptr_type_id, var_id, counter_var_id = 0;
+ struct vkd3d_descriptor_array_symbol array_symbol, counter_array_symbol = {NULL, 0};
+ uint32_t counter_type_id, type_id, var_id, counter_var_id = 0;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
SpvStorageClass storage_class = SpvStorageClassUniformConstant;
const struct vkd3d_shader_register *reg = &resource->reg.reg;
const struct vkd3d_spirv_resource_type *resource_type_info;
- struct vkd3d_descriptor_array_symbol array_symbol;
enum vkd3d_shader_component_type sampled_type;
struct vkd3d_symbol resource_symbol;
bool is_uav;
@@ -5987,7 +5972,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
}
var_id = vkd3d_dxbc_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg,
- &resource->range, resource_type, &array_symbol);
+ &resource->range, resource_type, false, &array_symbol);
if (is_uav)
{
@@ -6008,7 +5993,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
{
vkd3d_spirv_enable_capability(builder, SpvCapabilityAtomicStorage);
storage_class = SpvStorageClassAtomicCounter;
- ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, counter_type_id);
+ type_id = counter_type_id;
}
else if (compiler->ssbo_uavs)
{
@@ -6023,20 +6008,11 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
vkd3d_spirv_build_op_member_decorate1(builder, struct_id, 0, SpvDecorationOffset, 0);
storage_class = SpvStorageClassUniform;
- ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, struct_id);
- }
- else
- {
- ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id);
+ type_id = struct_id;
}
- counter_var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream,
- ptr_type_id, storage_class, 0);
-
- vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(compiler,
- counter_var_id, reg, &resource->range, resource_type, true);
-
- vkd3d_spirv_build_op_name(builder, counter_var_id, "u%u_counter", reg->idx[0].offset);
+ counter_var_id = vkd3d_dxbc_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg,
+ &resource->range, resource_type, true, &counter_array_symbol);
}
}
@@ -6050,6 +6026,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
resource_symbol.info.resource.structure_stride = structure_stride;
resource_symbol.info.resource.raw = raw;
resource_symbol.info.resource.uav_counter_id = counter_var_id;
+ resource_symbol.info.resource.uav_counter_array = counter_array_symbol;
vkd3d_dxbc_compiler_put_symbol(compiler, &resource_symbol);
}
@@ -8868,6 +8845,22 @@ static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_c
}
else
{
+ if (resource_symbol->info.resource.uav_counter_array.symbol)
+ {
+ const struct vkd3d_symbol_descriptor_array_data *array_data;
+ uint32_t index_id;
+
+ index_id = vkd3d_dxbc_compiler_get_descriptor_index(compiler, &src->reg,
+ &resource_symbol->info.resource.uav_counter_array,
+ resource_symbol->info.resource.resource_type_info->resource_type);
+
+ array_data = &resource_symbol->info.resource.uav_counter_array.symbol->info.descriptor_array;
+ ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, array_data->storage_class,
+ array_data->contained_type_id);
+
+ counter_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, counter_id, &index_id, 1);
+ }
+
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassImage, type_id);
coordinate_id = sample_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0);
pointer_id = vkd3d_spirv_build_op_image_texel_pointer(builder,
--
2.32.0
More information about the wine-devel
mailing list