vkd3d-shader: Pass a vkd3d_shader_compile_info structure to vkd3d_shader_scan_dxbc().

In order to allow it to handle different source types.

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Henri Verbeet 2020-07-30 14:59:55 +04:30 committed by Alexandre Julliard
parent 1c8077546e
commit 11f82d985c
7 changed files with 141 additions and 95 deletions

View File

@ -32,7 +32,7 @@ enum vkd3d_shader_structure_type
/* 1.2 */ /* 1.2 */
VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO, VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO,
VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO, VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO,
VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO, VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO,
VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_DOMAIN_SHADER_TARGET_INFO, VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_DOMAIN_SHADER_TARGET_INFO,
VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO, VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO,
VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO, VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO,
@ -653,10 +653,11 @@ struct vkd3d_shader_descriptor_info
unsigned int count; unsigned int count;
}; };
struct vkd3d_shader_scan_info /* Extends vkd3d_shader_compile_info. */
struct vkd3d_shader_scan_descriptor_info
{ {
enum vkd3d_shader_structure_type type; enum vkd3d_shader_structure_type type;
void *next; const void *next;
struct vkd3d_shader_descriptor_info *descriptors; struct vkd3d_shader_descriptor_info *descriptors;
unsigned int descriptor_count; unsigned int descriptor_count;
@ -762,9 +763,8 @@ int vkd3d_shader_serialize_root_signature(const struct vkd3d_shader_versioned_ro
int vkd3d_shader_convert_root_signature(struct vkd3d_shader_versioned_root_signature_desc *dst, int vkd3d_shader_convert_root_signature(struct vkd3d_shader_versioned_root_signature_desc *dst,
enum vkd3d_shader_root_signature_version version, const struct vkd3d_shader_versioned_root_signature_desc *src); enum vkd3d_shader_root_signature_version version, const struct vkd3d_shader_versioned_root_signature_desc *src);
int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc, int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages);
struct vkd3d_shader_scan_info *scan_info, char **messages); void vkd3d_shader_free_scan_descriptor_info(struct vkd3d_shader_scan_descriptor_info *scan_descriptor_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, int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_signature *signature); struct vkd3d_shader_signature *signature);
@ -793,9 +793,9 @@ typedef int (*PFN_vkd3d_shader_serialize_root_signature)(
typedef int (*PFN_vkd3d_shader_convert_root_signature)(struct vkd3d_shader_versioned_root_signature_desc *dst, typedef int (*PFN_vkd3d_shader_convert_root_signature)(struct vkd3d_shader_versioned_root_signature_desc *dst,
enum vkd3d_shader_root_signature_version version, const struct vkd3d_shader_versioned_root_signature_desc *src); enum vkd3d_shader_root_signature_version version, const struct vkd3d_shader_versioned_root_signature_desc *src);
typedef int (*PFN_vkd3d_shader_scan_dxbc)(const struct vkd3d_shader_code *dxbc, typedef int (*PFN_vkd3d_shader_scan)(const struct vkd3d_shader_compile_info *compile_info, char **messages);
struct vkd3d_shader_scan_info *scan_info, char **messages); typedef void (*PFN_vkd3d_shader_free_scan_descriptor_info)(
typedef void (*PFN_vkd3d_shader_free_scan_info)(struct vkd3d_shader_scan_info *scan_info); struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info);
typedef int (*PFN_vkd3d_shader_parse_input_signature)(const struct vkd3d_shader_code *dxbc, typedef int (*PFN_vkd3d_shader_parse_input_signature)(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_signature *signature); struct vkd3d_shader_signature *signature);

View File

@ -111,27 +111,6 @@ static void vkd3d_spirv_validate(const struct vkd3d_shader_code *spirv,
#endif /* HAVE_SPIRV_TOOLS */ #endif /* HAVE_SPIRV_TOOLS */
struct vkd3d_struct
{
enum vkd3d_shader_structure_type type;
const void *next;
};
#define vkd3d_find_struct(c, t) vkd3d_find_struct_(c, VKD3D_SHADER_STRUCTURE_TYPE_##t)
static const void *vkd3d_find_struct_(const struct vkd3d_struct *chain,
enum vkd3d_shader_structure_type type)
{
while (chain)
{
if (chain->type == type)
return chain;
chain = chain->next;
}
return NULL;
}
static enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, static enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval,
unsigned int index) unsigned int index)
{ {
@ -2103,7 +2082,7 @@ struct vkd3d_dxbc_compiler
uint32_t binding_idx; uint32_t binding_idx;
const struct vkd3d_shader_scan_info *scan_info; const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
unsigned int input_control_point_count; unsigned int input_control_point_count;
unsigned int output_control_point_count; unsigned int output_control_point_count;
bool use_vocp; bool use_vocp;
@ -2134,7 +2113,7 @@ static const char *vkd3d_dxbc_compiler_get_entry_point_name(const struct vkd3d_d
struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version, struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version,
const struct vkd3d_shader_desc *shader_desc, const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_desc *shader_desc, const struct vkd3d_shader_compile_info *compile_info,
const struct vkd3d_shader_scan_info *scan_info) const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info)
{ {
const struct vkd3d_shader_signature *patch_constant_signature = &shader_desc->patch_constant_signature; const struct vkd3d_shader_signature *patch_constant_signature = &shader_desc->patch_constant_signature;
const struct vkd3d_shader_signature *output_signature = &shader_desc->output_signature; const struct vkd3d_shader_signature *output_signature = &shader_desc->output_signature;
@ -2216,7 +2195,7 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
} }
} }
compiler->scan_info = scan_info; compiler->scan_descriptor_info = scan_descriptor_info;
vkd3d_dxbc_compiler_emit_initial_declarations(compiler); vkd3d_dxbc_compiler_emit_initial_declarations(compiler);
@ -5177,13 +5156,13 @@ static const struct vkd3d_shader_descriptor_info *vkd3d_dxbc_compiler_get_descri
struct vkd3d_dxbc_compiler *compiler, enum vkd3d_shader_descriptor_type type, struct vkd3d_dxbc_compiler *compiler, enum vkd3d_shader_descriptor_type type,
unsigned int register_space, unsigned int register_index) unsigned int register_space, unsigned int register_index)
{ {
const struct vkd3d_shader_scan_info *scan_info = compiler->scan_info; const struct vkd3d_shader_scan_descriptor_info *descriptor_info = compiler->scan_descriptor_info;
const struct vkd3d_shader_descriptor_info *d; const struct vkd3d_shader_descriptor_info *d;
unsigned int i; unsigned int i;
for (i = 0; i < scan_info->descriptor_count; ++i) for (i = 0; i < descriptor_info->descriptor_count; ++i)
{ {
d = &scan_info->descriptors[i]; d = &descriptor_info->descriptors[i];
if (d->type == type && d->register_space == register_space && d->register_index == register_index) if (d->type == type && d->register_space == register_space && d->register_index == register_index)
return d; return d;
} }

View File

@ -6,12 +6,12 @@ global:
vkd3d_shader_find_signature_element; vkd3d_shader_find_signature_element;
vkd3d_shader_free_messages; vkd3d_shader_free_messages;
vkd3d_shader_free_root_signature; vkd3d_shader_free_root_signature;
vkd3d_shader_free_scan_info; vkd3d_shader_free_scan_descriptor_info;
vkd3d_shader_free_shader_code; vkd3d_shader_free_shader_code;
vkd3d_shader_free_shader_signature; vkd3d_shader_free_shader_signature;
vkd3d_shader_parse_input_signature; vkd3d_shader_parse_input_signature;
vkd3d_shader_parse_root_signature; vkd3d_shader_parse_root_signature;
vkd3d_shader_scan_dxbc; vkd3d_shader_scan;
vkd3d_shader_serialize_root_signature; vkd3d_shader_serialize_root_signature;
local: *; local: *;

View File

@ -285,10 +285,11 @@ void vkd3d_shader_free_messages(char *messages)
int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out, char **messages) struct vkd3d_shader_code *out, char **messages)
{ {
struct vkd3d_shader_scan_descriptor_info scan_descriptor_info;
struct vkd3d_shader_message_context message_context; struct vkd3d_shader_message_context message_context;
struct vkd3d_shader_instruction instruction; struct vkd3d_shader_instruction instruction;
struct vkd3d_shader_compile_info scan_info;
struct vkd3d_dxbc_compiler *spirv_compiler; struct vkd3d_dxbc_compiler *spirv_compiler;
struct vkd3d_shader_scan_info scan_info;
struct vkd3d_shader_parser parser; struct vkd3d_shader_parser parser;
int ret; int ret;
@ -300,9 +301,12 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
if ((ret = vkd3d_shader_validate_compile_info(compile_info)) < 0) if ((ret = vkd3d_shader_validate_compile_info(compile_info)) < 0)
return ret; return ret;
scan_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO; scan_info = *compile_info;
scan_info.next = NULL; scan_descriptor_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO;
if ((ret = vkd3d_shader_scan_dxbc(&compile_info->source, &scan_info, messages)) < 0) scan_descriptor_info.next = scan_info.next;
scan_info.next = &scan_descriptor_info;
if ((ret = vkd3d_shader_scan(&scan_info, messages)) < 0)
return ret; return ret;
if (!vkd3d_shader_message_context_init(&message_context, compile_info->log_level, compile_info->source_name)) if (!vkd3d_shader_message_context_init(&message_context, compile_info->log_level, compile_info->source_name))
@ -317,15 +321,19 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
} }
vkd3d_shader_message_context_cleanup(&message_context); vkd3d_shader_message_context_cleanup(&message_context);
if (ret < 0) if (ret < 0)
{
vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
return ret; return ret;
}
vkd3d_shader_dump_shader(parser.shader_version.type, &compile_info->source); vkd3d_shader_dump_shader(parser.shader_version.type, &compile_info->source);
if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&parser.shader_version, if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&parser.shader_version,
&parser.shader_desc, compile_info, &scan_info))) &parser.shader_desc, compile_info, &scan_descriptor_info)))
{ {
ERR("Failed to create DXBC compiler.\n"); ERR("Failed to create DXBC compiler.\n");
vkd3d_shader_parser_destroy(&parser); vkd3d_shader_parser_destroy(&parser);
vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
return VKD3D_ERROR; return VKD3D_ERROR;
} }
@ -336,9 +344,8 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
if (instruction.handler_idx == VKD3DSIH_INVALID) if (instruction.handler_idx == VKD3DSIH_INVALID)
{ {
WARN("Encountered unrecognized or invalid instruction.\n"); WARN("Encountered unrecognized or invalid instruction.\n");
vkd3d_dxbc_compiler_destroy(spirv_compiler); ret = VKD3D_ERROR_INVALID_SHADER;
vkd3d_shader_parser_destroy(&parser); break;
return VKD3D_ERROR_INVALID_ARGUMENT;
} }
if ((ret = vkd3d_dxbc_compiler_handle_instruction(spirv_compiler, &instruction)) < 0) if ((ret = vkd3d_dxbc_compiler_handle_instruction(spirv_compiler, &instruction)) < 0)
@ -350,13 +357,13 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
vkd3d_dxbc_compiler_destroy(spirv_compiler); vkd3d_dxbc_compiler_destroy(spirv_compiler);
vkd3d_shader_parser_destroy(&parser); vkd3d_shader_parser_destroy(&parser);
vkd3d_shader_free_scan_info(&scan_info); vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
return ret; return ret;
} }
struct vkd3d_shader_scan_context struct vkd3d_shader_scan_context
{ {
struct vkd3d_shader_scan_info *scan_info; struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
size_t descriptors_size; size_t descriptors_size;
struct vkd3d_shader_message_context message_context; struct vkd3d_shader_message_context message_context;
@ -385,11 +392,12 @@ struct vkd3d_shader_scan_context
}; };
static bool vkd3d_shader_scan_context_init(struct vkd3d_shader_scan_context *context, static bool vkd3d_shader_scan_context_init(struct vkd3d_shader_scan_context *context,
struct vkd3d_shader_scan_info *scan_info) struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info,
enum vkd3d_shader_log_level log_level, const char *source_name)
{ {
memset(context, 0, sizeof(*context)); memset(context, 0, sizeof(*context));
context->scan_info = scan_info; context->scan_descriptor_info = scan_descriptor_info;
return vkd3d_shader_message_context_init(&context->message_context, VKD3D_SHADER_LOG_INFO, NULL); return vkd3d_shader_message_context_init(&context->message_context, log_level, source_name);
} }
static void vkd3d_shader_scan_context_cleanup(struct vkd3d_shader_scan_context *context) static void vkd3d_shader_scan_context_cleanup(struct vkd3d_shader_scan_context *context)
@ -471,7 +479,7 @@ static struct vkd3d_shader_descriptor_info *vkd3d_shader_scan_get_uav_descriptor
for (i = 0; i < context->uav_range_count; ++i) for (i = 0; i < context->uav_range_count; ++i)
{ {
if (context->uav_ranges[i].id == range_id) if (context->uav_ranges[i].id == range_id)
return &context->scan_info->descriptors[context->uav_ranges[i].descriptor_idx]; return &context->scan_descriptor_info->descriptors[context->uav_ranges[i].descriptor_idx];
} }
return NULL; return NULL;
@ -492,7 +500,7 @@ static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_context *
{ {
struct vkd3d_shader_descriptor_info *d; struct vkd3d_shader_descriptor_info *d;
if (!context->scan_info) if (!context->scan_descriptor_info)
return; return;
d = vkd3d_shader_scan_get_uav_descriptor_info(context, reg->idx[0].offset); d = vkd3d_shader_scan_get_uav_descriptor_info(context, reg->idx[0].offset);
@ -511,7 +519,7 @@ static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_contex
{ {
struct vkd3d_shader_descriptor_info *d; struct vkd3d_shader_descriptor_info *d;
if (!context->scan_info) if (!context->scan_descriptor_info)
return; return;
d = vkd3d_shader_scan_get_uav_descriptor_info(context, reg->idx[0].offset); d = vkd3d_shader_scan_get_uav_descriptor_info(context, reg->idx[0].offset);
@ -523,17 +531,17 @@ static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *c
enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_resource_data_type resource_data_type, enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_resource_data_type resource_data_type,
unsigned int flags) unsigned int flags)
{ {
struct vkd3d_shader_scan_info *scan_info = context->scan_info; struct vkd3d_shader_scan_descriptor_info *info = context->scan_descriptor_info;
struct vkd3d_shader_descriptor_info *d; struct vkd3d_shader_descriptor_info *d;
if (!vkd3d_array_reserve((void **)&scan_info->descriptors, &context->descriptors_size, if (!vkd3d_array_reserve((void **)&info->descriptors, &context->descriptors_size,
scan_info->descriptor_count + 1, sizeof(*scan_info->descriptors))) info->descriptor_count + 1, sizeof(*info->descriptors)))
{ {
ERR("Failed to allocate descriptor info.\n"); ERR("Failed to allocate descriptor info.\n");
return false; return false;
} }
d = &scan_info->descriptors[scan_info->descriptor_count]; d = &info->descriptors[info->descriptor_count];
d->type = type; d->type = type;
d->register_space = register_space; d->register_space = register_space;
d->register_index = register_index; d->register_index = register_index;
@ -541,7 +549,7 @@ static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *c
d->resource_data_type = resource_data_type; d->resource_data_type = resource_data_type;
d->flags = flags; d->flags = flags;
d->count = 1; d->count = 1;
++scan_info->descriptor_count; ++info->descriptor_count;
return true; return true;
} }
@ -568,7 +576,7 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc
{ {
const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb; const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb;
if (!context->scan_info) if (!context->scan_descriptor_info)
return; return;
vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, cb->register_space, vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, cb->register_space,
@ -581,7 +589,7 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte
const struct vkd3d_shader_sampler *sampler = &instruction->declaration.sampler; const struct vkd3d_shader_sampler *sampler = &instruction->declaration.sampler;
unsigned int flags; unsigned int flags;
if (!context->scan_info) if (!context->scan_descriptor_info)
return; return;
if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE) if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE)
@ -598,7 +606,7 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont
{ {
enum vkd3d_shader_descriptor_type type; enum vkd3d_shader_descriptor_type type;
if (!context->scan_info) if (!context->scan_descriptor_info)
return; return;
if (resource->reg.reg.type == VKD3DSPR_UAV) if (resource->reg.reg.type == VKD3DSPR_UAV)
@ -609,7 +617,7 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont
resource->register_index, resource_type, resource_data_type, 0); resource->register_index, resource_type, resource_data_type, 0);
if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV)
vkd3d_shader_scan_add_uav_range(context, resource->reg.reg.idx[0].offset, vkd3d_shader_scan_add_uav_range(context, resource->reg.reg.idx[0].offset,
context->scan_info->descriptor_count - 1); context->scan_descriptor_info->descriptor_count - 1);
} }
static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_scan_context *context, static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_scan_context *context,
@ -811,31 +819,44 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
return VKD3D_OK; return VKD3D_OK;
} }
int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc, int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages)
struct vkd3d_shader_scan_info *scan_info, char **messages)
{ {
struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
struct vkd3d_shader_message_context *message_context; struct vkd3d_shader_message_context *message_context;
struct vkd3d_shader_instruction instruction; struct vkd3d_shader_instruction instruction;
struct vkd3d_shader_scan_context context; struct vkd3d_shader_scan_context context;
struct vkd3d_shader_parser parser; struct vkd3d_shader_parser parser;
int ret; int ret;
TRACE("dxbc {%p, %zu}, scan_info %p, messages %p.\n", dxbc->code, dxbc->size, scan_info, messages); TRACE("compile_info %p, messages %p.\n", compile_info, messages);
if (messages) if (messages)
*messages = NULL; *messages = NULL;
if (scan_info->type != VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO) if (compile_info->type != VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO)
{ {
WARN("Invalid structure type %#x.\n", scan_info->type); WARN("Invalid structure type %#x.\n", compile_info->type);
return VKD3D_ERROR_INVALID_ARGUMENT; return VKD3D_ERROR_INVALID_ARGUMENT;
} }
if (!vkd3d_shader_scan_context_init(&context, scan_info)) if (compile_info->source_type != VKD3D_SHADER_SOURCE_DXBC_TPF)
{
WARN("Unsupported source type %#x.\n", compile_info->source_type);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
if ((scan_descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO)))
{
scan_descriptor_info->descriptors = NULL;
scan_descriptor_info->descriptor_count = 0;
}
if (!vkd3d_shader_scan_context_init(&context, scan_descriptor_info,
compile_info->log_level, compile_info->source_name))
return VKD3D_ERROR; return VKD3D_ERROR;
message_context = &context.message_context; message_context = &context.message_context;
if ((ret = vkd3d_shader_parser_init(&parser, dxbc, message_context)) < 0) if ((ret = vkd3d_shader_parser_init(&parser, &compile_info->source, message_context)) < 0)
{ {
vkd3d_shader_message_context_trace_messages(message_context); vkd3d_shader_message_context_trace_messages(message_context);
if (messages && !(*messages = vkd3d_shader_message_context_copy_messages(message_context))) if (messages && !(*messages = vkd3d_shader_message_context_copy_messages(message_context)))
@ -847,8 +868,6 @@ int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
if (TRACE_ON()) if (TRACE_ON())
vkd3d_shader_trace(parser.data); vkd3d_shader_trace(parser.data);
memset(scan_info, 0, sizeof(*scan_info));
message_context->line = 2; /* Line 1 is the version token. */ message_context->line = 2; /* Line 1 is the version token. */
message_context->column = 1; message_context->column = 1;
while (!shader_sm4_is_end(parser.data, &parser.ptr)) while (!shader_sm4_is_end(parser.data, &parser.ptr))
@ -858,14 +877,14 @@ int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
if (instruction.handler_idx == VKD3DSIH_INVALID) if (instruction.handler_idx == VKD3DSIH_INVALID)
{ {
WARN("Encountered unrecognized or invalid instruction.\n"); WARN("Encountered unrecognized or invalid instruction.\n");
vkd3d_shader_free_scan_info(scan_info); vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info);
ret = VKD3D_ERROR_INVALID_SHADER; ret = VKD3D_ERROR_INVALID_SHADER;
goto done; goto done;
} }
if ((ret = vkd3d_shader_scan_instruction(&context, &instruction)) < 0) if ((ret = vkd3d_shader_scan_instruction(&context, &instruction)) < 0)
{ {
vkd3d_shader_free_scan_info(scan_info); vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info);
goto done; goto done;
} }
++message_context->line; ++message_context->line;
@ -882,12 +901,12 @@ done:
return ret; return ret;
} }
void vkd3d_shader_free_scan_info(struct vkd3d_shader_scan_info *scan_info) void vkd3d_shader_free_scan_descriptor_info(struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info)
{ {
if (!scan_info) if (!scan_descriptor_info)
return; return;
vkd3d_free(scan_info->descriptors); vkd3d_free(scan_descriptor_info->descriptors);
} }
void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *shader_code) void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *shader_code)

View File

@ -846,7 +846,7 @@ struct vkd3d_dxbc_compiler;
struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version, struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version,
const struct vkd3d_shader_desc *shader_desc, const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_desc *shader_desc, const struct vkd3d_shader_compile_info *compile_info,
const struct vkd3d_shader_scan_info *scan_info) DECLSPEC_HIDDEN; const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info) DECLSPEC_HIDDEN;
int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction) DECLSPEC_HIDDEN; const struct vkd3d_shader_instruction *instruction) DECLSPEC_HIDDEN;
int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler, int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler,
@ -941,6 +941,27 @@ static inline unsigned int vkd3d_compact_swizzle(unsigned int swizzle, unsigned
return compacted_swizzle; return compacted_swizzle;
} }
struct vkd3d_struct
{
enum vkd3d_shader_structure_type type;
const void *next;
};
#define vkd3d_find_struct(c, t) vkd3d_find_struct_(c, VKD3D_SHADER_STRUCTURE_TYPE_##t)
static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain,
enum vkd3d_shader_structure_type type)
{
while (chain)
{
if (chain->type == type)
return (void *)chain;
chain = chain->next;
}
return NULL;
}
#define VKD3D_DXBC_MAX_SOURCE_COUNT 6 #define VKD3D_DXBC_MAX_SOURCE_COUNT 6
#define VKD3D_DXBC_HEADER_SIZE (8 * sizeof(uint32_t)) #define VKD3D_DXBC_HEADER_SIZE (8 * sizeof(uint32_t))

View File

@ -1376,6 +1376,25 @@ static HRESULT create_shader_stage(struct d3d12_device *device,
return S_OK; return S_OK;
} }
static int vkd3d_scan_dxbc(const D3D12_SHADER_BYTECODE *code,
struct vkd3d_shader_scan_descriptor_info *descriptor_info)
{
struct vkd3d_shader_compile_info compile_info;
compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
compile_info.next = descriptor_info;
compile_info.source.code = code->pShaderBytecode;
compile_info.source.size = code->BytecodeLength;
compile_info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
compile_info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
compile_info.options = NULL;
compile_info.option_count = 0;
compile_info.log_level = VKD3D_SHADER_LOG_NONE;
compile_info.source_name = NULL;
return vkd3d_shader_scan(&compile_info, NULL);
}
static HRESULT vkd3d_create_compute_pipeline(struct d3d12_device *device, static HRESULT vkd3d_create_compute_pipeline(struct d3d12_device *device,
const D3D12_SHADER_BYTECODE *code, const struct vkd3d_shader_interface_info *shader_interface, const D3D12_SHADER_BYTECODE *code, const struct vkd3d_shader_interface_info *shader_interface,
VkPipelineLayout vk_pipeline_layout, VkPipeline *vk_pipeline) VkPipelineLayout vk_pipeline_layout, VkPipeline *vk_pipeline)
@ -1409,7 +1428,7 @@ static HRESULT vkd3d_create_compute_pipeline(struct d3d12_device *device,
static HRESULT d3d12_pipeline_state_init_compute_uav_counters(struct d3d12_pipeline_state *state, static HRESULT d3d12_pipeline_state_init_compute_uav_counters(struct d3d12_pipeline_state *state,
struct d3d12_device *device, const struct d3d12_root_signature *root_signature, struct d3d12_device *device, const struct d3d12_root_signature *root_signature,
const struct vkd3d_shader_scan_info *shader_info) const struct vkd3d_shader_scan_descriptor_info *shader_info)
{ {
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
struct vkd3d_descriptor_set_context context; struct vkd3d_descriptor_set_context context;
@ -1503,11 +1522,10 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
struct d3d12_device *device, const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc) struct d3d12_device *device, const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc)
{ {
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
struct vkd3d_shader_scan_descriptor_info shader_info;
struct vkd3d_shader_interface_info shader_interface; struct vkd3d_shader_interface_info shader_interface;
const struct d3d12_root_signature *root_signature; const struct d3d12_root_signature *root_signature;
struct vkd3d_shader_scan_info shader_info;
VkPipelineLayout vk_pipeline_layout; VkPipelineLayout vk_pipeline_layout;
struct vkd3d_shader_code dxbc;
HRESULT hr; HRESULT hr;
int ret; int ret;
@ -1525,11 +1543,9 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
return E_INVALIDARG; return E_INVALIDARG;
} }
dxbc.code = desc->CS.pShaderBytecode; shader_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO;
dxbc.size = desc->CS.BytecodeLength;
shader_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO;
shader_info.next = NULL; shader_info.next = NULL;
if ((ret = vkd3d_shader_scan_dxbc(&dxbc, &shader_info, NULL)) < 0) if ((ret = vkd3d_scan_dxbc(&desc->CS, &shader_info)) < 0)
{ {
WARN("Failed to scan shader bytecode, vkd3d result %d.\n", ret); WARN("Failed to scan shader bytecode, vkd3d result %d.\n", ret);
return hresult_from_vkd3d_result(ret); return hresult_from_vkd3d_result(ret);
@ -1541,7 +1557,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); WARN("Failed to create descriptor set layout for UAV counters, hr %#x.\n", hr);
return hr; return hr;
} }
vkd3d_shader_free_scan_info(&shader_info); vkd3d_shader_free_scan_descriptor_info(&shader_info);
shader_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO; shader_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO;
shader_interface.next = NULL; shader_interface.next = NULL;
@ -2266,14 +2282,17 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
for (i = 0; i < ARRAY_SIZE(shader_stages); ++i) for (i = 0; i < ARRAY_SIZE(shader_stages); ++i)
{ {
struct vkd3d_shader_scan_descriptor_info shader_info =
{
.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO,
};
const D3D12_SHADER_BYTECODE *b = (const void *)((uintptr_t)desc + shader_stages[i].offset); const D3D12_SHADER_BYTECODE *b = (const void *)((uintptr_t)desc + shader_stages[i].offset);
struct vkd3d_shader_scan_info shader_info = {VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO};
const struct vkd3d_shader_code dxbc = {b->pShaderBytecode, b->BytecodeLength}; const struct vkd3d_shader_code dxbc = {b->pShaderBytecode, b->BytecodeLength};
if (!b->pShaderBytecode) if (!b->pShaderBytecode)
continue; continue;
if ((ret = vkd3d_shader_scan_dxbc(&dxbc, &shader_info, NULL)) < 0) if ((ret = vkd3d_scan_dxbc(b, &shader_info)) < 0)
{ {
WARN("Failed to scan shader bytecode, stage %#x, vkd3d result %d.\n", WARN("Failed to scan shader bytecode, stage %#x, vkd3d result %d.\n",
shader_stages[i].stage, ret); shader_stages[i].stage, ret);
@ -2291,7 +2310,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
break; break;
} }
} }
vkd3d_shader_free_scan_info(&shader_info); vkd3d_shader_free_scan_descriptor_info(&shader_info);
target_info = NULL; target_info = NULL;
switch (shader_stages[i].stage) switch (shader_stages[i].stage)

View File

@ -68,10 +68,14 @@ static void test_invalid_shaders(void)
rc = vkd3d_shader_compile(&info, &spirv, NULL); rc = vkd3d_shader_compile(&info, &spirv, NULL);
ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc); ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
rc = vkd3d_shader_scan(&info, NULL);
ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
} }
static void test_vkd3d_shader_pfns(void) static void test_vkd3d_shader_pfns(void)
{ {
PFN_vkd3d_shader_free_scan_descriptor_info pfn_vkd3d_shader_free_scan_descriptor_info;
PFN_vkd3d_shader_serialize_root_signature pfn_vkd3d_shader_serialize_root_signature; PFN_vkd3d_shader_serialize_root_signature pfn_vkd3d_shader_serialize_root_signature;
PFN_vkd3d_shader_find_signature_element pfn_vkd3d_shader_find_signature_element; PFN_vkd3d_shader_find_signature_element pfn_vkd3d_shader_find_signature_element;
PFN_vkd3d_shader_free_shader_signature pfn_vkd3d_shader_free_shader_signature; PFN_vkd3d_shader_free_shader_signature pfn_vkd3d_shader_free_shader_signature;
@ -79,13 +83,13 @@ static void test_vkd3d_shader_pfns(void)
PFN_vkd3d_shader_parse_root_signature pfn_vkd3d_shader_parse_root_signature; PFN_vkd3d_shader_parse_root_signature pfn_vkd3d_shader_parse_root_signature;
PFN_vkd3d_shader_free_root_signature pfn_vkd3d_shader_free_root_signature; PFN_vkd3d_shader_free_root_signature pfn_vkd3d_shader_free_root_signature;
PFN_vkd3d_shader_free_shader_code pfn_vkd3d_shader_free_shader_code; PFN_vkd3d_shader_free_shader_code pfn_vkd3d_shader_free_shader_code;
PFN_vkd3d_shader_scan_dxbc pfn_vkd3d_shader_scan_dxbc;
PFN_vkd3d_shader_compile pfn_vkd3d_shader_compile; PFN_vkd3d_shader_compile pfn_vkd3d_shader_compile;
PFN_vkd3d_shader_scan pfn_vkd3d_shader_scan;
struct vkd3d_shader_versioned_root_signature_desc root_signature_desc; struct vkd3d_shader_versioned_root_signature_desc root_signature_desc;
struct vkd3d_shader_scan_descriptor_info descriptor_info;
struct vkd3d_shader_signature_element *element; struct vkd3d_shader_signature_element *element;
struct vkd3d_shader_compile_info compile_info; struct vkd3d_shader_compile_info compile_info;
struct vkd3d_shader_scan_info scan_info;
struct vkd3d_shader_signature signature; struct vkd3d_shader_signature signature;
struct vkd3d_shader_code dxbc, spirv; struct vkd3d_shader_code dxbc, spirv;
int rc; int rc;
@ -112,6 +116,7 @@ static void test_vkd3d_shader_pfns(void)
}; };
static const struct vkd3d_shader_code vs = {vs_code, sizeof(vs_code)}; static const struct vkd3d_shader_code vs = {vs_code, sizeof(vs_code)};
pfn_vkd3d_shader_free_scan_descriptor_info = vkd3d_shader_free_scan_descriptor_info;
pfn_vkd3d_shader_serialize_root_signature = vkd3d_shader_serialize_root_signature; pfn_vkd3d_shader_serialize_root_signature = vkd3d_shader_serialize_root_signature;
pfn_vkd3d_shader_find_signature_element = vkd3d_shader_find_signature_element; pfn_vkd3d_shader_find_signature_element = vkd3d_shader_find_signature_element;
pfn_vkd3d_shader_free_shader_signature = vkd3d_shader_free_shader_signature; pfn_vkd3d_shader_free_shader_signature = vkd3d_shader_free_shader_signature;
@ -119,8 +124,8 @@ static void test_vkd3d_shader_pfns(void)
pfn_vkd3d_shader_parse_root_signature = vkd3d_shader_parse_root_signature; pfn_vkd3d_shader_parse_root_signature = vkd3d_shader_parse_root_signature;
pfn_vkd3d_shader_free_root_signature = vkd3d_shader_free_root_signature; pfn_vkd3d_shader_free_root_signature = vkd3d_shader_free_root_signature;
pfn_vkd3d_shader_free_shader_code = vkd3d_shader_free_shader_code; pfn_vkd3d_shader_free_shader_code = vkd3d_shader_free_shader_code;
pfn_vkd3d_shader_scan_dxbc = vkd3d_shader_scan_dxbc;
pfn_vkd3d_shader_compile = vkd3d_shader_compile; pfn_vkd3d_shader_compile = vkd3d_shader_compile;
pfn_vkd3d_shader_scan = vkd3d_shader_scan;
rc = pfn_vkd3d_shader_serialize_root_signature(&empty_rs_desc, &dxbc); rc = pfn_vkd3d_shader_serialize_root_signature(&empty_rs_desc, &dxbc);
ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc); ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
@ -149,10 +154,13 @@ static void test_vkd3d_shader_pfns(void)
ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc); ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
pfn_vkd3d_shader_free_shader_code(&spirv); pfn_vkd3d_shader_free_shader_code(&spirv);
memset(&scan_info, 0, sizeof(scan_info)); memset(&descriptor_info, 0, sizeof(descriptor_info));
scan_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO; descriptor_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO;
rc = pfn_vkd3d_shader_scan_dxbc(&vs, &scan_info, NULL); compile_info.next = &descriptor_info;
rc = pfn_vkd3d_shader_scan(&compile_info, NULL);
ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc); ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
pfn_vkd3d_shader_free_scan_descriptor_info(&descriptor_info);
} }
START_TEST(vkd3d_shader_api) START_TEST(vkd3d_shader_api)