Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 205 +++++++++++++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl.h | 22 ++++- libs/vkd3d-shader/hlsl.y | 205 --------------------------------------- 3 files changed, 224 insertions(+), 208 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index cd0d9cbc..e73ed923 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -18,6 +18,7 @@ */
#include "hlsl.h" +#include <stdio.h>
BOOL add_declaration(struct hlsl_scope *scope, struct hlsl_ir_var *decl, BOOL local_var) { @@ -102,6 +103,41 @@ struct hlsl_type *new_array_type(struct hlsl_type *basic_type, unsigned int arra return type; }
+static DWORD get_array_size(const struct hlsl_type *type) +{ + if (type->type == HLSL_CLASS_ARRAY) + return get_array_size(type->e.array.type) * type->e.array.elements_count; + return 1; +} + +struct hlsl_type *new_struct_type(const char *name, struct list *fields) +{ + struct hlsl_struct_field *field; + unsigned int reg_size = 0; + struct hlsl_type *type; + + if (!(type = vkd3d_calloc(1, sizeof(*type)))) + return NULL; + type->type = HLSL_CLASS_STRUCT; + type->base_type = HLSL_TYPE_VOID; + type->name = name; + type->dimx = 0; + type->dimy = 1; + type->e.elements = fields; + + LIST_FOR_EACH_ENTRY(field, fields, struct hlsl_struct_field, entry) + { + field->reg_offset = reg_size; + reg_size += field->type->reg_size; + type->dimx += field->type->dimx * field->type->dimy * get_array_size(field->type); + } + type->reg_size = reg_size; + + list_add_tail(&hlsl_ctx.types, &type->entry); + + return type; +} + struct hlsl_type *get_type(struct hlsl_scope *scope, const char *name, BOOL recursive) { struct rb_entry *entry = rb_get(&scope->types, name); @@ -639,6 +675,35 @@ struct hlsl_ir_expr *new_cast(struct hlsl_ir_node *node, struct hlsl_type *type, return expr_from_node(cast); }
+struct hlsl_ir_var *new_var(const char *name, struct hlsl_type *type, const struct source_location loc, + const char *semantic, unsigned int modifiers, const struct reg_reservation *reg_reservation) +{ + struct hlsl_ir_var *var; + + if (!(var = vkd3d_calloc(1, sizeof(*var)))) + { + hlsl_ctx.status = PARSE_ERR; + return NULL; + } + + var->name = name; + var->data_type = type; + var->loc = loc; + var->semantic = semantic; + var->modifiers = modifiers; + var->reg_reservation = reg_reservation; + return var; +} + +struct hlsl_ir_var *new_synthetic_var(const char *name, struct hlsl_type *type, const struct source_location loc) +{ + struct hlsl_ir_var *var = new_var(vkd3d_strdup(name), type, loc, NULL, 0, NULL); + + if (var) + list_add_tail(&hlsl_ctx.globals->vars, &var->scope_entry); + return var; +} + static enum hlsl_ir_expr_op op_from_assignment(enum parse_assign_op op) { static const enum hlsl_ir_expr_op ops[] = @@ -780,6 +845,146 @@ struct hlsl_ir_node *add_assignment(struct list *instrs, struct hlsl_ir_node *lh return &assign->node; }
+static BOOL type_is_single_reg(const struct hlsl_type *type) +{ + return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR; +} + +struct hlsl_ir_assignment *new_assignment(struct hlsl_ir_var *var, struct hlsl_ir_node *offset, + struct hlsl_ir_node *rhs, unsigned int writemask, struct source_location loc) +{ + struct hlsl_ir_assignment *assign; + + if (!writemask && type_is_single_reg(rhs->data_type)) + writemask = (1 << rhs->data_type->dimx) - 1; + + if (!(assign = vkd3d_malloc(sizeof(*assign)))) + return NULL; + + init_node(&assign->node, HLSL_IR_ASSIGNMENT, NULL, loc); + assign->lhs.var = var; + hlsl_src_from_node(&assign->lhs.offset, offset); + hlsl_src_from_node(&assign->rhs, rhs); + assign->writemask = writemask; + return assign; +} + +struct hlsl_ir_assignment *new_simple_assignment(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) +{ + return new_assignment(lhs, NULL, rhs, 0, rhs->loc); +} + +struct hlsl_ir_constant *new_uint_constant(unsigned int n, const struct source_location loc) +{ + struct hlsl_ir_constant *c; + + if (!(c = vkd3d_malloc(sizeof(*c)))) + return NULL; + init_node(&c->node, HLSL_IR_CONSTANT, hlsl_ctx.builtin_types.scalar[HLSL_TYPE_UINT], loc); + c->value.u[0] = n; + return c; +} + +struct hlsl_ir_node *new_unary_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, struct source_location loc) +{ + struct hlsl_ir_expr *expr; + + if (!(expr = vkd3d_calloc(1, sizeof(*expr)))) + return NULL; + init_node(&expr->node, HLSL_IR_EXPR, arg->data_type, loc); + expr->op = op; + hlsl_src_from_node(&expr->operands[0], arg); + return &expr->node; +} + +struct hlsl_ir_node *new_binary_expr(enum hlsl_ir_expr_op op, + struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2) +{ + struct hlsl_ir_expr *expr; + + assert(compare_hlsl_types(arg1->data_type, arg2->data_type)); + + if (!(expr = vkd3d_calloc(1, sizeof(*expr)))) + return NULL; + init_node(&expr->node, HLSL_IR_EXPR, arg1->data_type, arg1->loc); + expr->op = op; + hlsl_src_from_node(&expr->operands[0], arg1); + hlsl_src_from_node(&expr->operands[1], arg2); + return &expr->node; +} + +struct hlsl_ir_if *new_if(struct hlsl_ir_node *condition, struct source_location loc) +{ + struct hlsl_ir_if *iff; + + if (!(iff = vkd3d_malloc(sizeof(*iff)))) + return NULL; + init_node(&iff->node, HLSL_IR_IF, NULL, loc); + hlsl_src_from_node(&iff->condition, condition); + list_init(&iff->then_instrs); + list_init(&iff->else_instrs); + return iff; +} + +struct hlsl_ir_load *new_var_load(struct hlsl_ir_var *var, const struct source_location loc) +{ + struct hlsl_ir_load *load; + + if (!(load = vkd3d_calloc(1, sizeof(*load)))) + return NULL; + init_node(&load->node, HLSL_IR_LOAD, var->data_type, loc); + load->src.var = var; + return load; +} + +struct hlsl_ir_swizzle *new_swizzle(DWORD s, unsigned int components, + struct hlsl_ir_node *val, struct source_location *loc) +{ + struct hlsl_ir_swizzle *swizzle; + + if (!(swizzle = vkd3d_malloc(sizeof(*swizzle)))) + return NULL; + init_node(&swizzle->node, HLSL_IR_SWIZZLE, + new_hlsl_type(NULL, HLSL_CLASS_VECTOR, val->data_type->base_type, components, 1), *loc); + hlsl_src_from_node(&swizzle->val, val); + swizzle->swizzle = s; + return swizzle; +} + +BOOL type_is_void(const struct hlsl_type *type) +{ + return type->type == HLSL_CLASS_OBJECT && type->base_type == HLSL_TYPE_VOID; +} + +struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type, + struct list *parameters, const char *semantic, struct source_location loc) +{ + struct hlsl_ir_function_decl *decl; + + if (!(decl = vkd3d_calloc(1, sizeof(*decl)))) + return NULL; + decl->return_type = return_type; + decl->parameters = parameters; + decl->semantic = semantic; + decl->loc = loc; + + if (!type_is_void(return_type)) + { + struct hlsl_ir_var *return_var; + char name[28]; + + sprintf(name, "<retval-%p>", decl); + if (!(return_var = new_synthetic_var(name, return_type, loc))) + { + vkd3d_free(decl); + return NULL; + } + decl->return_var = return_var; + } + + return decl; +} + static int compare_hlsl_types_rb(const void *key, const struct rb_entry *entry) { const struct hlsl_type *type = RB_ENTRY_VALUE(entry, const struct hlsl_type, scope_entry); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 128de1d6..aabfbaf9 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -599,19 +599,34 @@ struct hlsl_ir_expr *add_expr(struct list *instrs, enum hlsl_ir_expr_op op, stru struct hlsl_ir_node *add_implicit_conversion(struct list *instrs, struct hlsl_ir_node *node, struct hlsl_type *type, struct source_location *loc) DECLSPEC_HIDDEN;
-struct hlsl_ir_expr *new_cast(struct hlsl_ir_node *node, struct hlsl_type *type, - struct source_location *loc) DECLSPEC_HIDDEN; +struct hlsl_type *new_array_type(struct hlsl_type *basic_type, unsigned int array_size) DECLSPEC_HIDDEN; +struct hlsl_ir_assignment *new_assignment(struct hlsl_ir_var *var, struct hlsl_ir_node *offset, + struct hlsl_ir_node *rhs, unsigned int writemask, struct source_location loc) DECLSPEC_HIDDEN; struct hlsl_ir_node *new_binary_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2) DECLSPEC_HIDDEN; +struct hlsl_ir_expr *new_cast(struct hlsl_ir_node *node, struct hlsl_type *type, + struct source_location *loc) DECLSPEC_HIDDEN; +struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type, + struct list *parameters, const char *semantic, struct source_location loc) DECLSPEC_HIDDEN; +struct hlsl_ir_if *new_if(struct hlsl_ir_node *condition, struct source_location loc) DECLSPEC_HIDDEN; +struct hlsl_ir_assignment *new_simple_assignment(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) DECLSPEC_HIDDEN; +struct hlsl_type *new_struct_type(const char *name, struct list *fields) DECLSPEC_HIDDEN; +struct hlsl_ir_swizzle *new_swizzle(DWORD s, unsigned int components, + struct hlsl_ir_node *val, struct source_location *loc) DECLSPEC_HIDDEN; +struct hlsl_ir_var *new_synthetic_var(const char *name, struct hlsl_type *type, + const struct source_location loc) DECLSPEC_HIDDEN; +struct hlsl_ir_constant *new_uint_constant(unsigned int n, const struct source_location loc) DECLSPEC_HIDDEN; struct hlsl_ir_node *new_unary_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, struct source_location loc) DECLSPEC_HIDDEN; +struct hlsl_ir_var *new_var(const char *name, struct hlsl_type *type, const struct source_location loc, + const char *semantic, unsigned int modifiers, const struct reg_reservation *reg_reservation) DECLSPEC_HIDDEN; +struct hlsl_ir_load *new_var_load(struct hlsl_ir_var *var, const struct source_location loc) DECLSPEC_HIDDEN;
BOOL add_declaration(struct hlsl_scope *scope, struct hlsl_ir_var *decl, BOOL local_var) DECLSPEC_HIDDEN; struct hlsl_ir_var *get_variable(struct hlsl_scope *scope, const char *name) DECLSPEC_HIDDEN; void free_declaration(struct hlsl_ir_var *decl) DECLSPEC_HIDDEN; struct hlsl_type *new_hlsl_type(const char *name, enum hlsl_type_class type_class, enum hlsl_base_type base_type, unsigned dimx, unsigned dimy) DECLSPEC_HIDDEN; -struct hlsl_type *new_array_type(struct hlsl_type *basic_type, unsigned int array_size) DECLSPEC_HIDDEN; struct hlsl_type *clone_hlsl_type(struct hlsl_type *old, unsigned int default_majority) DECLSPEC_HIDDEN; struct hlsl_type *get_type(struct hlsl_scope *scope, const char *name, BOOL recursive) DECLSPEC_HIDDEN; BOOL is_row_major(const struct hlsl_type *type) DECLSPEC_HIDDEN; @@ -624,6 +639,7 @@ BOOL pop_scope(struct hlsl_parse_ctx *ctx) DECLSPEC_HIDDEN; void init_functions_tree(struct rb_tree *funcs) DECLSPEC_HIDDEN; void add_function_decl(struct rb_tree *funcs, char *name, struct hlsl_ir_function_decl *decl, BOOL intrinsic) DECLSPEC_HIDDEN; +BOOL 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; diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 4e2218c5..df155a08 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -77,11 +77,6 @@ static void check_invalid_matrix_modifiers(DWORD modifiers, struct source_locati "'row_major' or 'column_major' modifiers are only allowed for matrices."); }
-static BOOL type_is_single_reg(const struct hlsl_type *type) -{ - return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR; -} - static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local) { BOOL ret; @@ -232,24 +227,6 @@ static void declare_predefined_types(struct hlsl_scope *scope) add_type_to_scope(scope, type); }
-static BOOL type_is_void(const struct hlsl_type *type) -{ - return type->type == HLSL_CLASS_OBJECT && type->base_type == HLSL_TYPE_VOID; -} - -static struct hlsl_ir_if *new_if(struct hlsl_ir_node *condition, struct source_location loc) -{ - struct hlsl_ir_if *iff; - - if (!(iff = vkd3d_malloc(sizeof(*iff)))) - return NULL; - init_node(&iff->node, HLSL_IR_IF, NULL, loc); - hlsl_src_from_node(&iff->condition, condition); - list_init(&iff->then_instrs); - list_init(&iff->else_instrs); - return iff; -} - static BOOL append_conditional_break(struct list *cond_list) { struct hlsl_ir_node *condition, *not; @@ -352,20 +329,6 @@ static void free_parse_initializer(struct parse_initializer *initializer) vkd3d_free(initializer->args); }
-static struct hlsl_ir_swizzle *new_swizzle(DWORD s, unsigned int components, - struct hlsl_ir_node *val, struct source_location *loc) -{ - struct hlsl_ir_swizzle *swizzle; - - if (!(swizzle = vkd3d_malloc(sizeof(*swizzle)))) - return NULL; - init_node(&swizzle->node, HLSL_IR_SWIZZLE, - new_hlsl_type(NULL, HLSL_CLASS_VECTOR, val->data_type->base_type, components, 1), *loc); - hlsl_src_from_node(&swizzle->val, val); - swizzle->swizzle = s; - return swizzle; -} - static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const char *swizzle, struct source_location *loc) { @@ -448,60 +411,6 @@ static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const cha return NULL; }
-static struct hlsl_ir_var *new_var(const char *name, struct hlsl_type *type, const struct source_location loc, - const char *semantic, unsigned int modifiers, const struct reg_reservation *reg_reservation) -{ - struct hlsl_ir_var *var; - - if (!(var = vkd3d_calloc(1, sizeof(*var)))) - { - hlsl_ctx.status = PARSE_ERR; - return NULL; - } - - var->name = name; - var->data_type = type; - var->loc = loc; - var->semantic = semantic; - var->modifiers = modifiers; - var->reg_reservation = reg_reservation; - return var; -} - -static struct hlsl_ir_var *new_synthetic_var(const char *name, struct hlsl_type *type, - const struct source_location loc) -{ - struct hlsl_ir_var *var = new_var(vkd3d_strdup(name), type, loc, NULL, 0, NULL); - - if (var) - list_add_tail(&hlsl_ctx.globals->vars, &var->scope_entry); - return var; -} - -static struct hlsl_ir_assignment *new_assignment(struct hlsl_ir_var *var, struct hlsl_ir_node *offset, - struct hlsl_ir_node *rhs, unsigned int writemask, struct source_location loc) -{ - struct hlsl_ir_assignment *assign; - - if (!writemask && type_is_single_reg(rhs->data_type)) - writemask = (1 << rhs->data_type->dimx) - 1; - - if (!(assign = vkd3d_malloc(sizeof(*assign)))) - return NULL; - - init_node(&assign->node, HLSL_IR_ASSIGNMENT, NULL, loc); - assign->lhs.var = var; - hlsl_src_from_node(&assign->lhs.offset, offset); - hlsl_src_from_node(&assign->rhs, rhs); - assign->writemask = writemask; - return assign; -} - -static struct hlsl_ir_assignment *new_simple_assignment(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) -{ - return new_assignment(lhs, NULL, rhs, 0, rhs->loc); -} - static struct hlsl_ir_jump *add_return(struct list *instrs, struct hlsl_ir_node *return_value, struct source_location loc) { @@ -534,56 +443,6 @@ static struct hlsl_ir_jump *add_return(struct list *instrs, return jump; }
-static struct hlsl_ir_constant *new_uint_constant(unsigned int n, const struct source_location loc) -{ - struct hlsl_ir_constant *c; - - if (!(c = vkd3d_malloc(sizeof(*c)))) - return NULL; - init_node(&c->node, HLSL_IR_CONSTANT, hlsl_ctx.builtin_types.scalar[HLSL_TYPE_UINT], loc); - c->value.u[0] = n; - return c; -} - -struct hlsl_ir_node *new_unary_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, struct source_location loc) -{ - struct hlsl_ir_expr *expr; - - if (!(expr = vkd3d_calloc(1, sizeof(*expr)))) - return NULL; - init_node(&expr->node, HLSL_IR_EXPR, arg->data_type, loc); - expr->op = op; - hlsl_src_from_node(&expr->operands[0], arg); - return &expr->node; -} - -struct hlsl_ir_node *new_binary_expr(enum hlsl_ir_expr_op op, - struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2) -{ - struct hlsl_ir_expr *expr; - - assert(compare_hlsl_types(arg1->data_type, arg2->data_type)); - - if (!(expr = vkd3d_calloc(1, sizeof(*expr)))) - return NULL; - init_node(&expr->node, HLSL_IR_EXPR, arg1->data_type, arg1->loc); - expr->op = op; - hlsl_src_from_node(&expr->operands[0], arg1); - hlsl_src_from_node(&expr->operands[1], arg2); - return &expr->node; -} - -static struct hlsl_ir_load *new_var_load(struct hlsl_ir_var *var, const struct source_location loc) -{ - struct hlsl_ir_load *load; - - if (!(load = vkd3d_calloc(1, sizeof(*load)))) - return NULL; - init_node(&load->node, HLSL_IR_LOAD, var->data_type, loc); - load->src.var = var; - return load; -} - static struct hlsl_ir_load *add_load(struct list *instrs, struct hlsl_ir_node *var_node, struct hlsl_ir_node *offset, struct hlsl_type *data_type, const struct source_location loc) { @@ -777,41 +636,6 @@ static struct list *gen_struct_fields(struct hlsl_type *type, DWORD modifiers, s return list; }
-static DWORD get_array_size(const struct hlsl_type *type) -{ - if (type->type == HLSL_CLASS_ARRAY) - return get_array_size(type->e.array.type) * type->e.array.elements_count; - return 1; -} - -static struct hlsl_type *new_struct_type(const char *name, struct list *fields) -{ - struct hlsl_struct_field *field; - unsigned int reg_size = 0; - struct hlsl_type *type; - - if (!(type = vkd3d_calloc(1, sizeof(*type)))) - return NULL; - type->type = HLSL_CLASS_STRUCT; - type->base_type = HLSL_TYPE_VOID; - type->name = name; - type->dimx = 0; - type->dimy = 1; - type->e.elements = fields; - - LIST_FOR_EACH_ENTRY(field, fields, struct hlsl_struct_field, entry) - { - field->reg_offset = reg_size; - reg_size += field->type->reg_size; - type->dimx += field->type->dimx * field->type->dimy * get_array_size(field->type); - } - type->reg_size = reg_size; - - list_add_tail(&hlsl_ctx.types, &type->entry); - - return type; -} - static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct list *list) { struct parse_variable_def *v, *v_next; @@ -1203,35 +1027,6 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, return statements_list; }
-static struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type, - struct list *parameters, const char *semantic, struct source_location loc) -{ - struct hlsl_ir_function_decl *decl; - - if (!(decl = vkd3d_calloc(1, sizeof(*decl)))) - return NULL; - decl->return_type = return_type; - decl->parameters = parameters; - decl->semantic = semantic; - decl->loc = loc; - - if (!type_is_void(return_type)) - { - struct hlsl_ir_var *return_var; - char name[28]; - - sprintf(name, "<retval-%p>", decl); - if (!(return_var = new_synthetic_var(name, return_type, loc))) - { - vkd3d_free(decl); - return NULL; - } - decl->return_var = return_var; - } - - return decl; -} - %}
%locations