vkd3d: Deal correctly with SM 5.1 register spaces.

Resource index is found in idx[0] in SM 5.0, but idx[1] when using SM
5.1, and register space is encoded separately. An rb_tree keeps track of
the internal resource index idx[0] and can map that to space/binding as
required when emitting SPIR-V.

For this to work, we must also make UAV counters register space aware.
In earlier implementation, UAV counter mask was assumed to correlate 1:1
with register_index, which breaks on SM 5.1.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
Hans-Kristian Arntzen 2019-11-18 15:20:12 +01:00
parent 96925f8a70
commit 93e4b6ff9b
7 changed files with 289 additions and 54 deletions

View File

@ -35,6 +35,7 @@ enum vkd3d_shader_structure_type
VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO,
VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO,
VKD3D_SHADER_STRUCTURE_TYPE_DOMAIN_SHADER_COMPILE_ARGUMENTS,
VKD3D_SHADER_STRUCTURE_TYPE_EFFECTIVE_UAV_COUNTER_BINDING_INFO,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
};
@ -138,6 +139,7 @@ struct vkd3d_shader_parameter
struct vkd3d_shader_resource_binding
{
enum vkd3d_shader_descriptor_type type;
unsigned int register_space;
unsigned int register_index;
enum vkd3d_shader_visibility shader_visibility;
unsigned int flags; /* vkd3d_shader_binding_flags */
@ -159,8 +161,10 @@ struct vkd3d_shader_combined_resource_sampler
struct vkd3d_shader_uav_counter_binding
{
unsigned int register_space;
unsigned int register_index; /* u# */
enum vkd3d_shader_visibility shader_visibility;
unsigned int counter_index;
struct vkd3d_shader_descriptor_binding binding;
unsigned int offset;
@ -168,6 +172,7 @@ struct vkd3d_shader_uav_counter_binding
struct vkd3d_shader_push_constant_buffer
{
unsigned int register_space;
unsigned int register_index;
enum vkd3d_shader_visibility shader_visibility;
@ -215,6 +220,17 @@ struct vkd3d_shader_transform_feedback_info
unsigned int buffer_stride_count;
};
/* Extends vkd3d_shader_interface_info. */
struct vkd3d_shader_effective_uav_counter_binding_info
{
enum vkd3d_shader_structure_type type;
const void *next;
unsigned int *uav_register_spaces;
unsigned int *uav_register_bindings;
unsigned int uav_counter_count;
};
enum vkd3d_shader_target
{
VKD3D_SHADER_TARGET_NONE,

View File

@ -624,6 +624,10 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins,
ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT;
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.semantic.register_space);
if (shader_is_sm_5_1(priv))
ins->declaration.semantic.register_index = ins->declaration.semantic.reg.reg.idx[1].offset;
else
ins->declaration.semantic.register_index = ins->declaration.semantic.reg.reg.idx[0].offset;
}
static void shader_sm4_read_dcl_constant_buffer(struct vkd3d_shader_instruction *ins,
@ -647,9 +651,12 @@ static void shader_sm4_read_dcl_constant_buffer(struct vkd3d_shader_instruction
return;
}
ins->declaration.cb.register_index = ins->declaration.cb.src.reg.idx[1].offset;
ins->declaration.cb.size = *tokens++;
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.cb.register_space);
}
else
ins->declaration.cb.register_index = ins->declaration.cb.src.reg.idx[0].offset;
}
static void shader_sm4_read_dcl_sampler(struct vkd3d_shader_instruction *ins,
@ -663,6 +670,10 @@ static void shader_sm4_read_dcl_sampler(struct vkd3d_shader_instruction *ins,
FIXME("Unhandled sampler mode %#x.\n", ins->flags);
shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_SAMPLER, &ins->declaration.sampler.src);
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.sampler.register_space);
if (shader_is_sm_5_1(priv))
ins->declaration.sampler.register_index = ins->declaration.sampler.src.reg.idx[1].offset;
else
ins->declaration.sampler.register_index = ins->declaration.sampler.src.reg.idx[0].offset;
}
static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins,
@ -863,6 +874,10 @@ static void shader_sm5_read_dcl_uav_raw(struct vkd3d_shader_instruction *ins,
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UAV, &ins->declaration.raw_resource.dst);
ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT;
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.raw_resource.register_space);
if (shader_is_sm_5_1(priv))
ins->declaration.raw_resource.register_index = ins->declaration.raw_resource.dst.reg.idx[1].offset;
else
ins->declaration.raw_resource.register_index = ins->declaration.raw_resource.dst.reg.idx[0].offset;
}
static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction *ins,
@ -874,9 +889,14 @@ static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction *
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UAV, &ins->declaration.structured_resource.reg);
ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT;
ins->declaration.structured_resource.byte_stride = *tokens;
tokens++;
if (ins->declaration.structured_resource.byte_stride % 4)
FIXME("Byte stride %u is not multiple of 4.\n", ins->declaration.structured_resource.byte_stride);
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.structured_resource.register_space);
if (shader_is_sm_5_1(priv))
ins->declaration.structured_resource.register_index = ins->declaration.structured_resource.reg.reg.idx[1].offset;
else
ins->declaration.structured_resource.register_index = ins->declaration.structured_resource.reg.reg.idx[0].offset;
}
static void shader_sm5_read_dcl_tgsm_raw(struct vkd3d_shader_instruction *ins,
@ -909,9 +929,14 @@ static void shader_sm5_read_dcl_resource_structured(struct vkd3d_shader_instruct
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_RESOURCE, &ins->declaration.structured_resource.reg);
ins->declaration.structured_resource.byte_stride = *tokens;
tokens++;
if (ins->declaration.structured_resource.byte_stride % 4)
FIXME("Byte stride %u is not multiple of 4.\n", ins->declaration.structured_resource.byte_stride);
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.structured_resource.register_space);
if (shader_is_sm_5_1(priv))
ins->declaration.structured_resource.register_index = ins->declaration.structured_resource.reg.reg.idx[1].offset;
else
ins->declaration.structured_resource.register_index = ins->declaration.structured_resource.reg.reg.idx[0].offset;
}
static void shader_sm5_read_dcl_resource_raw(struct vkd3d_shader_instruction *ins,
@ -922,6 +947,10 @@ static void shader_sm5_read_dcl_resource_raw(struct vkd3d_shader_instruction *in
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_RESOURCE, &ins->declaration.dst);
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.raw_resource.register_space);
if (shader_is_sm_5_1(priv))
ins->declaration.raw_resource.register_index = ins->declaration.dst.reg.idx[1].offset;
else
ins->declaration.raw_resource.register_index = ins->declaration.dst.reg.idx[0].offset;
}
static void shader_sm5_read_sync(struct vkd3d_shader_instruction *ins,

View File

@ -1895,6 +1895,20 @@ struct vkd3d_symbol
} info;
};
struct vkd3d_sm51_symbol_key
{
enum vkd3d_shader_descriptor_type descriptor_type;
unsigned int idx;
};
struct vkd3d_sm51_symbol
{
struct rb_entry entry;
struct vkd3d_sm51_symbol_key key;
unsigned int register_space;
unsigned int resource_idx;
};
static int vkd3d_symbol_compare(const void *key, const struct rb_entry *entry)
{
const struct vkd3d_symbol *a = key;
@ -1905,6 +1919,13 @@ static int vkd3d_symbol_compare(const void *key, const struct rb_entry *entry)
return memcmp(&a->key, &b->key, sizeof(a->key));
}
static int vkd3d_sm51_symbol_compare(const void *key, const struct rb_entry *entry)
{
const struct vkd3d_sm51_symbol_key *a = key;
const struct vkd3d_sm51_symbol *b = RB_ENTRY_VALUE(entry, const struct vkd3d_sm51_symbol, entry);
return memcmp(a, &b->key, sizeof(*a));
}
static void vkd3d_symbol_free(struct rb_entry *entry, void *context)
{
struct vkd3d_symbol *s = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry);
@ -1912,6 +1933,13 @@ static void vkd3d_symbol_free(struct rb_entry *entry, void *context)
vkd3d_free(s);
}
static void vkd3d_sm51_symbol_free(struct rb_entry *entry, void *context)
{
struct vkd3d_sm51_symbol *s = RB_ENTRY_VALUE(entry, struct vkd3d_sm51_symbol, entry);
vkd3d_free(s);
}
static void vkd3d_symbol_make_register(struct vkd3d_symbol *symbol,
const struct vkd3d_shader_register *reg)
{
@ -2057,6 +2085,7 @@ struct vkd3d_hull_shader_variables
struct vkd3d_dxbc_compiler
{
struct vkd3d_shader_version shader_version;
struct vkd3d_spirv_builder spirv_builder;
uint32_t options;
@ -2067,6 +2096,8 @@ struct vkd3d_dxbc_compiler
struct vkd3d_hull_shader_variables hs;
uint32_t sample_positions_id;
struct rb_tree sm51_resource_table;
enum vkd3d_shader_type shader_type;
unsigned int branch_id;
@ -2112,6 +2143,11 @@ struct vkd3d_dxbc_compiler
size_t spec_constants_size;
};
static bool shader_is_sm_5_1(const struct vkd3d_dxbc_compiler *compiler)
{
return (compiler->shader_version.major * 100 + compiler->shader_version.minor) >= 501;
}
static bool is_control_point_phase(const struct vkd3d_shader_phase *phase)
{
return phase && phase->type == VKD3DSIH_HS_CONTROL_POINT_PHASE;
@ -2136,6 +2172,8 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
memset(compiler, 0, sizeof(*compiler));
compiler->shader_version = *shader_version;
max_element_count = max(output_signature->element_count, patch_constant_signature->element_count);
if (!(compiler->output_info = vkd3d_calloc(max_element_count, sizeof(*compiler->output_info))))
{
@ -2147,6 +2185,7 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
compiler->options = compiler_options;
rb_init(&compiler->symbol_table, vkd3d_symbol_compare);
rb_init(&compiler->sm51_resource_table, vkd3d_sm51_symbol_compare);
compiler->shader_type = shader_version->type;
@ -2232,9 +2271,10 @@ static bool vkd3d_dxbc_compiler_check_shader_visibility(const struct vkd3d_dxbc_
}
static struct vkd3d_push_constant_buffer_binding *vkd3d_dxbc_compiler_find_push_constant_buffer(
const struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg)
const struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_constant_buffer *cb)
{
unsigned int reg_idx = reg->idx[0].offset;
unsigned int reg_idx = cb->register_index;
unsigned int reg_space = cb->register_space;
unsigned int i;
for (i = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i)
@ -2244,7 +2284,7 @@ static struct vkd3d_push_constant_buffer_binding *vkd3d_dxbc_compiler_find_push_
if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, current->pc.shader_visibility))
continue;
if (current->pc.register_index == reg_idx)
if (current->pc.register_index == reg_idx && current->pc.register_space == reg_space)
return current;
}
@ -2279,6 +2319,49 @@ static bool vkd3d_dxbc_compiler_has_combined_sampler(const struct vkd3d_dxbc_com
return false;
}
static bool vkd3d_get_binding_info_for_register(
struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg,
unsigned int *reg_space, unsigned int *reg_binding)
{
const struct vkd3d_sm51_symbol *symbol;
struct vkd3d_sm51_symbol_key key;
const struct rb_entry *entry;
if (shader_is_sm_5_1(compiler))
{
key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_UNKNOWN;
if (reg->type == VKD3DSPR_CONSTBUFFER)
key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_CBV;
else if (reg->type == VKD3DSPR_RESOURCE)
key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
else if (reg->type == VKD3DSPR_UAV)
key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
else if (reg->type == VKD3DSPR_SAMPLER)
key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER;
else
FIXME("Unhandled register type %#x.\n", reg->type);
key.idx = reg->idx[0].offset;
entry = rb_get(&compiler->sm51_resource_table, &key);
if (entry)
{
symbol = RB_ENTRY_VALUE(entry, const struct vkd3d_sm51_symbol, entry);
*reg_space = symbol->register_space;
*reg_binding = symbol->resource_idx;
return true;
}
else
return false;
}
else
{
*reg_space = 0;
*reg_binding = reg->idx[0].offset;
return true;
}
}
static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor_binding(
struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg,
enum vkd3d_shader_resource_type resource_type, bool is_uav_counter)
@ -2287,8 +2370,9 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
enum vkd3d_shader_descriptor_type descriptor_type;
enum vkd3d_shader_binding_flag resource_type_flag;
struct vkd3d_shader_descriptor_binding binding;
unsigned int reg_idx = reg->idx[0].offset;
unsigned int i;
unsigned int reg_space = 0;
unsigned int reg_idx = 0;
descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_UNKNOWN;
if (reg->type == VKD3DSPR_CONSTBUFFER)
@ -2305,6 +2389,11 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER
? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE;
if (!vkd3d_get_binding_info_for_register(compiler, reg, &reg_space, &reg_idx))
{
ERR("Failed to find binding for resource type %#x.\n", reg->type);
}
if (is_uav_counter)
{
assert(descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV);
@ -2318,8 +2407,19 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
if (current->offset)
FIXME("Atomic counter offsets are not supported yet.\n");
if (current->register_index == reg_idx)
/* Do not use space/binding, but just the plain index here, since that's how the UAV counter mask is exposed. */
if (current->counter_index == reg->idx[0].offset)
{
/* Let pipeline know what the actual space/bindings for the counter are. */
const struct vkd3d_shader_effective_uav_counter_binding_info *binding_info =
vkd3d_find_struct(shader_interface->next, EFFECTIVE_UAV_COUNTER_BINDING_INFO);
if (binding_info && current->counter_index < binding_info->uav_counter_count)
{
binding_info->uav_register_spaces[current->counter_index] = reg_space;
binding_info->uav_register_bindings[current->counter_index] = reg_idx;
}
return current->binding;
}
}
if (shader_interface->uav_counter_count)
FIXME("Could not find descriptor binding for UAV counter %u.\n", reg_idx);
@ -2336,7 +2436,7 @@ 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->type == descriptor_type && current->register_index == reg_idx)
if (current->type == descriptor_type && current->register_index == reg_idx && current->register_space == reg_space)
return current->binding;
}
if (shader_interface->binding_count)
@ -2833,7 +2933,8 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp
{
assert(!reg->idx[0].rel_addr);
indexes[index_count++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, register_info->member_idx);
indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, &reg->idx[1]);
indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler,
&reg->idx[shader_is_sm_5_1(compiler) ? 2 : 1]);
}
else if (reg->type == VKD3DSPR_IMMCONSTBUFFER)
{
@ -2843,6 +2944,12 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp
{
indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, &reg->idx[1]);
}
else if (reg->type == VKD3DSPR_SAMPLER)
{
/* SM 5.1 will have an index here referring to an array of samplers,
* which we currently throw away as there is no support for descriptor arrays. */
index_count = 0;
}
else if (register_info->is_aggregate)
{
struct vkd3d_shader_register_index reg_idx = reg->idx[0];
@ -4956,7 +5063,8 @@ static void vkd3d_dxbc_compiler_emit_push_constant_buffers(struct vkd3d_dxbc_com
if (!cb->reg.type)
continue;
cb_size = cb->reg.idx[1].offset;
cb_size = (cb->pc.size + 15) / 16;
length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, cb_size);
member_ids[j] = vkd3d_spirv_build_op_type_array(builder, vec4_id, length_id);
vkd3d_spirv_build_op_decorate1(builder, member_ids[j], SpvDecorationArrayStride, 16);
@ -5007,10 +5115,19 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi
assert(!(instruction->flags & ~VKD3DSI_INDEXED_DYNAMIC));
if (cb->register_space)
FIXME("Unhandled register space %u.\n", cb->register_space);
if (shader_is_sm_5_1(compiler))
{
struct vkd3d_sm51_symbol *sym;
sym = vkd3d_calloc(1, sizeof(*sym));
sym->key.idx = reg->idx[0].offset;
sym->key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_CBV;
sym->register_space = instruction->declaration.cb.register_space;
sym->resource_idx = instruction->declaration.cb.register_index;
if (rb_put(&compiler->sm51_resource_table, &sym->key, &sym->entry) == -1)
vkd3d_free(sym);
}
if ((push_cb = vkd3d_dxbc_compiler_find_push_constant_buffer(compiler, reg)))
if ((push_cb = vkd3d_dxbc_compiler_find_push_constant_buffer(compiler, cb)))
{
/* Push constant buffers are handled in
* vkd3d_dxbc_compiler_emit_push_constant_buffers().
@ -5092,8 +5209,17 @@ static void vkd3d_dxbc_compiler_emit_dcl_sampler(struct vkd3d_dxbc_compiler *com
uint32_t type_id, ptr_type_id, var_id;
struct vkd3d_symbol reg_symbol;
if (instruction->declaration.sampler.register_space)
FIXME("Unhandled register space %u.\n", instruction->declaration.sampler.register_space);
if (shader_is_sm_5_1(compiler))
{
struct vkd3d_sm51_symbol *sym;
sym = vkd3d_calloc(1, sizeof(*sym));
sym->key.idx = reg->idx[0].offset;
sym->key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER;
sym->register_space = instruction->declaration.sampler.register_space;
sym->resource_idx = instruction->declaration.sampler.register_index;
if (rb_put(&compiler->sm51_resource_table, &sym->key, &sym->entry) == -1)
vkd3d_free(sym);
}
if (vkd3d_dxbc_compiler_has_combined_sampler(compiler, NULL, reg))
return;
@ -5314,8 +5440,18 @@ static void vkd3d_dxbc_compiler_emit_dcl_resource(struct vkd3d_dxbc_compiler *co
{
const struct vkd3d_shader_semantic *semantic = &instruction->declaration.semantic;
if (semantic->register_space)
FIXME("Unhandled register space %u.\n", semantic->register_space);
if (shader_is_sm_5_1(compiler))
{
struct vkd3d_sm51_symbol *sym;
sym = vkd3d_calloc(1, sizeof(*sym));
sym->key.idx = semantic->reg.reg.idx[0].offset;
sym->key.descriptor_type = semantic->reg.reg.type == VKD3DSPR_UAV ? VKD3D_SHADER_DESCRIPTOR_TYPE_UAV : VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
sym->register_space = semantic->register_space;
sym->resource_idx = semantic->register_index;
if (rb_put(&compiler->sm51_resource_table, &sym->key, &sym->entry) == -1)
vkd3d_free(sym);
}
if (instruction->flags)
FIXME("Unhandled UAV flags %#x.\n", instruction->flags);
@ -5328,8 +5464,18 @@ static void vkd3d_dxbc_compiler_emit_dcl_resource_raw(struct vkd3d_dxbc_compiler
{
const struct vkd3d_shader_raw_resource *resource = &instruction->declaration.raw_resource;
if (resource->register_space)
FIXME("Unhandled register space %u.\n", resource->register_space);
if (shader_is_sm_5_1(compiler))
{
struct vkd3d_sm51_symbol *sym;
sym = vkd3d_calloc(1, sizeof(*sym));
sym->key.idx = resource->dst.reg.idx[0].offset;
sym->key.descriptor_type = resource->dst.reg.type == VKD3DSPR_UAV ? VKD3D_SHADER_DESCRIPTOR_TYPE_UAV : VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
sym->register_space = resource->register_space;
sym->resource_idx = resource->register_index;
if (rb_put(&compiler->sm51_resource_table, &sym->key, &sym->entry) == -1)
vkd3d_free(sym);
}
if (instruction->flags)
FIXME("Unhandled UAV flags %#x.\n", instruction->flags);
@ -5344,8 +5490,18 @@ static void vkd3d_dxbc_compiler_emit_dcl_resource_structured(struct vkd3d_dxbc_c
const struct vkd3d_shader_register *reg = &resource->reg.reg;
unsigned int stride = resource->byte_stride;
if (resource->register_space)
FIXME("Unhandled register space %u.\n", resource->register_space);
if (shader_is_sm_5_1(compiler))
{
struct vkd3d_sm51_symbol *sym;
sym = vkd3d_calloc(1, sizeof(*sym));
sym->key.idx = resource->reg.reg.idx[0].offset;
sym->key.descriptor_type = resource->reg.reg.type == VKD3DSPR_UAV ? VKD3D_SHADER_DESCRIPTOR_TYPE_UAV : VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
sym->register_space = resource->register_space;
sym->resource_idx = resource->register_index;
if (rb_put(&compiler->sm51_resource_table, &sym->key, &sym->entry) == -1)
vkd3d_free(sym);
}
if (instruction->flags)
FIXME("Unhandled UAV flags %#x.\n", instruction->flags);
@ -8777,6 +8933,7 @@ void vkd3d_dxbc_compiler_destroy(struct vkd3d_dxbc_compiler *compiler)
vkd3d_spirv_builder_free(&compiler->spirv_builder);
rb_destroy(&compiler->symbol_table, vkd3d_symbol_free, NULL);
rb_destroy(&compiler->sm51_resource_table, vkd3d_sm51_symbol_free, NULL);
vkd3d_free(compiler->shader_phases);
vkd3d_free(compiler->spec_constants);

View File

@ -615,6 +615,7 @@ struct vkd3d_shader_semantic
enum vkd3d_data_type resource_data_type;
struct vkd3d_shader_dst_param reg;
unsigned int register_space;
unsigned int register_index;
};
enum vkd3d_shader_input_sysval_semantic
@ -662,6 +663,7 @@ struct vkd3d_shader_register_semantic
struct vkd3d_shader_sampler
{
struct vkd3d_shader_src_param src;
unsigned int register_index;
unsigned int register_space;
};
@ -669,6 +671,7 @@ struct vkd3d_shader_constant_buffer
{
struct vkd3d_shader_src_param src;
unsigned int size;
unsigned int register_index;
unsigned int register_space;
};
@ -676,12 +679,14 @@ struct vkd3d_shader_structured_resource
{
struct vkd3d_shader_dst_param reg;
unsigned int byte_stride;
unsigned int register_index;
unsigned int register_space;
};
struct vkd3d_shader_raw_resource
{
struct vkd3d_shader_dst_param dst;
unsigned int register_index;
unsigned int register_space;
};

View File

@ -2655,7 +2655,7 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list
const struct d3d12_root_descriptor_table *descriptor_table;
const struct d3d12_root_descriptor_table_range *range;
VkDevice vk_device = list->device->vk_device;
unsigned int i, j, descriptor_count;
unsigned int i, j, k, descriptor_count;
struct d3d12_desc *descriptor;
descriptor_table = root_signature_get_descriptor_table(root_signature, index);
@ -2678,14 +2678,26 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list
unsigned int register_idx = range->base_register_idx + j;
/* Track UAV counters. */
if (range->descriptor_magic == VKD3D_DESCRIPTOR_MAGIC_UAV
&& register_idx < ARRAY_SIZE(bindings->vk_uav_counter_views))
if (list->state->uav_counter_mask != 0 && range->descriptor_magic == VKD3D_DESCRIPTOR_MAGIC_UAV)
{
VkBufferView vk_counter_view = descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_UAV
? descriptor->u.view->vk_counter_view : VK_NULL_HANDLE;
if (bindings->vk_uav_counter_views[register_idx] != vk_counter_view)
bindings->uav_counter_dirty_mask |= 1u << register_idx;
bindings->vk_uav_counter_views[register_idx] = vk_counter_view;
const struct vkd3d_shader_uav_counter_binding *counter_bindings = list->state->uav_counters;
for (k = 0; k < VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS; k++)
{
if (list->state->uav_counter_mask & (1u << k))
{
if (counter_bindings->register_space == range->register_space &&
counter_bindings->register_index == register_idx)
{
VkBufferView vk_counter_view = descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_UAV
? descriptor->u.view->vk_counter_view : VK_NULL_HANDLE;
if (bindings->vk_uav_counter_views[k] != vk_counter_view)
bindings->uav_counter_dirty_mask |= 1u << k;
bindings->vk_uav_counter_views[k] = vk_counter_view;
break;
}
counter_bindings++;
}
}
}
if (!vk_write_descriptor_set_from_d3d12_desc(current_descriptor_write,
@ -2841,7 +2853,7 @@ static void d3d12_command_list_update_uav_counter_descriptors(struct d3d12_comma
const struct vkd3d_shader_uav_counter_binding *uav_counter = &state->uav_counters[i];
const VkBufferView *vk_uav_counter_views = bindings->vk_uav_counter_views;
assert(vk_uav_counter_views[uav_counter->register_index]);
assert(vk_uav_counter_views[uav_counter->counter_index]);
vk_descriptor_writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
vk_descriptor_writes[i].pNext = NULL;
@ -2852,7 +2864,7 @@ static void d3d12_command_list_update_uav_counter_descriptors(struct d3d12_comma
vk_descriptor_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
vk_descriptor_writes[i].pImageInfo = NULL;
vk_descriptor_writes[i].pBufferInfo = NULL;
vk_descriptor_writes[i].pTexelBufferView = &vk_uav_counter_views[uav_counter->register_index];
vk_descriptor_writes[i].pTexelBufferView = &vk_uav_counter_views[uav_counter->counter_index];
}
VK_CALL(vkUpdateDescriptorSets(vk_device, uav_counter_count, vk_descriptor_writes, 0, NULL));

View File

@ -309,12 +309,6 @@ static bool vk_binding_from_d3d12_descriptor_range(struct VkDescriptorSetLayoutB
= vk_descriptor_type_from_d3d12_range_type(descriptor_range->RangeType, is_buffer);
binding_desc->descriptorCount = 1;
if (descriptor_range->RegisterSpace)
{
FIXME("Unhandled register space %u.\n", descriptor_range->RegisterSpace);
return false;
}
binding_desc->stageFlags = stage_flags_from_visibility(shader_visibility);
binding_desc->pImmutableSamplers = NULL;
@ -495,12 +489,6 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat
if (p->ParameterType != D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS)
continue;
if (p->u.Constants.RegisterSpace)
{
FIXME("Unhandled register space %u for parameter %u.\n", p->u.Constants.RegisterSpace, i);
return E_NOTIMPL;
}
idx = push_constant_count == 1 ? 0 : p->ShaderVisibility;
offset = push_constants_offset[idx];
push_constants_offset[idx] += p->u.Constants.Num32BitValues * sizeof(uint32_t);
@ -510,6 +498,7 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat
? push_constants[0].stageFlags : stage_flags_from_visibility(p->ShaderVisibility);
root_constant->offset = offset;
root_signature->root_constants[j].register_space = p->u.Constants.RegisterSpace;
root_signature->root_constants[j].register_index = p->u.Constants.ShaderRegister;
root_signature->root_constants[j].shader_visibility
= vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility);
@ -533,7 +522,7 @@ struct vkd3d_descriptor_set_context
};
static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *root_signature,
enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_idx,
enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_space, unsigned int register_idx,
bool buffer_descriptor, enum vkd3d_shader_visibility shader_visibility,
struct vkd3d_descriptor_set_context *context)
{
@ -541,6 +530,7 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *
= &root_signature->descriptor_mapping[context->descriptor_index++];
mapping->type = descriptor_type;
mapping->register_space = register_space;
mapping->register_index = register_idx;
mapping->shader_visibility = shader_visibility;
mapping->flags = buffer_descriptor ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE;
@ -549,7 +539,7 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *
}
static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signature *root_signature,
enum vkd3d_shader_descriptor_type descriptor_type, unsigned int base_register_idx,
enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_space, unsigned int base_register_idx,
unsigned int binding_count, bool is_buffer_descriptor, bool duplicate_descriptors,
enum vkd3d_shader_visibility shader_visibility, struct vkd3d_descriptor_set_context *context)
{
@ -566,10 +556,10 @@ static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signat
{
if (duplicate_descriptors)
d3d12_root_signature_append_vk_binding(root_signature, descriptor_type,
base_register_idx + i, true, shader_visibility, context);
register_space, base_register_idx + i, true, shader_visibility, context);
d3d12_root_signature_append_vk_binding(root_signature, descriptor_type,
base_register_idx + i, is_buffer_descriptor, shader_visibility, context);
register_space, base_register_idx + i, is_buffer_descriptor, shader_visibility, context);
}
return first_binding;
}
@ -625,7 +615,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
vk_binding = d3d12_root_signature_assign_vk_bindings(root_signature,
vkd3d_descriptor_type_from_d3d12_range_type(range->RangeType),
range->BaseShaderRegister, range->NumDescriptors, false, true,
range->RegisterSpace, range->BaseShaderRegister, range->NumDescriptors, false, true,
vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility), context);
/* Unroll descriptor range. */
@ -658,6 +648,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
table->ranges[j].binding = vk_binding;
table->ranges[j].descriptor_magic = vkd3d_descriptor_magic_from_d3d12(range->RangeType);
table->ranges[j].base_register_idx = range->BaseShaderRegister;
table->ranges[j].register_space = range->RegisterSpace;
}
}
@ -683,15 +674,9 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign
root_signature->push_descriptor_mask |= 1u << i;
if (p->u.Descriptor.RegisterSpace)
{
FIXME("Unhandled register space %u for parameter %u.\n", p->u.Descriptor.RegisterSpace, i);
return E_NOTIMPL;
}
cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature,
vkd3d_descriptor_type_from_d3d12_root_parameter_type(p->ParameterType),
p->u.Descriptor.ShaderRegister, 1, true, false,
p->u.Descriptor.RegisterSpace, p->u.Descriptor.ShaderRegister, 1, true, false,
vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility), context);
cur_binding->descriptorType = vk_descriptor_type_from_d3d12_root_parameter(p->ParameterType);
cur_binding->descriptorCount = 1;
@ -728,7 +713,7 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa
return hr;
cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature,
VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, s->ShaderRegister, 1, false, false,
VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, s->RegisterSpace, s->ShaderRegister, 1, false, false,
vkd3d_shader_visibility_from_d3d12(s->ShaderVisibility), context);
cur_binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
cur_binding->descriptorCount = 1;
@ -1451,7 +1436,14 @@ static HRESULT d3d12_pipeline_state_init_compute_uav_counters(struct d3d12_pipel
if (!(shader_info->uav_counter_mask & (1u << i)))
continue;
/* UAV counters will lookup Vulkan bindings based on the mask index directly.
* We currently don't know the actual space/binding for this UAV,
* but register_space/register_index are fixed up later after compilation is finished. */
state->uav_counters[j].register_space = 0;
state->uav_counters[j].register_index = i;
state->uav_counters[j].counter_index = i;
state->uav_counters[j].shader_visibility = VKD3D_SHADER_VISIBILITY_COMPUTE;
state->uav_counters[j].binding.set = context.set_index;
state->uav_counters[j].binding.binding = context.descriptor_binding;
@ -1507,6 +1499,10 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
struct vkd3d_shader_code dxbc;
HRESULT hr;
int ret;
unsigned int i, j;
unsigned int uav_counter_spaces[VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS] = { 0 };
unsigned int uav_counter_bindings[VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS] = { 0 };
struct vkd3d_shader_effective_uav_counter_binding_info uav_binding_info = { VKD3D_SHADER_STRUCTURE_TYPE_EFFECTIVE_UAV_COUNTER_BINDING_INFO };
state->ID3D12PipelineState_iface.lpVtbl = &d3d12_pipeline_state_vtbl;
state->refcount = 1;
@ -1550,8 +1546,14 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
shader_interface.uav_counters = state->uav_counters;
shader_interface.uav_counter_count = vkd3d_popcount(state->uav_counter_mask);
shader_interface.next = &uav_binding_info;
uav_binding_info.uav_register_spaces = uav_counter_spaces;
uav_binding_info.uav_register_bindings = uav_counter_bindings;
uav_binding_info.uav_counter_count = VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS;
vk_pipeline_layout = state->vk_pipeline_layout
? state->vk_pipeline_layout : root_signature->vk_pipeline_layout;
if (FAILED(hr = vkd3d_create_compute_pipeline(device, &desc->CS, &shader_interface,
vk_pipeline_layout, &state->u.compute.vk_pipeline)))
{
@ -1575,6 +1577,17 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
return hr;
}
/* Map back to actual space/bindings for the UAV counter now that we know. */
for (i = 0, j = 0; i < VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS; i++)
{
if (state->uav_counter_mask & (1u << i))
{
state->uav_counters[j].register_space = uav_counter_spaces[i];
state->uav_counters[j].register_index = uav_counter_bindings[i];
j++;
}
}
state->vk_bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
d3d12_device_add_ref(state->device = device);
@ -2911,6 +2924,7 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d
binding.type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
binding.register_index = 0;
binding.register_space = 0;
binding.shader_visibility = VKD3D_SHADER_VISIBILITY_COMPUTE;
binding.binding.set = 0;
binding.binding.binding = 0;
@ -2919,6 +2933,7 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d
push_constant_range.offset = 0;
push_constant_range.size = sizeof(struct vkd3d_uav_clear_args);
push_constant.register_space = 0;
push_constant.register_index = 0;
push_constant.shader_visibility = VKD3D_SHADER_VISIBILITY_COMPUTE;
push_constant.offset = 0;

View File

@ -661,6 +661,7 @@ struct d3d12_root_descriptor_table_range
uint32_t descriptor_magic;
unsigned int base_register_idx;
unsigned int register_space;
};
struct d3d12_root_descriptor_table