mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/hlsl: Add initial support for parsing 'switch' statements.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
parent
ebb5aacabf
commit
ec8dfa467f
Notes:
Alexandre Julliard
2023-10-31 22:37:53 +01:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Zebediah Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/361
@ -1343,6 +1343,40 @@ struct hlsl_ir_node *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *cond
|
||||
return &iff->node;
|
||||
}
|
||||
|
||||
struct hlsl_ir_switch_case *hlsl_new_switch_case(struct hlsl_ctx *ctx, unsigned int value,
|
||||
bool is_default, struct hlsl_block *body, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
struct hlsl_ir_switch_case *c;
|
||||
|
||||
if (!(c = hlsl_alloc(ctx, sizeof(*c))))
|
||||
return NULL;
|
||||
|
||||
c->value = value;
|
||||
c->is_default = is_default;
|
||||
hlsl_block_init(&c->body);
|
||||
if (body)
|
||||
hlsl_block_add_block(&c->body, body);
|
||||
c->loc = *loc;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
struct hlsl_ir_node *hlsl_new_switch(struct hlsl_ctx *ctx, struct hlsl_ir_node *selector,
|
||||
struct list *cases, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
struct hlsl_ir_switch *s;
|
||||
|
||||
if (!(s = hlsl_alloc(ctx, sizeof(*s))))
|
||||
return NULL;
|
||||
init_node(&s->node, HLSL_IR_SWITCH, NULL, loc);
|
||||
hlsl_src_from_node(&s->selector, selector);
|
||||
list_init(&s->cases);
|
||||
if (cases)
|
||||
list_move_head(&s->cases, cases);
|
||||
|
||||
return &s->node;
|
||||
}
|
||||
|
||||
struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl_deref *deref,
|
||||
struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
@ -1805,6 +1839,58 @@ static struct hlsl_ir_node *clone_index(struct hlsl_ctx *ctx, struct clone_instr
|
||||
return dst;
|
||||
}
|
||||
|
||||
void hlsl_free_ir_switch_case(struct hlsl_ir_switch_case *c)
|
||||
{
|
||||
hlsl_block_cleanup(&c->body);
|
||||
list_remove(&c->entry);
|
||||
vkd3d_free(c);
|
||||
}
|
||||
|
||||
void hlsl_cleanup_ir_switch_cases(struct list *cases)
|
||||
{
|
||||
struct hlsl_ir_switch_case *c, *next;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(c, next, cases, struct hlsl_ir_switch_case, entry)
|
||||
{
|
||||
hlsl_free_ir_switch_case(c);
|
||||
}
|
||||
}
|
||||
|
||||
static struct hlsl_ir_node *clone_switch(struct hlsl_ctx *ctx,
|
||||
struct clone_instr_map *map, struct hlsl_ir_switch *s)
|
||||
{
|
||||
struct hlsl_ir_switch_case *c, *d;
|
||||
struct hlsl_ir_node *ret;
|
||||
struct hlsl_block body;
|
||||
struct list cases;
|
||||
|
||||
list_init(&cases);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry)
|
||||
{
|
||||
if (!(clone_block(ctx, &body, &c->body, map)))
|
||||
{
|
||||
hlsl_cleanup_ir_switch_cases(&cases);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
d = hlsl_new_switch_case(ctx, c->value, c->is_default, &body, &c->loc);
|
||||
hlsl_block_cleanup(&body);
|
||||
if (!d)
|
||||
{
|
||||
hlsl_cleanup_ir_switch_cases(&cases);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_add_tail(&cases, &d->entry);
|
||||
}
|
||||
|
||||
ret = hlsl_new_switch(ctx, map_instr(map, s->selector.node), &cases, &s->node.loc);
|
||||
hlsl_cleanup_ir_switch_cases(&cases);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx,
|
||||
struct clone_instr_map *map, const struct hlsl_ir_node *instr)
|
||||
{
|
||||
@ -1843,6 +1929,9 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx,
|
||||
case HLSL_IR_STORE:
|
||||
return clone_store(ctx, map, hlsl_ir_store(instr));
|
||||
|
||||
case HLSL_IR_SWITCH:
|
||||
return clone_switch(ctx, map, hlsl_ir_switch(instr));
|
||||
|
||||
case HLSL_IR_SWIZZLE:
|
||||
return clone_swizzle(ctx, map, hlsl_ir_swizzle(instr));
|
||||
}
|
||||
@ -2261,6 +2350,7 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type)
|
||||
[HLSL_IR_RESOURCE_LOAD ] = "HLSL_IR_RESOURCE_LOAD",
|
||||
[HLSL_IR_RESOURCE_STORE] = "HLSL_IR_RESOURCE_STORE",
|
||||
[HLSL_IR_STORE ] = "HLSL_IR_STORE",
|
||||
[HLSL_IR_SWITCH ] = "HLSL_IR_SWITCH",
|
||||
[HLSL_IR_SWIZZLE ] = "HLSL_IR_SWIZZLE",
|
||||
};
|
||||
|
||||
@ -2685,6 +2775,32 @@ static void dump_ir_index(struct vkd3d_string_buffer *buffer, const struct hlsl_
|
||||
vkd3d_string_buffer_printf(buffer, "]");
|
||||
}
|
||||
|
||||
static void dump_ir_switch(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_switch *s)
|
||||
{
|
||||
struct hlsl_ir_switch_case *c;
|
||||
|
||||
vkd3d_string_buffer_printf(buffer, "switch (");
|
||||
dump_src(buffer, &s->selector);
|
||||
vkd3d_string_buffer_printf(buffer, ") {\n");
|
||||
|
||||
LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry)
|
||||
{
|
||||
if (c->is_default)
|
||||
{
|
||||
vkd3d_string_buffer_printf(buffer, " %10s default: {\n", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
vkd3d_string_buffer_printf(buffer, " %10s case %u : {\n", "", c->value);
|
||||
}
|
||||
|
||||
dump_block(ctx, buffer, &c->body);
|
||||
vkd3d_string_buffer_printf(buffer, " %10s }\n", "");
|
||||
}
|
||||
|
||||
vkd3d_string_buffer_printf(buffer, " %10s }", "");
|
||||
}
|
||||
|
||||
static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_node *instr)
|
||||
{
|
||||
if (instr->index)
|
||||
@ -2740,6 +2856,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
|
||||
dump_ir_store(buffer, hlsl_ir_store(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_SWITCH:
|
||||
dump_ir_switch(ctx, buffer, hlsl_ir_switch(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_SWIZZLE:
|
||||
dump_ir_swizzle(buffer, hlsl_ir_swizzle(instr));
|
||||
break;
|
||||
@ -2900,6 +3020,14 @@ static void free_ir_swizzle(struct hlsl_ir_swizzle *swizzle)
|
||||
vkd3d_free(swizzle);
|
||||
}
|
||||
|
||||
static void free_ir_switch(struct hlsl_ir_switch *s)
|
||||
{
|
||||
hlsl_src_remove(&s->selector);
|
||||
hlsl_cleanup_ir_switch_cases(&s->cases);
|
||||
|
||||
vkd3d_free(s);
|
||||
}
|
||||
|
||||
static void free_ir_index(struct hlsl_ir_index *index)
|
||||
{
|
||||
hlsl_src_remove(&index->val);
|
||||
@ -2960,6 +3088,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node)
|
||||
case HLSL_IR_SWIZZLE:
|
||||
free_ir_swizzle(hlsl_ir_swizzle(node));
|
||||
break;
|
||||
|
||||
case HLSL_IR_SWITCH:
|
||||
free_ir_switch(hlsl_ir_switch(node));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,6 +281,7 @@ enum hlsl_ir_node_type
|
||||
HLSL_IR_RESOURCE_STORE,
|
||||
HLSL_IR_STORE,
|
||||
HLSL_IR_SWIZZLE,
|
||||
HLSL_IR_SWITCH,
|
||||
};
|
||||
|
||||
/* Common data for every type of IR instruction node. */
|
||||
@ -499,6 +500,22 @@ struct hlsl_ir_loop
|
||||
unsigned int next_index; /* liveness index of the end of the loop */
|
||||
};
|
||||
|
||||
struct hlsl_ir_switch_case
|
||||
{
|
||||
unsigned int value;
|
||||
bool is_default;
|
||||
struct hlsl_block body;
|
||||
struct list entry;
|
||||
struct vkd3d_shader_location loc;
|
||||
};
|
||||
|
||||
struct hlsl_ir_switch
|
||||
{
|
||||
struct hlsl_ir_node node;
|
||||
struct hlsl_src selector;
|
||||
struct list cases;
|
||||
};
|
||||
|
||||
enum hlsl_ir_expr_op
|
||||
{
|
||||
HLSL_OP0_VOID,
|
||||
@ -947,6 +964,12 @@ static inline struct hlsl_ir_index *hlsl_ir_index(const struct hlsl_ir_node *nod
|
||||
return CONTAINING_RECORD(node, struct hlsl_ir_index, node);
|
||||
}
|
||||
|
||||
static inline struct hlsl_ir_switch *hlsl_ir_switch(const struct hlsl_ir_node *node)
|
||||
{
|
||||
assert(node->type == HLSL_IR_SWITCH);
|
||||
return CONTAINING_RECORD(node, struct hlsl_ir_switch, node);
|
||||
}
|
||||
|
||||
static inline void hlsl_block_init(struct hlsl_block *block)
|
||||
{
|
||||
list_init(&block->instrs);
|
||||
@ -1120,6 +1143,9 @@ bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struc
|
||||
void hlsl_cleanup_deref(struct hlsl_deref *deref);
|
||||
void hlsl_cleanup_semantic(struct hlsl_semantic *semantic);
|
||||
|
||||
void hlsl_cleanup_ir_switch_cases(struct list *cases);
|
||||
void hlsl_free_ir_switch_case(struct hlsl_ir_switch_case *c);
|
||||
|
||||
void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new);
|
||||
|
||||
void hlsl_free_attribute(struct hlsl_attribute *attr);
|
||||
@ -1213,6 +1239,10 @@ struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr
|
||||
struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type,
|
||||
const struct vkd3d_shader_location *loc, const struct hlsl_semantic *semantic, unsigned int modifiers,
|
||||
const struct hlsl_reg_reservation *reg_reservation);
|
||||
struct hlsl_ir_switch_case *hlsl_new_switch_case(struct hlsl_ctx *ctx, unsigned int value, bool is_default,
|
||||
struct hlsl_block *body, const struct vkd3d_shader_location *loc);
|
||||
struct hlsl_ir_node *hlsl_new_switch(struct hlsl_ctx *ctx, struct hlsl_ir_node *selector,
|
||||
struct list *cases, const struct vkd3d_shader_location *loc);
|
||||
|
||||
void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc,
|
||||
enum vkd3d_shader_error error, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5);
|
||||
|
@ -46,7 +46,7 @@ static void update_location(struct hlsl_ctx *ctx, YYLTYPE *loc);
|
||||
|
||||
%x pp pp_line pp_pragma pp_ignore
|
||||
|
||||
RESERVED1 auto|case|catch|char|class|const_cast|default|delete|dynamic_cast|enum
|
||||
RESERVED1 auto|catch|char|class|const_cast|delete|dynamic_cast|enum
|
||||
RESERVED2 explicit|friend|goto|long|mutable|new|operator|private|protected|public
|
||||
RESERVED3 reinterpret_cast|short|signed|sizeof|static_cast|template|this|throw|try
|
||||
RESERVED4 typename|union|unsigned|using|virtual
|
||||
@ -73,6 +73,7 @@ ANY (.)
|
||||
BlendState {return KW_BLENDSTATE; }
|
||||
break {return KW_BREAK; }
|
||||
Buffer {return KW_BUFFER; }
|
||||
case {return KW_CASE; }
|
||||
cbuffer {return KW_CBUFFER; }
|
||||
centroid {return KW_CENTROID; }
|
||||
compile {return KW_COMPILE; }
|
||||
@ -80,6 +81,7 @@ const {return KW_CONST; }
|
||||
continue {return KW_CONTINUE; }
|
||||
DepthStencilState {return KW_DEPTHSTENCILSTATE; }
|
||||
DepthStencilView {return KW_DEPTHSTENCILVIEW; }
|
||||
default {return KW_DEFAULT; }
|
||||
discard {return KW_DISCARD; }
|
||||
do {return KW_DO; }
|
||||
double {return KW_DOUBLE; }
|
||||
|
@ -162,6 +162,12 @@ static void destroy_block(struct hlsl_block *block)
|
||||
vkd3d_free(block);
|
||||
}
|
||||
|
||||
static void destroy_switch_cases(struct list *cases)
|
||||
{
|
||||
hlsl_cleanup_ir_switch_cases(cases);
|
||||
vkd3d_free(cases);
|
||||
}
|
||||
|
||||
static bool hlsl_types_are_componentwise_compatible(struct hlsl_ctx *ctx, struct hlsl_type *src,
|
||||
struct hlsl_type *dst)
|
||||
{
|
||||
@ -1180,6 +1186,7 @@ static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, str
|
||||
case HLSL_IR_RESOURCE_LOAD:
|
||||
case HLSL_IR_RESOURCE_STORE:
|
||||
case HLSL_IR_STORE:
|
||||
case HLSL_IR_SWITCH:
|
||||
hlsl_error(ctx, &node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
|
||||
"Expected literal expression.");
|
||||
}
|
||||
@ -4679,17 +4686,20 @@ static struct hlsl_scope *get_loop_scope(struct hlsl_scope *scope)
|
||||
enum hlsl_sampler_dim sampler_dim;
|
||||
struct hlsl_attribute *attr;
|
||||
struct parse_attribute_list attr_list;
|
||||
struct hlsl_ir_switch_case *switch_case;
|
||||
}
|
||||
|
||||
%token KW_BLENDSTATE
|
||||
%token KW_BREAK
|
||||
%token KW_BUFFER
|
||||
%token KW_CASE
|
||||
%token KW_CBUFFER
|
||||
%token KW_CENTROID
|
||||
%token KW_COLUMN_MAJOR
|
||||
%token KW_COMPILE
|
||||
%token KW_CONST
|
||||
%token KW_CONTINUE
|
||||
%token KW_DEFAULT
|
||||
%token KW_DEPTHSTENCILSTATE
|
||||
%token KW_DEPTHSTENCILVIEW
|
||||
%token KW_DISCARD
|
||||
@ -4796,6 +4806,7 @@ static struct hlsl_scope *get_loop_scope(struct hlsl_scope *scope)
|
||||
%type <list> type_specs
|
||||
%type <list> variables_def
|
||||
%type <list> variables_def_typed
|
||||
%type <list> switch_cases
|
||||
|
||||
%token <name> VAR_IDENTIFIER
|
||||
%token <name> NEW_IDENTIFIER
|
||||
@ -4838,6 +4849,7 @@ static struct hlsl_scope *get_loop_scope(struct hlsl_scope *scope)
|
||||
%type <block> statement
|
||||
%type <block> statement_list
|
||||
%type <block> struct_declaration_without_vars
|
||||
%type <block> switch_statement
|
||||
%type <block> unary_expr
|
||||
|
||||
%type <boolval> boolean
|
||||
@ -4876,6 +4888,8 @@ static struct hlsl_scope *get_loop_scope(struct hlsl_scope *scope)
|
||||
|
||||
%type <semantic> semantic
|
||||
|
||||
%type <switch_case> switch_case
|
||||
|
||||
%type <type> field_type
|
||||
%type <type> named_struct_spec
|
||||
%type <type> unnamed_struct_spec
|
||||
@ -5357,6 +5371,11 @@ loop_scope_start:
|
||||
ctx->cur_scope->loop = true;
|
||||
}
|
||||
|
||||
switch_scope_start:
|
||||
%empty
|
||||
{
|
||||
}
|
||||
|
||||
var_identifier:
|
||||
VAR_IDENTIFIER
|
||||
| NEW_IDENTIFIER
|
||||
@ -6185,6 +6204,7 @@ statement:
|
||||
| jump_statement
|
||||
| selection_statement
|
||||
| loop_statement
|
||||
| switch_statement
|
||||
|
||||
jump_statement:
|
||||
KW_BREAK ';'
|
||||
@ -6333,6 +6353,103 @@ loop_statement:
|
||||
hlsl_pop_scope(ctx);
|
||||
}
|
||||
|
||||
switch_statement:
|
||||
attribute_list_optional switch_scope_start KW_SWITCH '(' expr ')' '{' switch_cases '}'
|
||||
{
|
||||
struct hlsl_ir_node *selector = node_from_block($5);
|
||||
struct hlsl_ir_node *s;
|
||||
|
||||
if (!(selector = add_implicit_conversion(ctx, $5, selector, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &@5)))
|
||||
{
|
||||
destroy_switch_cases($8);
|
||||
destroy_block($5);
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
s = hlsl_new_switch(ctx, selector, $8, &@3);
|
||||
|
||||
destroy_switch_cases($8);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
destroy_block($5);
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
$$ = $5;
|
||||
hlsl_block_add_instr($$, s);
|
||||
}
|
||||
|
||||
switch_case:
|
||||
KW_CASE expr ':' statement_list
|
||||
{
|
||||
struct hlsl_ir_switch_case *c;
|
||||
unsigned int value;
|
||||
|
||||
value = evaluate_static_expression_as_uint(ctx, $2, &@2);
|
||||
|
||||
c = hlsl_new_switch_case(ctx, value, false, $4, &@2);
|
||||
|
||||
destroy_block($2);
|
||||
destroy_block($4);
|
||||
|
||||
if (!c)
|
||||
YYABORT;
|
||||
$$ = c;
|
||||
}
|
||||
| KW_CASE expr ':'
|
||||
{
|
||||
struct hlsl_ir_switch_case *c;
|
||||
unsigned int value;
|
||||
|
||||
value = evaluate_static_expression_as_uint(ctx, $2, &@2);
|
||||
|
||||
c = hlsl_new_switch_case(ctx, value, false, NULL, &@2);
|
||||
|
||||
destroy_block($2);
|
||||
|
||||
if (!c)
|
||||
YYABORT;
|
||||
$$ = c;
|
||||
}
|
||||
| KW_DEFAULT ':' statement_list
|
||||
{
|
||||
struct hlsl_ir_switch_case *c;
|
||||
|
||||
c = hlsl_new_switch_case(ctx, 0, true, $3, &@1);
|
||||
|
||||
destroy_block($3);
|
||||
|
||||
if (!c)
|
||||
YYABORT;
|
||||
$$ = c;
|
||||
}
|
||||
| KW_DEFAULT ':'
|
||||
{
|
||||
struct hlsl_ir_switch_case *c;
|
||||
|
||||
if (!(c = hlsl_new_switch_case(ctx, 0, true, NULL, &@1)))
|
||||
YYABORT;
|
||||
$$ = c;
|
||||
}
|
||||
|
||||
switch_cases:
|
||||
switch_case
|
||||
{
|
||||
struct hlsl_ir_switch_case *c = LIST_ENTRY($1, struct hlsl_ir_switch_case, entry);
|
||||
if (!($$ = make_empty_list(ctx)))
|
||||
{
|
||||
hlsl_free_ir_switch_case(c);
|
||||
YYABORT;
|
||||
}
|
||||
list_add_head($$, &$1->entry);
|
||||
}
|
||||
| switch_cases switch_case
|
||||
{
|
||||
$$ = $1;
|
||||
list_add_tail($$, &$2->entry);
|
||||
}
|
||||
|
||||
expr_optional:
|
||||
%empty
|
||||
{
|
||||
|
@ -575,7 +575,19 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx,
|
||||
progress |= hlsl_transform_ir(ctx, func, &iff->else_block, context);
|
||||
}
|
||||
else if (instr->type == HLSL_IR_LOOP)
|
||||
{
|
||||
progress |= hlsl_transform_ir(ctx, func, &hlsl_ir_loop(instr)->body, context);
|
||||
}
|
||||
else if (instr->type == HLSL_IR_SWITCH)
|
||||
{
|
||||
struct hlsl_ir_switch *s = hlsl_ir_switch(instr);
|
||||
struct hlsl_ir_switch_case *c;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry)
|
||||
{
|
||||
progress |= hlsl_transform_ir(ctx, func, &c->body, context);
|
||||
}
|
||||
}
|
||||
|
||||
progress |= func(ctx, instr, context);
|
||||
}
|
||||
@ -835,6 +847,30 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (instr->type == HLSL_IR_SWITCH)
|
||||
{
|
||||
struct hlsl_ir_switch *s = hlsl_ir_switch(instr);
|
||||
struct hlsl_ir_switch_case *c;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry)
|
||||
{
|
||||
has_early_return |= lower_return(ctx, func, &c->body, true);
|
||||
}
|
||||
|
||||
if (has_early_return)
|
||||
{
|
||||
if (in_loop)
|
||||
{
|
||||
/* For a 'switch' nested in a loop append a break after the 'switch'. */
|
||||
insert_early_return_break(ctx, func, instr);
|
||||
}
|
||||
else
|
||||
{
|
||||
cf_instr = instr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (return_instr)
|
||||
@ -2929,6 +2965,7 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
|
||||
case HLSL_IR_JUMP:
|
||||
case HLSL_IR_LOOP:
|
||||
case HLSL_IR_RESOURCE_STORE:
|
||||
case HLSL_IR_SWITCH:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2956,6 +2993,16 @@ static unsigned int index_instructions(struct hlsl_block *block, unsigned int in
|
||||
index = index_instructions(&hlsl_ir_loop(instr)->body, index);
|
||||
hlsl_ir_loop(instr)->next_index = index;
|
||||
}
|
||||
else if (instr->type == HLSL_IR_SWITCH)
|
||||
{
|
||||
struct hlsl_ir_switch *s = hlsl_ir_switch(instr);
|
||||
struct hlsl_ir_switch_case *c;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry)
|
||||
{
|
||||
index = index_instructions(&c->body, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
@ -3173,6 +3220,16 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop
|
||||
jump->condition.node->last_read = last_read;
|
||||
break;
|
||||
}
|
||||
case HLSL_IR_SWITCH:
|
||||
{
|
||||
struct hlsl_ir_switch *s = hlsl_ir_switch(instr);
|
||||
struct hlsl_ir_switch_case *c;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry)
|
||||
compute_liveness_recurse(&c->body, loop_first, loop_last);
|
||||
s->selector.node->last_read = last_read;
|
||||
break;
|
||||
}
|
||||
case HLSL_IR_CONSTANT:
|
||||
break;
|
||||
}
|
||||
@ -3524,6 +3581,18 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx,
|
||||
break;
|
||||
}
|
||||
|
||||
case HLSL_IR_SWITCH:
|
||||
{
|
||||
struct hlsl_ir_switch *s = hlsl_ir_switch(instr);
|
||||
struct hlsl_ir_switch_case *c;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry)
|
||||
{
|
||||
allocate_temp_registers_recurse(ctx, &c->body, allocator);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -3633,6 +3702,18 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx,
|
||||
break;
|
||||
}
|
||||
|
||||
case HLSL_IR_SWITCH:
|
||||
{
|
||||
struct hlsl_ir_switch *s = hlsl_ir_switch(instr);
|
||||
struct hlsl_ir_switch_case *c;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry)
|
||||
{
|
||||
allocate_const_registers_recurse(ctx, &c->body, allocator);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ float4 main() : sv_target
|
||||
return c;
|
||||
}
|
||||
|
||||
[pixel shader fail]
|
||||
[pixel shader fail todo]
|
||||
uint4 v;
|
||||
|
||||
float4 main() : sv_target
|
||||
@ -246,7 +246,7 @@ float4 main() : sv_target
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
[pixel shader fail]
|
||||
[pixel shader fail todo]
|
||||
uint4 v;
|
||||
|
||||
float4 main() : sv_target
|
||||
@ -262,7 +262,7 @@ float4 main() : sv_target
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
[pixel shader fail(sm<6)]
|
||||
[pixel shader fail(sm<6) todo]
|
||||
uint4 v;
|
||||
|
||||
float4 main() : sv_target
|
||||
@ -279,7 +279,7 @@ float4 main() : sv_target
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
[pixel shader fail(sm<6)]
|
||||
[pixel shader fail(sm<6) todo]
|
||||
uint4 v;
|
||||
|
||||
float4 main() : sv_target
|
||||
@ -296,7 +296,7 @@ float4 main() : sv_target
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
[pixel shader fail(sm<6)]
|
||||
[pixel shader fail(sm<6) todo]
|
||||
uint4 v;
|
||||
|
||||
float4 main() : sv_target
|
||||
@ -455,7 +455,7 @@ todo draw quad
|
||||
probe all rgba (1.0, 2.0, 3.0, 4.0)
|
||||
|
||||
% 'continue' is not supported in switches
|
||||
[pixel shader fail(sm<6)]
|
||||
[pixel shader fail(sm<6) todo]
|
||||
uint4 v;
|
||||
|
||||
float4 main() : sv_target
|
||||
|
Loading…
x
Reference in New Issue
Block a user