vkd3d-shader: Report descriptor usage information in vkd3d_shader_scan_dxbc().

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Henri Verbeet 2020-06-25 10:48:24 +04:30 committed by Alexandre Julliard
parent 73145653ac
commit 25c0966b69
4 changed files with 137 additions and 9 deletions

View File

@ -585,11 +585,22 @@ struct vkd3d_versioned_root_signature_desc
/* FIXME: Add support for 64 UAV bind slots. */
#define VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS 8
struct vkd3d_shader_descriptor_info
{
enum vkd3d_shader_descriptor_type type;
unsigned int register_space;
unsigned int register_index;
unsigned int count;
};
struct vkd3d_shader_scan_info
{
enum vkd3d_shader_structure_type type;
void *next;
struct vkd3d_shader_descriptor_info *descriptors;
unsigned int descriptor_count;
unsigned int uav_read_mask; /* VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS */
unsigned int uav_counter_mask; /* VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS */
unsigned int sampler_comparison_mode_mask; /* 16 */
@ -694,6 +705,7 @@ int vkd3d_shader_convert_root_signature(struct vkd3d_versioned_root_signature_de
int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_scan_info *scan_info);
void vkd3d_shader_free_scan_info(struct vkd3d_shader_scan_info *scan_info);
int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_signature *signature);
@ -723,6 +735,7 @@ typedef int (*PFN_vkd3d_shader_convert_root_signature)(struct vkd3d_versioned_ro
typedef int (*PFN_vkd3d_shader_scan_dxbc)(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_scan_info *scan_info);
typedef void (*PFN_vkd3d_shader_free_scan_info)(struct vkd3d_shader_scan_info *scan_info);
typedef int (*PFN_vkd3d_shader_parse_input_signature)(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_signature *signature);

View File

@ -5,6 +5,7 @@ global:
vkd3d_shader_convert_root_signature;
vkd3d_shader_find_signature_element;
vkd3d_shader_free_root_signature;
vkd3d_shader_free_scan_info;
vkd3d_shader_free_shader_code;
vkd3d_shader_free_shader_signature;
vkd3d_shader_parse_input_signature;

View File

@ -187,9 +187,16 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, s
vkd3d_dxbc_compiler_destroy(spirv_compiler);
vkd3d_shader_parser_destroy(&parser);
vkd3d_shader_free_scan_info(&scan_info);
return ret;
}
struct vkd3d_shader_scan_context
{
struct vkd3d_shader_scan_info *scan_info;
size_t descriptors_size;
};
static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instruction *instruction)
{
enum VKD3D_SHADER_INSTRUCTION_HANDLER handler_idx = instruction->handler_idx;
@ -221,6 +228,38 @@ static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_info *
scan_info->uav_counter_mask |= 1u << reg->idx[0].offset;
}
static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context,
enum vkd3d_shader_descriptor_type type, unsigned int register_space, unsigned int register_index)
{
struct vkd3d_shader_scan_info *scan_info = context->scan_info;
struct vkd3d_shader_descriptor_info *d;
if (!vkd3d_array_reserve((void **)&scan_info->descriptors, &context->descriptors_size,
scan_info->descriptor_count + 1, sizeof(*scan_info->descriptors)))
{
ERR("Failed to allocate descriptor info.\n");
return false;
}
d = &scan_info->descriptors[scan_info->descriptor_count];
d->type = type;
d->register_space = register_space;
d->register_index = register_index;
d->count = 1;
++scan_info->descriptor_count;
return true;
}
static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_instruction *instruction)
{
const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb;
vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV,
cb->register_space, cb->register_index);
}
static void vkd3d_shader_scan_input_declaration(struct vkd3d_shader_scan_info *scan_info,
const struct vkd3d_shader_instruction *instruction)
{
@ -230,29 +269,89 @@ static void vkd3d_shader_scan_input_declaration(struct vkd3d_shader_scan_info *s
scan_info->use_vocp = true;
}
static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_info *scan_info,
static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_instruction *instruction)
{
unsigned int sampler_index = instruction->declaration.dst.reg.idx[0].offset;
const struct vkd3d_shader_sampler *sampler = &instruction->declaration.sampler;
struct vkd3d_shader_scan_info *scan_info = context->scan_info;
unsigned int sampler_index = sampler->register_index;
if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE)
{
assert(sampler_index < CHAR_BIT * sizeof(scan_info->sampler_comparison_mode_mask));
scan_info->sampler_comparison_mode_mask |= 1u << sampler_index;
}
vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER,
sampler->register_space, sampler->register_index);
}
static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_info *scan_info,
static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_instruction *instruction)
{
const struct vkd3d_shader_semantic *semantic = &instruction->declaration.semantic;
enum vkd3d_shader_descriptor_type type;
if (semantic->reg.reg.type == VKD3DSPR_UAV)
type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
else
type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
vkd3d_shader_scan_add_descriptor(context, type, semantic->register_space, semantic->register_index);
}
static void vkd3d_shader_scan_resource_declaration_raw(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_instruction *instruction)
{
const struct vkd3d_shader_raw_resource *resource = &instruction->declaration.raw_resource;
enum vkd3d_shader_descriptor_type type;
if (resource->dst.reg.type == VKD3DSPR_UAV)
type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
else
type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
vkd3d_shader_scan_add_descriptor(context, type, resource->register_space, resource->register_index);
}
static void vkd3d_shader_scan_resource_declaration_structured(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_instruction *instruction)
{
const struct vkd3d_shader_structured_resource *resource = &instruction->declaration.structured_resource;
enum vkd3d_shader_descriptor_type type;
if (resource->reg.reg.type == VKD3DSPR_UAV)
type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
else
type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
vkd3d_shader_scan_add_descriptor(context, type, resource->register_space, resource->register_index);
}
static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_instruction *instruction)
{
unsigned int i;
switch (instruction->handler_idx)
{
case VKD3DSIH_DCL_CONSTANT_BUFFER:
vkd3d_shader_scan_constant_buffer_declaration(context, instruction);
break;
case VKD3DSIH_DCL_INPUT:
vkd3d_shader_scan_input_declaration(scan_info, instruction);
vkd3d_shader_scan_input_declaration(context->scan_info, instruction);
break;
case VKD3DSIH_DCL_SAMPLER:
vkd3d_shader_scan_sampler_declaration(scan_info, instruction);
vkd3d_shader_scan_sampler_declaration(context, instruction);
break;
case VKD3DSIH_DCL:
case VKD3DSIH_DCL_UAV_TYPED:
vkd3d_shader_scan_resource_declaration(context, instruction);
break;
case VKD3DSIH_DCL_RESOURCE_RAW:
case VKD3DSIH_DCL_UAV_RAW:
vkd3d_shader_scan_resource_declaration_raw(context, instruction);
break;
case VKD3DSIH_DCL_RESOURCE_STRUCTURED:
case VKD3DSIH_DCL_UAV_STRUCTURED:
vkd3d_shader_scan_resource_declaration_structured(context, instruction);
break;
default:
break;
@ -263,23 +362,24 @@ static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_info *scan_in
for (i = 0; i < instruction->dst_count; ++i)
{
if (instruction->dst[i].reg.type == VKD3DSPR_UAV)
vkd3d_shader_scan_record_uav_read(scan_info, &instruction->dst[i].reg);
vkd3d_shader_scan_record_uav_read(context->scan_info, &instruction->dst[i].reg);
}
for (i = 0; i < instruction->src_count; ++i)
{
if (instruction->src[i].reg.type == VKD3DSPR_UAV)
vkd3d_shader_scan_record_uav_read(scan_info, &instruction->src[i].reg);
vkd3d_shader_scan_record_uav_read(context->scan_info, &instruction->src[i].reg);
}
}
if (vkd3d_shader_instruction_is_uav_counter(instruction))
vkd3d_shader_scan_record_uav_counter(scan_info, &instruction->src[0].reg);
vkd3d_shader_scan_record_uav_counter(context->scan_info, &instruction->src[0].reg);
}
int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_scan_info *scan_info)
{
struct vkd3d_shader_instruction instruction;
struct vkd3d_shader_scan_context context;
struct vkd3d_shader_parser parser;
int ret;
@ -296,6 +396,9 @@ int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
memset(scan_info, 0, sizeof(*scan_info));
memset(&context, 0, sizeof(context));
context.scan_info = scan_info;
while (!shader_sm4_is_end(parser.data, &parser.ptr))
{
shader_sm4_read_instruction(parser.data, &parser.ptr, &instruction);
@ -303,17 +406,26 @@ int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
if (instruction.handler_idx == VKD3DSIH_INVALID)
{
WARN("Encountered unrecognized or invalid instruction.\n");
vkd3d_shader_free_scan_info(scan_info);
vkd3d_shader_parser_destroy(&parser);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
vkd3d_shader_scan_instruction(scan_info, &instruction);
vkd3d_shader_scan_instruction(&context, &instruction);
}
vkd3d_shader_parser_destroy(&parser);
return VKD3D_OK;
}
void vkd3d_shader_free_scan_info(struct vkd3d_shader_scan_info *scan_info)
{
if (!scan_info)
return;
vkd3d_free(scan_info->descriptors);
}
void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *shader_code)
{
if (!shader_code)

View File

@ -1528,6 +1528,7 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
WARN("Failed to create descriptor set layout for UAV counters, hr %#x.\n", hr);
return hr;
}
vkd3d_shader_free_scan_info(&shader_info);
shader_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO;
shader_interface.next = NULL;
@ -2267,6 +2268,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
}
if (shader_info.uav_counter_mask)
FIXME("UAV counters not implemented for graphics pipelines.\n");
vkd3d_shader_free_scan_info(&shader_info);
target_info = NULL;
switch (shader_stages[i].stage)