[PATCH vkd3d 1/5] vkd3d-shader: Report descriptor usage information in vkd3d_shader_scan_dxbc().
Henri Verbeet
hverbeet at codeweavers.com
Thu Jun 25 01:18:24 CDT 2020
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
include/vkd3d_shader.h | 13 ++++
libs/vkd3d-shader/vkd3d_shader.map | 1 +
libs/vkd3d-shader/vkd3d_shader_main.c | 130 +++++++++++++++++++++++++++++++---
libs/vkd3d/state.c | 2 +
4 files changed, 137 insertions(+), 9 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 358e90d..b2fa499 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -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);
diff --git a/libs/vkd3d-shader/vkd3d_shader.map b/libs/vkd3d-shader/vkd3d_shader.map
index a8c73b6..13bebde 100644
--- a/libs/vkd3d-shader/vkd3d_shader.map
+++ b/libs/vkd3d-shader/vkd3d_shader.map
@@ -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;
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 3255094..45a7a80 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -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_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_instruction(struct vkd3d_shader_scan_info *scan_info,
+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)
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index db342df..501afc6 100644
--- a/libs/vkd3d/state.c
+++ b/libs/vkd3d/state.c
@@ -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)
--
2.11.0
More information about the wine-devel
mailing list