mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
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:
parent
73145653ac
commit
25c0966b69
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user