Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 182 +++++++++++++++++++++++++++++++++++---- libs/vkd3d-shader/hlsl.h | 11 +-- libs/vkd3d-shader/hlsl.l | 5 +- libs/vkd3d-shader/hlsl.y | 153 ++------------------------------ 4 files changed, 180 insertions(+), 171 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 5ad4484d..e3d11108 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -328,6 +328,15 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_type *old, unsigned int default_ma return type; }
+bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type) +{ + if (hlsl_get_type(scope, type->name, false)) + return false; + + rb_put(&scope->types, type->name, &type->scope_entry); + return true; +} + struct hlsl_ir_expr *hlsl_new_cast(struct hlsl_ir_node *node, struct hlsl_type *type, struct source_location *loc) { @@ -622,19 +631,6 @@ static int compare_function_decl_rb(const void *key, const struct rb_entry *entr return 0; }
-static int compare_function_rb(const void *key, const struct rb_entry *entry) -{ - const char *name = key; - const struct hlsl_ir_function *func = RB_ENTRY_VALUE(entry, const struct hlsl_ir_function,entry); - - return strcmp(name, func->name); -} - -void init_functions_tree(struct rb_tree *funcs) -{ - rb_init(&hlsl_ctx.functions, compare_function_rb); -} - const char *hlsl_base_type_to_string(const struct hlsl_type *type) { const char *name = "(unknown)"; @@ -1230,7 +1226,7 @@ static void free_function(struct hlsl_ir_function *func) vkd3d_free(func); }
-void hlsl_free_function_rb(struct rb_entry *entry, void *context) +static void free_function_rb(struct rb_entry *entry, void *context) { free_function(RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry)); } @@ -1372,11 +1368,159 @@ static const struct hlsl_profile_info *get_target_info(const char *target) return NULL; }
+static int compare_function_rb(const void *key, const struct rb_entry *entry) +{ + const char *name = key; + const struct hlsl_ir_function *func = RB_ENTRY_VALUE(entry, const struct hlsl_ir_function,entry); + + return strcmp(name, func->name); +} + +static void declare_predefined_types(struct hlsl_scope *scope) +{ + struct hlsl_type *type; + unsigned int x, y, bt; + static const char * const names[] = + { + "float", + "half", + "double", + "int", + "uint", + "bool", + }; + char name[10]; + + static const char *const sampler_names[] = + { + "sampler", + "sampler1D", + "sampler2D", + "sampler3D", + "samplerCUBE" + }; + + for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt) + { + for (y = 1; y <= 4; ++y) + { + for (x = 1; x <= 4; ++x) + { + sprintf(name, "%s%ux%u", names[bt], y, x); + type = hlsl_new_type(vkd3d_strdup(name), HLSL_CLASS_MATRIX, bt, x, y); + hlsl_scope_add_type(scope, type); + + if (y == 1) + { + sprintf(name, "%s%u", names[bt], x); + type = hlsl_new_type(vkd3d_strdup(name), HLSL_CLASS_VECTOR, bt, x, y); + hlsl_scope_add_type(scope, type); + hlsl_ctx.builtin_types.vector[bt][x - 1] = type; + + if (x == 1) + { + sprintf(name, "%s", names[bt]); + type = hlsl_new_type(vkd3d_strdup(name), HLSL_CLASS_SCALAR, bt, x, y); + hlsl_scope_add_type(scope, type); + hlsl_ctx.builtin_types.scalar[bt] = type; + } + } + } + } + } + + for (bt = 0; bt <= HLSL_SAMPLER_DIM_MAX; ++bt) + { + type = hlsl_new_type(vkd3d_strdup(sampler_names[bt]), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); + type->sampler_dim = bt; + hlsl_ctx.builtin_types.sampler[bt] = type; + } + + hlsl_ctx.builtin_types.Void = hlsl_new_type(vkd3d_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1); + + /* DX8 effects predefined types */ + type = hlsl_new_type(vkd3d_strdup("DWORD"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1); + hlsl_scope_add_type(scope, type); + type = hlsl_new_type(vkd3d_strdup("FLOAT"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1); + hlsl_scope_add_type(scope, type); + type = hlsl_new_type(vkd3d_strdup("VECTOR"), HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1); + hlsl_scope_add_type(scope, type); + type = hlsl_new_type(vkd3d_strdup("MATRIX"), HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4); + hlsl_scope_add_type(scope, type); + type = hlsl_new_type(vkd3d_strdup("STRING"), HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1); + hlsl_scope_add_type(scope, type); + type = hlsl_new_type(vkd3d_strdup("TEXTURE"), HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1); + hlsl_scope_add_type(scope, type); + type = hlsl_new_type(vkd3d_strdup("PIXELSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1); + hlsl_scope_add_type(scope, type); + type = hlsl_new_type(vkd3d_strdup("VERTEXSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1); + hlsl_scope_add_type(scope, type); +} + +static bool hlsl_ctx_init(struct hlsl_parse_ctx *ctx, struct vkd3d_shader_message_context *message_context) +{ + memset(ctx, 0, sizeof(*ctx)); + + ctx->message_context = message_context; + + ctx->line_no = ctx->column = 1; + if (!(ctx->source_file = vkd3d_strdup(""))) + return false; + if (!(ctx->source_files = vkd3d_malloc(sizeof(*ctx->source_files)))) + { + vkd3d_free((void *)ctx->source_file); + return false; + } + ctx->source_files[0] = ctx->source_file; + ctx->source_files_count = 1; + + ctx->matrix_majority = HLSL_COLUMN_MAJOR; + + list_init(&ctx->scopes); + hlsl_push_scope(ctx); + ctx->globals = ctx->cur_scope; + + list_init(&ctx->types); + declare_predefined_types(ctx->globals); + + rb_init(&ctx->functions, compare_function_rb); + + list_init(&ctx->static_initializers); + + return true; +} + +static void hlsl_ctx_cleanup(struct hlsl_parse_ctx *ctx) +{ + struct hlsl_scope *scope, *next_scope; + struct hlsl_ir_var *var, *next_var; + struct hlsl_type *type, *next_type; + unsigned int i; + + for (i = 0; i < ctx->source_files_count; ++i) + vkd3d_free((void *)ctx->source_files[i]); + vkd3d_free(ctx->source_files); + + rb_destroy(&ctx->functions, free_function_rb, NULL); + + LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &ctx->scopes, struct hlsl_scope, entry) + { + LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry) + hlsl_free_var(var); + rb_destroy(&scope->types, NULL, NULL); + vkd3d_free(scope); + } + + LIST_FOR_EACH_ENTRY_SAFE(type, next_type, &ctx->types, struct hlsl_type, entry) + hlsl_free_type(type); +} + int hlsl_compile_shader(const char *text, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *dxbc, struct vkd3d_shader_message_context *message_context) { const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; const struct hlsl_profile_info *profile; + int ret;
if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO))) { @@ -1392,6 +1536,12 @@ int hlsl_compile_shader(const char *text, const struct vkd3d_shader_compile_info
vkd3d_shader_dump_shader(profile->type, &compile_info->source);
- return hlsl_lexer_compile(text, profile->type, profile->sm_major, profile->sm_minor, - hlsl_source_info->entry_point ? hlsl_source_info->entry_point : "main", dxbc, message_context); + if (!hlsl_ctx_init(&hlsl_ctx, message_context)) + return VKD3D_ERROR_OUT_OF_MEMORY; + + ret = hlsl_lexer_compile(text, hlsl_source_info->entry_point ? hlsl_source_info->entry_point : "main"); + + hlsl_ctx_cleanup(&hlsl_ctx); + + return ret; } diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index a3c16c51..48067956 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -518,8 +518,6 @@ static inline void set_parse_status(enum parse_status *current, enum parse_statu *current = PARSE_WARN; }
-void init_functions_tree(struct rb_tree *funcs) DECLSPEC_HIDDEN; - const char *hlsl_base_type_to_string(const struct hlsl_type *type) DECLSPEC_HIDDEN; const char *debug_hlsl_type(const struct hlsl_type *type) DECLSPEC_HIDDEN; const char *hlsl_debug_modifiers(DWORD modifiers) DECLSPEC_HIDDEN; @@ -536,7 +534,6 @@ void hlsl_dump_function(const struct hlsl_ir_function_decl *func) DECLSPEC_HIDDE
void hlsl_free_instr(struct hlsl_ir_node *node) DECLSPEC_HIDDEN; void hlsl_free_instr_list(struct list *list) DECLSPEC_HIDDEN; -void hlsl_free_function_rb(struct rb_entry *entry, void *context) DECLSPEC_HIDDEN; void hlsl_free_type(struct hlsl_type *type) DECLSPEC_HIDDEN; void hlsl_free_var(struct hlsl_ir_var *decl) DECLSPEC_HIDDEN;
@@ -578,15 +575,15 @@ void hlsl_report_message(const struct source_location loc, void hlsl_push_scope(struct hlsl_parse_ctx *ctx) DECLSPEC_HIDDEN; void hlsl_pop_scope(struct hlsl_parse_ctx *ctx) DECLSPEC_HIDDEN;
+bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type) DECLSPEC_HIDDEN; + struct hlsl_type *hlsl_type_clone(struct hlsl_type *old, unsigned int default_majority) DECLSPEC_HIDDEN; bool hlsl_type_compare(const struct hlsl_type *t1, const struct hlsl_type *t2) DECLSPEC_HIDDEN; unsigned int hlsl_type_component_count(struct hlsl_type *type) DECLSPEC_HIDDEN; bool hlsl_type_is_row_major(const struct hlsl_type *type) DECLSPEC_HIDDEN; bool hlsl_type_is_void(const struct hlsl_type *type) DECLSPEC_HIDDEN;
-int hlsl_lexer_compile(const char *text, enum vkd3d_shader_type type, DWORD major, DWORD minor, const char *entrypoint, - struct vkd3d_shader_code *dxbc, struct vkd3d_shader_message_context *message_context) DECLSPEC_HIDDEN; -int hlsl_parser_compile(enum vkd3d_shader_type type, DWORD major, DWORD minor, const char *entrypoint, - struct vkd3d_shader_code *dxbc, struct vkd3d_shader_message_context *message_context) DECLSPEC_HIDDEN; +int hlsl_lexer_compile(const char *text, const char *entrypoint) DECLSPEC_HIDDEN; +int hlsl_parser_compile(const char *entrypoint) DECLSPEC_HIDDEN;
#endif diff --git a/libs/vkd3d-shader/hlsl.l b/libs/vkd3d-shader/hlsl.l index 2a951ab0..0dea3d4c 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -271,8 +271,7 @@ row_major {return KW_ROW_MAJOR; }
%%
-int hlsl_lexer_compile(const char *text, enum vkd3d_shader_type type, DWORD major, DWORD minor, const char *entrypoint, - struct vkd3d_shader_code *dxbc, struct vkd3d_shader_message_context *message_context) +int hlsl_lexer_compile(const char *text, const char *entrypoint) { YY_BUFFER_STATE buffer; int ret; @@ -280,7 +279,7 @@ int hlsl_lexer_compile(const char *text, enum vkd3d_shader_type type, DWORD majo buffer = hlsl__scan_string(text); hlsl__switch_to_buffer(buffer);
- ret = hlsl_parser_compile(type, major, minor, entrypoint, dxbc, message_context); + ret = hlsl_parser_compile(entrypoint);
hlsl__delete_buffer(buffer); return ret; diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 5c3160f4..81e2be1d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -341,96 +341,6 @@ static DWORD add_modifiers(DWORD modifiers, DWORD mod, const struct source_locat return modifiers | mod; }
-static bool add_type_to_scope(struct hlsl_scope *scope, struct hlsl_type *def) -{ - if (hlsl_get_type(scope, def->name, false)) - return false; - - rb_put(&scope->types, def->name, &def->scope_entry); - return true; -} - -static void declare_predefined_types(struct hlsl_scope *scope) -{ - struct hlsl_type *type; - unsigned int x, y, bt; - static const char * const names[] = - { - "float", - "half", - "double", - "int", - "uint", - "bool", - }; - char name[10]; - - static const char *const sampler_names[] = - { - "sampler", - "sampler1D", - "sampler2D", - "sampler3D", - "samplerCUBE" - }; - - for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt) - { - for (y = 1; y <= 4; ++y) - { - for (x = 1; x <= 4; ++x) - { - sprintf(name, "%s%ux%u", names[bt], y, x); - type = hlsl_new_type(vkd3d_strdup(name), HLSL_CLASS_MATRIX, bt, x, y); - add_type_to_scope(scope, type); - - if (y == 1) - { - sprintf(name, "%s%u", names[bt], x); - type = hlsl_new_type(vkd3d_strdup(name), HLSL_CLASS_VECTOR, bt, x, y); - add_type_to_scope(scope, type); - hlsl_ctx.builtin_types.vector[bt][x - 1] = type; - - if (x == 1) - { - sprintf(name, "%s", names[bt]); - type = hlsl_new_type(vkd3d_strdup(name), HLSL_CLASS_SCALAR, bt, x, y); - add_type_to_scope(scope, type); - hlsl_ctx.builtin_types.scalar[bt] = type; - } - } - } - } - } - - for (bt = 0; bt <= HLSL_SAMPLER_DIM_MAX; ++bt) - { - type = hlsl_new_type(vkd3d_strdup(sampler_names[bt]), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); - type->sampler_dim = bt; - hlsl_ctx.builtin_types.sampler[bt] = type; - } - - hlsl_ctx.builtin_types.Void = hlsl_new_type(vkd3d_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1); - - /* DX8 effects predefined types */ - type = hlsl_new_type(vkd3d_strdup("DWORD"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1); - add_type_to_scope(scope, type); - type = hlsl_new_type(vkd3d_strdup("FLOAT"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1); - add_type_to_scope(scope, type); - type = hlsl_new_type(vkd3d_strdup("VECTOR"), HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1); - add_type_to_scope(scope, type); - type = hlsl_new_type(vkd3d_strdup("MATRIX"), HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4); - add_type_to_scope(scope, type); - type = hlsl_new_type(vkd3d_strdup("STRING"), HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1); - add_type_to_scope(scope, type); - type = hlsl_new_type(vkd3d_strdup("TEXTURE"), HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1); - add_type_to_scope(scope, type); - type = hlsl_new_type(vkd3d_strdup("PIXELSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1); - add_type_to_scope(scope, type); - type = hlsl_new_type(vkd3d_strdup("VERTEXSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1); - add_type_to_scope(scope, type); -} - static bool append_conditional_break(struct list *cond_list) { struct hlsl_ir_node *condition, *not; @@ -867,7 +777,7 @@ static bool add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct lis && (type->modifiers & HLSL_MODIFIER_ROW_MAJOR)) hlsl_report_message(v->loc, HLSL_LEVEL_ERROR, "more than one matrix majority keyword");
- ret = add_type_to_scope(hlsl_ctx.cur_scope, type); + ret = hlsl_scope_add_type(hlsl_ctx.cur_scope, type); if (!ret) hlsl_report_message(v->loc, HLSL_LEVEL_ERROR, "redefinition of custom type '%s'", v->name); @@ -1910,7 +1820,7 @@ named_struct_spec: YYABORT; }
- ret = add_type_to_scope(hlsl_ctx.cur_scope, $$); + ret = hlsl_scope_add_type(hlsl_ctx.cur_scope, $$); if (!ret) { hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR, "redefinition of struct '%s'", $2); @@ -3222,44 +3132,19 @@ static void compute_liveness(struct hlsl_ir_function_decl *entry_func) compute_liveness_recurse(entry_func->body, 0, 0); }
-int hlsl_parser_compile(enum vkd3d_shader_type type, DWORD major, DWORD minor, const char *entrypoint, - struct vkd3d_shader_code *dxbc, struct vkd3d_shader_message_context *message_context) +int hlsl_parser_compile(const char *entrypoint) { struct hlsl_ir_function_decl *entry_func; - struct hlsl_scope *scope, *next_scope; - struct hlsl_type *hlsl_type, *next_type; - struct hlsl_ir_var *var, *next_var; - int ret = VKD3D_ERROR; - unsigned int i; - - hlsl_ctx.status = PARSE_SUCCESS; - hlsl_ctx.message_context = message_context; - hlsl_ctx.line_no = hlsl_ctx.column = 1; - hlsl_ctx.source_file = vkd3d_strdup(""); - hlsl_ctx.source_files = vkd3d_malloc(sizeof(*hlsl_ctx.source_files)); - if (hlsl_ctx.source_files) - hlsl_ctx.source_files[0] = hlsl_ctx.source_file; - hlsl_ctx.source_files_count = 1; - hlsl_ctx.cur_scope = NULL; - hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR; - list_init(&hlsl_ctx.scopes); - list_init(&hlsl_ctx.types); - init_functions_tree(&hlsl_ctx.functions); - list_init(&hlsl_ctx.static_initializers); - - hlsl_push_scope(&hlsl_ctx); - hlsl_ctx.globals = hlsl_ctx.cur_scope; - declare_predefined_types(hlsl_ctx.globals);
hlsl_parse();
if (hlsl_ctx.status == PARSE_ERR) - goto out; + return VKD3D_ERROR_INVALID_SHADER;
if (!(entry_func = get_func_entry(entrypoint))) { hlsl_message("error: entry point %s is not defined\n", debugstr_a(entrypoint)); - goto out; + return VKD3D_ERROR_INVALID_SHADER; }
if (!hlsl_type_is_void(entry_func->return_type) @@ -3282,29 +3167,7 @@ int hlsl_parser_compile(enum vkd3d_shader_type type, DWORD major, DWORD minor, c
compute_liveness(entry_func);
- if (hlsl_ctx.status != PARSE_ERR) - ret = VKD3D_ERROR_NOT_IMPLEMENTED; - -out: - for (i = 0; i < hlsl_ctx.source_files_count; ++i) - vkd3d_free((void *)hlsl_ctx.source_files[i]); - vkd3d_free(hlsl_ctx.source_files); - - TRACE("Freeing functions IR.\n"); - rb_destroy(&hlsl_ctx.functions, hlsl_free_function_rb, NULL); - - TRACE("Freeing variables.\n"); - LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry) - { - LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry) - hlsl_free_var(var); - rb_destroy(&scope->types, NULL, NULL); - vkd3d_free(scope); - } - - TRACE("Freeing types.\n"); - LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry) - hlsl_free_type(hlsl_type); - - return ret; + if (hlsl_ctx.status == PARSE_ERR) + return VKD3D_ERROR_INVALID_SHADER; + return VKD3D_ERROR_NOT_IMPLEMENTED; }