Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- libs/vkd3d-shader/dxbc.c | 182 ++++++++++++----------- libs/vkd3d-shader/glsl.c | 4 +- libs/vkd3d-shader/trace.c | 6 +- libs/vkd3d-shader/vkd3d_shader_main.c | 18 +-- libs/vkd3d-shader/vkd3d_shader_private.h | 39 ++++- 5 files changed, 138 insertions(+), 111 deletions(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 656c982c..44e842d3 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -960,90 +960,7 @@ static enum vkd3d_data_type map_data_type(char t) } }
-static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t *byte_code, - size_t byte_code_size, const char *source_name, const struct vkd3d_shader_signature *output_signature, - struct vkd3d_shader_message_context *message_context) -{ - struct vkd3d_shader_version version; - uint32_t version_token, token_count; - unsigned int i; - - if (byte_code_size / sizeof(*byte_code) < 2) - { - WARN("Invalid byte code size %lu.\n", (long)byte_code_size); - return false; - } - - version_token = byte_code[0]; - TRACE("Version: 0x%08x.\n", version_token); - token_count = byte_code[1]; - TRACE("Token count: %u.\n", token_count); - - if (token_count < 2 || byte_code_size / sizeof(*byte_code) < token_count) - { - WARN("Invalid token count %u.\n", token_count); - return false; - } - - sm4->start = &byte_code[2]; - sm4->end = &byte_code[token_count]; - - switch (version_token >> 16) - { - case VKD3D_SM4_PS: - version.type = VKD3D_SHADER_TYPE_PIXEL; - break; - - case VKD3D_SM4_VS: - version.type = VKD3D_SHADER_TYPE_VERTEX; - break; - - case VKD3D_SM4_GS: - version.type = VKD3D_SHADER_TYPE_GEOMETRY; - break; - - case VKD3D_SM5_HS: - version.type = VKD3D_SHADER_TYPE_HULL; - break; - - case VKD3D_SM5_DS: - version.type = VKD3D_SHADER_TYPE_DOMAIN; - break; - - case VKD3D_SM5_CS: - version.type = VKD3D_SHADER_TYPE_COMPUTE; - break; - - default: - FIXME("Unrecognised shader type %#x.\n", version_token >> 16); - } - version.major = VKD3D_SM4_VERSION_MAJOR(version_token); - version.minor = VKD3D_SM4_VERSION_MINOR(version_token); - - vkd3d_shader_parser_init(&sm4->p, message_context, source_name, &version); - sm4->p.ptr = sm4->start; - - memset(sm4->output_map, 0xff, sizeof(sm4->output_map)); - for (i = 0; i < output_signature->element_count; ++i) - { - struct vkd3d_shader_signature_element *e = &output_signature->elements[i]; - - if (e->register_index >= ARRAY_SIZE(sm4->output_map)) - { - WARN("Invalid output index %u.\n", e->register_index); - continue; - } - - sm4->output_map[e->register_index] = e->semantic_index; - } - - list_init(&sm4->src_free); - list_init(&sm4->src); - - return true; -} - -void shader_sm4_free(struct vkd3d_shader_parser *parser) +static void shader_sm4_destroy(struct vkd3d_shader_parser *parser) { struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser); struct vkd3d_shader_src_param_entry *e1, *e2; @@ -1521,7 +1438,7 @@ 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) +static void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins) { struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser); const struct vkd3d_sm4_opcode_info *opcode_info; @@ -1643,14 +1560,14 @@ fail: return; }
-bool shader_sm4_is_end(struct vkd3d_shader_parser *parser) +static bool shader_sm4_is_end(struct vkd3d_shader_parser *parser) { struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser);
return parser->ptr == sm4->end; }
-void shader_sm4_reset(struct vkd3d_shader_parser *parser) +static void shader_sm4_reset(struct vkd3d_shader_parser *parser) { struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser);
@@ -1658,6 +1575,97 @@ void shader_sm4_reset(struct vkd3d_shader_parser *parser) parser->failed = false; }
+static const struct vkd3d_shader_parser_ops shader_sm4_parser_ops = +{ + .parser_reset = shader_sm4_reset, + .parser_destroy = shader_sm4_destroy, + .parser_read_instruction = shader_sm4_read_instruction, + .parser_is_end = shader_sm4_is_end, +}; + +static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t *byte_code, + size_t byte_code_size, const char *source_name, const struct vkd3d_shader_signature *output_signature, + struct vkd3d_shader_message_context *message_context) +{ + struct vkd3d_shader_version version; + uint32_t version_token, token_count; + unsigned int i; + + if (byte_code_size / sizeof(*byte_code) < 2) + { + WARN("Invalid byte code size %lu.\n", (long)byte_code_size); + return false; + } + + version_token = byte_code[0]; + TRACE("Version: 0x%08x.\n", version_token); + token_count = byte_code[1]; + TRACE("Token count: %u.\n", token_count); + + if (token_count < 2 || byte_code_size / sizeof(*byte_code) < token_count) + { + WARN("Invalid token count %u.\n", token_count); + return false; + } + + sm4->start = &byte_code[2]; + sm4->end = &byte_code[token_count]; + + switch (version_token >> 16) + { + case VKD3D_SM4_PS: + version.type = VKD3D_SHADER_TYPE_PIXEL; + break; + + case VKD3D_SM4_VS: + version.type = VKD3D_SHADER_TYPE_VERTEX; + break; + + case VKD3D_SM4_GS: + version.type = VKD3D_SHADER_TYPE_GEOMETRY; + break; + + case VKD3D_SM5_HS: + version.type = VKD3D_SHADER_TYPE_HULL; + break; + + case VKD3D_SM5_DS: + version.type = VKD3D_SHADER_TYPE_DOMAIN; + break; + + case VKD3D_SM5_CS: + version.type = VKD3D_SHADER_TYPE_COMPUTE; + break; + + default: + FIXME("Unrecognised shader type %#x.\n", version_token >> 16); + } + version.major = VKD3D_SM4_VERSION_MAJOR(version_token); + version.minor = VKD3D_SM4_VERSION_MINOR(version_token); + + vkd3d_shader_parser_init(&sm4->p, message_context, source_name, &version, &shader_sm4_parser_ops); + sm4->p.ptr = sm4->start; + + memset(sm4->output_map, 0xff, sizeof(sm4->output_map)); + for (i = 0; i < output_signature->element_count; ++i) + { + struct vkd3d_shader_signature_element *e = &output_signature->elements[i]; + + if (e->register_index >= ARRAY_SIZE(sm4->output_map)) + { + WARN("Invalid output index %u.\n", e->register_index); + continue; + } + + sm4->output_map[e->register_index] = e->semantic_index; + } + + list_init(&sm4->src_free); + list_init(&sm4->src); + + return true; +} + 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) { diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c index b90a5d91..56fa7043 100644 --- a/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d-shader/glsl.c @@ -99,9 +99,9 @@ int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *generator, vkd3d_string_buffer_printf(&generator->buffer, "#version 440\n\n"); vkd3d_string_buffer_printf(&generator->buffer, "void main()\n{\n");
- while (!shader_sm4_is_end(parser)) + while (!vkd3d_shader_parser_is_end(parser)) { - shader_sm4_read_instruction(parser, &ins); + vkd3d_shader_parser_read_instruction(parser, &ins);
if (ins.handler_idx == VKD3DSIH_INVALID) { diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c index 57104246..edba0b42 100644 --- a/libs/vkd3d-shader/trace.c +++ b/libs/vkd3d-shader/trace.c @@ -1889,12 +1889,12 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(struct vkd3d_shader_parser *parser, shader_version->minor, compiler.colours.reset);
indent = 0; - shader_sm4_reset(parser); - while (!shader_sm4_is_end(parser)) + vkd3d_shader_parser_reset(parser); + while (!vkd3d_shader_parser_is_end(parser)) { struct vkd3d_shader_instruction ins;
- shader_sm4_read_instruction(parser, &ins); + vkd3d_shader_parser_read_instruction(parser, &ins); if (ins.handler_idx == VKD3DSIH_INVALID) { WARN("Skipping unrecognized instruction.\n"); diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index c30a3757..98607154 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -364,18 +364,14 @@ void vkd3d_shader_dump_shader(enum vkd3d_shader_source_type source_type,
void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vkd3d_shader_message_context *message_context, const char *source_name, - const struct vkd3d_shader_version *version) + const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops) { parser->message_context = message_context; parser->location.source_name = source_name; parser->location.line = 1; parser->location.column = 0; parser->shader_version = *version; -} - -static void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser) -{ - shader_sm4_free(parser); + parser->ops = ops; }
void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, @@ -946,12 +942,12 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info, if (TRACE_ON()) { vkd3d_shader_trace(parser); - shader_sm4_reset(parser); + vkd3d_shader_parser_reset(parser); }
- while (!shader_sm4_is_end(parser)) + while (!vkd3d_shader_parser_is_end(parser)) { - shader_sm4_read_instruction(parser, &instruction); + vkd3d_shader_parser_read_instruction(parser, &instruction);
if (instruction.handler_idx == VKD3DSIH_INVALID) { @@ -1081,9 +1077,9 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info return VKD3D_ERROR; }
- while (!shader_sm4_is_end(parser)) + while (!vkd3d_shader_parser_is_end(parser)) { - shader_sm4_read_instruction(parser, &instruction); + vkd3d_shader_parser_read_instruction(parser, &instruction);
if (instruction.handler_idx == VKD3DSIH_INVALID) { diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 97048ea6..da12247a 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -902,24 +902,47 @@ struct vkd3d_shader_parser struct vkd3d_shader_desc shader_desc; struct vkd3d_shader_version shader_version; const uint32_t *ptr; + const struct vkd3d_shader_parser_ops *ops; +}; + +struct vkd3d_shader_parser_ops +{ + void (*parser_reset)(struct vkd3d_shader_parser *parser); + void (*parser_destroy)(struct vkd3d_shader_parser *parser); + void (*parser_read_instruction)(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *instruction); + bool (*parser_is_end)(struct vkd3d_shader_parser *parser); };
void vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vkd3d_shader_message_context *message_context, const char *source_name, - const struct vkd3d_shader_version *version); + const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops);
-void vkd3d_shader_trace(struct vkd3d_shader_parser *parser); +static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser) +{ + parser->ops->parser_destroy(parser); +}
-const char *shader_get_type_prefix(enum vkd3d_shader_type type); +static inline bool vkd3d_shader_parser_is_end(struct vkd3d_shader_parser *parser) +{ + return parser->ops->parser_is_end(parser); +}
-struct vkd3d_shader_message_context; +static inline void vkd3d_shader_parser_read_instruction(struct vkd3d_shader_parser *parser, + struct vkd3d_shader_instruction *instruction) +{ + parser->ops->parser_read_instruction(parser, instruction); +} + +static inline void vkd3d_shader_parser_reset(struct vkd3d_shader_parser *parser) +{ + parser->ops->parser_reset(parser); +} + +void vkd3d_shader_trace(struct vkd3d_shader_parser *parser);
-void shader_sm4_free(struct vkd3d_shader_parser *parser); -void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins); -bool shader_sm4_is_end(struct vkd3d_shader_parser *parser); -void shader_sm4_reset(struct vkd3d_shader_parser *parser); +const char *shader_get_type_prefix(enum vkd3d_shader_type type);
struct vkd3d_string_buffer {