Skip to content
Snippets Groups Projects
Commit b5cc04b6 authored by Dave Airlie's avatar Dave Airlie Committed by Emil Velikov
Browse files

r600g/sb: fix issues cause by GLSL switching to loops for switch

Since 73dd50ac
glsl: implement switch flow control using a loop

The SB backend was falling over in an assert or crashing.

Tracked this down to the loops having no repeats, but requiring
a working break, initial code just called the loop handler for
all non-if statements, but this caused a regression in
tests/shaders/dead-code-break-interaction.shader_test.
So I had to add further code to detect if all the departure
nodes are empty and avoid generating an empty loop for that case.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=86089


Cc: "10.4" <mesa-stable@lists.freedesktop.org>
Reviewed-By: default avatarGlenn Kennard <glenn.kennard@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
(cherry picked from commit 7b0067d2)
parent d2e9fd5b
No related branches found
No related tags found
Loading
......@@ -46,15 +46,22 @@ int bc_finalizer::run() {
for (regions_vec::reverse_iterator I = rv.rbegin(), E = rv.rend(); I != E;
++I) {
region_node *r = *I;
bool is_if = false;
assert(r);
bool loop = r->is_loop();
assert(r->first);
if (r->first->is_container()) {
container_node *repdep1 = static_cast<container_node*>(r->first);
assert(repdep1->is_depart() || repdep1->is_repeat());
if_node *n_if = static_cast<if_node*>(repdep1->first);
if (n_if && n_if->is_if())
is_if = true;
}
if (loop)
finalize_loop(r);
else
if (is_if)
finalize_if(r);
else
finalize_loop(r);
r->expand();
}
......@@ -112,16 +119,33 @@ void bc_finalizer::finalize_loop(region_node* r) {
cf_node *loop_start = sh.create_cf(CF_OP_LOOP_START_DX10);
cf_node *loop_end = sh.create_cf(CF_OP_LOOP_END);
bool has_instr = false;
if (!r->is_loop()) {
for (depart_vec::iterator I = r->departs.begin(), E = r->departs.end();
I != E; ++I) {
depart_node *dep = *I;
if (!dep->empty()) {
has_instr = true;
break;
}
}
} else
has_instr = true;
loop_start->jump_after(loop_end);
loop_end->jump_after(loop_start);
if (has_instr) {
loop_start->jump_after(loop_end);
loop_end->jump_after(loop_start);
}
for (depart_vec::iterator I = r->departs.begin(), E = r->departs.end();
I != E; ++I) {
depart_node *dep = *I;
cf_node *loop_break = sh.create_cf(CF_OP_LOOP_BREAK);
loop_break->jump(loop_end);
dep->push_back(loop_break);
if (has_instr) {
cf_node *loop_break = sh.create_cf(CF_OP_LOOP_BREAK);
loop_break->jump(loop_end);
dep->push_back(loop_break);
}
dep->expand();
}
......@@ -137,8 +161,10 @@ void bc_finalizer::finalize_loop(region_node* r) {
rep->expand();
}
r->push_front(loop_start);
r->push_back(loop_end);
if (has_instr) {
r->push_front(loop_start);
r->push_back(loop_end);
}
}
void bc_finalizer::finalize_if(region_node* r) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment