vkd3d-shader/sm4: Store a vkd3d_shader_parser structure in the vkd3d_sm4_data structure.

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Henri Verbeet 2021-10-01 17:51:11 +02:00 committed by Alexandre Julliard
parent 49eba71844
commit 88c8d11805
3 changed files with 95 additions and 84 deletions

View File

@ -99,6 +99,7 @@ struct vkd3d_sm4_data
struct vkd3d_shader_immediate_constant_buffer icb; struct vkd3d_shader_immediate_constant_buffer icb;
struct vkd3d_shader_message_context *message_context; struct vkd3d_shader_message_context *message_context;
struct vkd3d_shader_parser p;
}; };
struct vkd3d_sm4_opcode_info struct vkd3d_sm4_opcode_info
@ -165,6 +166,11 @@ static const enum vkd3d_data_type data_type_table[] =
/* VKD3D_SM4_DATA_UNUSED */ VKD3D_DATA_UNUSED, /* VKD3D_SM4_DATA_UNUSED */ VKD3D_DATA_UNUSED,
}; };
static struct vkd3d_sm4_data *vkd3d_sm4_data(struct vkd3d_shader_parser *parser)
{
return CONTAINING_RECORD(parser, struct vkd3d_sm4_data, p);
}
static bool shader_is_sm_5_1(const struct vkd3d_sm4_data *priv) static bool shader_is_sm_5_1(const struct vkd3d_sm4_data *priv)
{ {
const struct vkd3d_shader_version *version = &priv->shader_version; const struct vkd3d_shader_version *version = &priv->shader_version;
@ -998,17 +1004,16 @@ static enum vkd3d_data_type map_data_type(char t)
} }
} }
void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size, static bool shader_sm4_init(struct vkd3d_sm4_data *sm4, const uint32_t *byte_code, size_t byte_code_size,
const struct vkd3d_shader_signature *output_signature, struct vkd3d_shader_message_context *message_context) const struct vkd3d_shader_signature *output_signature, struct vkd3d_shader_message_context *message_context)
{ {
DWORD version_token, token_count; uint32_t version_token, token_count;
struct vkd3d_sm4_data *priv;
unsigned int i; unsigned int i;
if (byte_code_size / sizeof(*byte_code) < 2) if (byte_code_size / sizeof(*byte_code) < 2)
{ {
WARN("Invalid byte code size %lu.\n", (long)byte_code_size); WARN("Invalid byte code size %lu.\n", (long)byte_code_size);
return NULL; return false;
} }
version_token = byte_code[0]; version_token = byte_code[0];
@ -1019,82 +1024,77 @@ void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size,
if (token_count < 2 || byte_code_size / sizeof(*byte_code) < token_count) if (token_count < 2 || byte_code_size / sizeof(*byte_code) < token_count)
{ {
WARN("Invalid token count %u.\n", token_count); WARN("Invalid token count %u.\n", token_count);
return NULL; return false;
} }
if (!(priv = vkd3d_malloc(sizeof(*priv)))) sm4->start = &byte_code[2];
{ sm4->end = &byte_code[token_count];
ERR("Failed to allocate private data\n");
return NULL;
}
priv->start = &byte_code[2];
priv->end = &byte_code[token_count];
switch (version_token >> 16) switch (version_token >> 16)
{ {
case VKD3D_SM4_PS: case VKD3D_SM4_PS:
priv->shader_version.type = VKD3D_SHADER_TYPE_PIXEL; sm4->shader_version.type = VKD3D_SHADER_TYPE_PIXEL;
break; break;
case VKD3D_SM4_VS: case VKD3D_SM4_VS:
priv->shader_version.type = VKD3D_SHADER_TYPE_VERTEX; sm4->shader_version.type = VKD3D_SHADER_TYPE_VERTEX;
break; break;
case VKD3D_SM4_GS: case VKD3D_SM4_GS:
priv->shader_version.type = VKD3D_SHADER_TYPE_GEOMETRY; sm4->shader_version.type = VKD3D_SHADER_TYPE_GEOMETRY;
break; break;
case VKD3D_SM5_HS: case VKD3D_SM5_HS:
priv->shader_version.type = VKD3D_SHADER_TYPE_HULL; sm4->shader_version.type = VKD3D_SHADER_TYPE_HULL;
break; break;
case VKD3D_SM5_DS: case VKD3D_SM5_DS:
priv->shader_version.type = VKD3D_SHADER_TYPE_DOMAIN; sm4->shader_version.type = VKD3D_SHADER_TYPE_DOMAIN;
break; break;
case VKD3D_SM5_CS: case VKD3D_SM5_CS:
priv->shader_version.type = VKD3D_SHADER_TYPE_COMPUTE; sm4->shader_version.type = VKD3D_SHADER_TYPE_COMPUTE;
break; break;
default: default:
FIXME("Unrecognised shader type %#x.\n", version_token >> 16); FIXME("Unrecognised shader type %#x.\n", version_token >> 16);
} }
priv->shader_version.major = VKD3D_SM4_VERSION_MAJOR(version_token); sm4->shader_version.major = VKD3D_SM4_VERSION_MAJOR(version_token);
priv->shader_version.minor = VKD3D_SM4_VERSION_MINOR(version_token); sm4->shader_version.minor = VKD3D_SM4_VERSION_MINOR(version_token);
memset(priv->output_map, 0xff, sizeof(priv->output_map)); memset(sm4->output_map, 0xff, sizeof(sm4->output_map));
for (i = 0; i < output_signature->element_count; ++i) for (i = 0; i < output_signature->element_count; ++i)
{ {
struct vkd3d_shader_signature_element *e = &output_signature->elements[i]; struct vkd3d_shader_signature_element *e = &output_signature->elements[i];
if (e->register_index >= ARRAY_SIZE(priv->output_map)) if (e->register_index >= ARRAY_SIZE(sm4->output_map))
{ {
WARN("Invalid output index %u.\n", e->register_index); WARN("Invalid output index %u.\n", e->register_index);
continue; continue;
} }
priv->output_map[e->register_index] = e->semantic_index; sm4->output_map[e->register_index] = e->semantic_index;
} }
list_init(&priv->src_free); list_init(&sm4->src_free);
list_init(&priv->src); list_init(&sm4->src);
priv->message_context = message_context; sm4->message_context = message_context;
return priv; return true;
} }
void shader_sm4_free(struct vkd3d_shader_parser *parser) void shader_sm4_free(struct vkd3d_shader_parser *parser)
{ {
struct vkd3d_sm4_data *sm4 = vkd3d_sm4_data(parser);
struct vkd3d_shader_src_param_entry *e1, *e2; struct vkd3d_shader_src_param_entry *e1, *e2;
struct vkd3d_sm4_data *sm4 = parser->data;
list_move_head(&sm4->src_free, &sm4->src); list_move_head(&sm4->src_free, &sm4->src);
LIST_FOR_EACH_ENTRY_SAFE(e1, e2, &sm4->src_free, struct vkd3d_shader_src_param_entry, entry) LIST_FOR_EACH_ENTRY_SAFE(e1, e2, &sm4->src_free, struct vkd3d_shader_src_param_entry, entry)
{ {
vkd3d_free(e1); vkd3d_free(e1);
} }
free_shader_desc(&parser->shader_desc);
vkd3d_free(sm4); vkd3d_free(sm4);
} }
@ -1122,7 +1122,7 @@ static struct vkd3d_shader_src_param *get_src_param(struct vkd3d_sm4_data *priv)
void shader_sm4_read_header(struct vkd3d_shader_parser *parser, struct vkd3d_shader_version *shader_version) void shader_sm4_read_header(struct vkd3d_shader_parser *parser, struct vkd3d_shader_version *shader_version)
{ {
struct vkd3d_sm4_data *sm4 = parser->data; struct vkd3d_sm4_data *sm4 = vkd3d_sm4_data(parser);
parser->ptr = sm4->start; parser->ptr = sm4->start;
*shader_version = sm4->shader_version; *shader_version = sm4->shader_version;
@ -1573,9 +1573,9 @@ static void shader_sm4_read_instruction_modifier(DWORD modifier, struct vkd3d_sh
void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins) void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins)
{ {
struct vkd3d_sm4_data *sm4 = vkd3d_sm4_data(parser);
const struct vkd3d_sm4_opcode_info *opcode_info; const struct vkd3d_sm4_opcode_info *opcode_info;
uint32_t opcode_token, opcode, previous_token; uint32_t opcode_token, opcode, previous_token;
struct vkd3d_sm4_data *sm4 = parser->data;
const uint32_t **ptr = &parser->ptr; const uint32_t **ptr = &parser->ptr;
unsigned int i, len; unsigned int i, len;
size_t remaining; size_t remaining;
@ -1693,18 +1693,55 @@ fail:
bool shader_sm4_is_end(struct vkd3d_shader_parser *parser) bool shader_sm4_is_end(struct vkd3d_shader_parser *parser)
{ {
struct vkd3d_sm4_data *sm4 = parser->data; struct vkd3d_sm4_data *sm4 = vkd3d_sm4_data(parser);
return parser->ptr == sm4->end; return parser->ptr == sm4->end;
} }
void shader_sm4_reset(struct vkd3d_shader_parser *parser) void shader_sm4_reset(struct vkd3d_shader_parser *parser)
{ {
struct vkd3d_sm4_data *sm4 = parser->data; struct vkd3d_sm4_data *sm4 = vkd3d_sm4_data(parser);
parser->ptr = sm4->start; parser->ptr = sm4->start;
} }
int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser)
{
struct vkd3d_shader_desc *shader_desc;
struct vkd3d_sm4_data *sm4;
int ret;
if (!(sm4 = vkd3d_calloc(1, sizeof(*sm4))))
{
ERR("Failed to allocate parser.\n");
return VKD3D_ERROR_OUT_OF_MEMORY;
}
shader_desc = &sm4->p.shader_desc;
if ((ret = shader_extract_from_dxbc(compile_info->source.code, compile_info->source.size,
message_context, compile_info->source_name, shader_desc)) < 0)
{
WARN("Failed to extract shader, vkd3d result %d.\n", ret);
vkd3d_free(sm4);
return ret;
}
if (!shader_sm4_init(sm4, shader_desc->byte_code, shader_desc->byte_code_size,
&shader_desc->output_signature, message_context))
{
WARN("Failed to initialise shader parser.\n");
free_shader_desc(shader_desc);
vkd3d_free(sm4);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
shader_sm4_read_header(&sm4->p, &sm4->p.shader_version);
*parser = &sm4->p;
return VKD3D_OK;
}
static bool require_space(size_t offset, size_t count, size_t size, size_t data_size) static bool require_space(size_t offset, size_t count, size_t size, size_t data_size)
{ {
return !count || (data_size - offset) / count >= size; return !count || (data_size - offset) / count >= size;

View File

@ -362,35 +362,9 @@ void vkd3d_shader_dump_shader(enum vkd3d_shader_source_type source_type,
shader_get_source_type_suffix(source_type), shader->code, shader->size); shader_get_source_type_suffix(source_type), shader->code, shader->size);
} }
static int vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
{
struct vkd3d_shader_desc *shader_desc = &parser->shader_desc;
int ret;
if ((ret = shader_extract_from_dxbc(compile_info->source.code, compile_info->source.size,
message_context, compile_info->source_name, shader_desc)) < 0)
{
WARN("Failed to extract shader, vkd3d result %d.\n", ret);
return ret;
}
if (!(parser->data = shader_sm4_init(shader_desc->byte_code,
shader_desc->byte_code_size, &shader_desc->output_signature, message_context)))
{
WARN("Failed to initialize shader parser.\n");
free_shader_desc(shader_desc);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
shader_sm4_read_header(parser, &parser->shader_version);
return VKD3D_OK;
}
static void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser) static void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser)
{ {
shader_sm4_free(parser); shader_sm4_free(parser);
free_shader_desc(&parser->shader_desc);
} }
static int vkd3d_shader_validate_compile_info(const struct vkd3d_shader_compile_info *compile_info, static int vkd3d_shader_validate_compile_info(const struct vkd3d_shader_compile_info *compile_info,
@ -929,7 +903,7 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info; struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
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;
if ((scan_descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO))) if ((scan_descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO)))
@ -940,7 +914,7 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
vkd3d_shader_scan_context_init(&context, compile_info, scan_descriptor_info, message_context); vkd3d_shader_scan_context_init(&context, compile_info, scan_descriptor_info, message_context);
if ((ret = vkd3d_shader_parser_init(&parser, compile_info, message_context)) < 0) if ((ret = vkd3d_shader_sm4_parser_create(compile_info, message_context, &parser)) < 0)
{ {
vkd3d_shader_scan_context_cleanup(&context); vkd3d_shader_scan_context_cleanup(&context);
return ret; return ret;
@ -948,13 +922,13 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
if (TRACE_ON()) if (TRACE_ON())
{ {
vkd3d_shader_trace(&parser); vkd3d_shader_trace(parser);
shader_sm4_reset(&parser); shader_sm4_reset(parser);
} }
while (!shader_sm4_is_end(&parser)) while (!shader_sm4_is_end(parser))
{ {
shader_sm4_read_instruction(&parser, &instruction); shader_sm4_read_instruction(parser, &instruction);
if (instruction.handler_idx == VKD3DSIH_INVALID) if (instruction.handler_idx == VKD3DSIH_INVALID)
{ {
@ -977,7 +951,7 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
done: done:
vkd3d_shader_scan_context_cleanup(&context); vkd3d_shader_scan_context_cleanup(&context);
vkd3d_shader_parser_destroy(&parser); vkd3d_shader_parser_destroy(parser);
return ret; return ret;
} }
@ -1027,7 +1001,7 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
struct vkd3d_shader_instruction instruction; struct vkd3d_shader_instruction instruction;
struct vkd3d_shader_compile_info scan_info; struct vkd3d_shader_compile_info scan_info;
struct vkd3d_dxbc_compiler *spirv_compiler; struct vkd3d_dxbc_compiler *spirv_compiler;
struct vkd3d_shader_parser parser; struct vkd3d_shader_parser *parser;
int ret; int ret;
scan_info = *compile_info; scan_info = *compile_info;
@ -1038,19 +1012,19 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
if ((ret = scan_dxbc(&scan_info, message_context)) < 0) if ((ret = scan_dxbc(&scan_info, message_context)) < 0)
return ret; return ret;
if ((ret = vkd3d_shader_parser_init(&parser, compile_info, message_context)) < 0) if ((ret = vkd3d_shader_sm4_parser_create(compile_info, message_context, &parser)) < 0)
{ {
vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info); vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
return ret; return ret;
} }
vkd3d_shader_dump_shader(compile_info->source_type, parser.shader_version.type, &compile_info->source); vkd3d_shader_dump_shader(compile_info->source_type, parser->shader_version.type, &compile_info->source);
if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_ASM) if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_ASM)
{ {
vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info); vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
ret = vkd3d_dxbc_binary_to_text(&parser, compile_info, out); ret = vkd3d_dxbc_binary_to_text(parser, compile_info, out);
vkd3d_shader_parser_destroy(&parser); vkd3d_shader_parser_destroy(parser);
return ret; return ret;
} }
@ -1058,34 +1032,34 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
{ {
struct vkd3d_glsl_generator *glsl_generator; struct vkd3d_glsl_generator *glsl_generator;
if (!(glsl_generator = vkd3d_glsl_generator_create(&parser.shader_version, compile_info, message_context))) if (!(glsl_generator = vkd3d_glsl_generator_create(&parser->shader_version, compile_info, message_context)))
{ {
ERR("Failed to create GLSL generator.\n"); ERR("Failed to create GLSL generator.\n");
vkd3d_shader_parser_destroy(&parser); vkd3d_shader_parser_destroy(parser);
vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info); vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
return VKD3D_ERROR; return VKD3D_ERROR;
} }
ret = vkd3d_glsl_generator_generate(glsl_generator, &parser, out); ret = vkd3d_glsl_generator_generate(glsl_generator, parser, out);
vkd3d_glsl_generator_destroy(glsl_generator); vkd3d_glsl_generator_destroy(glsl_generator);
vkd3d_shader_parser_destroy(&parser); vkd3d_shader_parser_destroy(parser);
vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info); vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
return ret; return ret;
} }
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_descriptor_info, message_context))) &parser->shader_desc, compile_info, &scan_descriptor_info, message_context)))
{ {
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); vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
return VKD3D_ERROR; return VKD3D_ERROR;
} }
while (!shader_sm4_is_end(&parser)) while (!shader_sm4_is_end(parser))
{ {
shader_sm4_read_instruction(&parser, &instruction); shader_sm4_read_instruction(parser, &instruction);
if (instruction.handler_idx == VKD3DSIH_INVALID) if (instruction.handler_idx == VKD3DSIH_INVALID)
{ {
@ -1102,7 +1076,7 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
ret = vkd3d_dxbc_compiler_generate_spirv(spirv_compiler, compile_info, out); ret = vkd3d_dxbc_compiler_generate_spirv(spirv_compiler, compile_info, out);
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_descriptor_info(&scan_descriptor_info); vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
return ret; return ret;
} }

View File

@ -891,7 +891,6 @@ struct vkd3d_shader_parser
{ {
struct vkd3d_shader_desc shader_desc; struct vkd3d_shader_desc shader_desc;
struct vkd3d_shader_version shader_version; struct vkd3d_shader_version shader_version;
void *data;
const uint32_t *ptr; const uint32_t *ptr;
}; };
@ -901,8 +900,6 @@ const char *shader_get_type_prefix(enum vkd3d_shader_type type);
struct vkd3d_shader_message_context; struct vkd3d_shader_message_context;
void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size,
const struct vkd3d_shader_signature *output_signature, struct vkd3d_shader_message_context *message_context);
void shader_sm4_free(struct vkd3d_shader_parser *parser); void shader_sm4_free(struct vkd3d_shader_parser *parser);
void shader_sm4_read_header(struct vkd3d_shader_parser *parser, struct vkd3d_shader_version *shader_version); void shader_sm4_read_header(struct vkd3d_shader_parser *parser, struct vkd3d_shader_version *shader_version);
void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins); void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins);
@ -1000,6 +997,9 @@ void vkd3d_shader_trace_text_(const char *text, size_t size, const char *functio
#define vkd3d_shader_trace_text(text, size) \ #define vkd3d_shader_trace_text(text, size) \
vkd3d_shader_trace_text_(text, size, __FUNCTION__) vkd3d_shader_trace_text_(text, size, __FUNCTION__)
int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
int shader_extract_from_dxbc(const void *dxbc, size_t dxbc_length, int shader_extract_from_dxbc(const void *dxbc, size_t dxbc_length,
struct vkd3d_shader_message_context *message_context, const char *source_name, struct vkd3d_shader_desc *desc); struct vkd3d_shader_message_context *message_context, const char *source_name, struct vkd3d_shader_desc *desc);
void free_shader_desc(struct vkd3d_shader_desc *desc); void free_shader_desc(struct vkd3d_shader_desc *desc);