r300: fix reader detection with breaks

We were previously ignoring the breaks completelly. This patch
is heavily based on analysis and draft patch from Filip Gawin.

It mostly mirrors the current behavior for ENDIF with minor
differences. If the reader is in a branch leading directly to BRK,
we set the AbortOnRead mask as when encountering ENDIF but jump to
the ENDLOOP. If the reader was before the branch, we save the
AbortOnRead mask as if in normal branch handling and restore it
at the end of the loop.

Besides the single dEQP fix, this also fixes one more dEQP and few
piglits when the loop unrolling is disabled.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7249

Signed-off-by: Pavel Ondračka <pavel.ondracka@gmail.com>
Reviewed-by: Filip Gawin <filip@gawin.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18900>
This commit is contained in:
Pavel Ondračka
2022-09-20 16:55:52 +02:00
parent ff933485b7
commit d1dbf6fe7e
2 changed files with 24 additions and 3 deletions

View File

@@ -43,8 +43,6 @@ dEQP-GLES2.functional.rasterization.primitives.line_loop_wide,Fail
dEQP-GLES2.functional.shaders.random.texture.fragment.141,Fail
dEQP-GLES2.functional.shaders.return.return_in_dynamic_loop_dynamic_fragment,Fail
dEQP-GLES2.functional.texture.format.a8_cube_npot,Fail
dEQP-GLES2.functional.texture.format.l8_cube_npot,Fail
dEQP-GLES2.functional.texture.format.la88_cube_npot,Fail

View File

@@ -688,6 +688,7 @@ static void get_readers_for_single_write(
unsigned int branch_depth = 0;
struct rc_instruction * endloop = NULL;
unsigned int abort_on_read_at_endloop = 0;
unsigned int abort_on_read_at_break = 0;
struct get_readers_callback_data * d = userdata;
d->ReaderData->Writer = writer;
@@ -741,6 +742,27 @@ static void get_readers_for_single_write(
continue;
}
break;
case RC_OPCODE_BRK:
if (branch_depth == 0 && d->ReaderData->LoopDepth == 0) {
tmp = rc_match_bgnloop(tmp);
d->ReaderData->AbortOnRead = d->AliveWriteMask;
} else {
struct branch_write_mask * masks = &d->BranchMasks[branch_depth];
if (masks->HasElse) {
/* Abort on read for components that were written in the IF
* block. */
abort_on_read_at_break |=
masks->IfWriteMask & ~masks->ElseWriteMask;
/* Abort on read for components that were written in the ELSE
* block. */
abort_on_read_at_break |=
masks->ElseWriteMask & ~d->AliveWriteMask;
} else {
abort_on_read_at_break |=
masks->IfWriteMask & ~d->AliveWriteMask;
}
}
break;
case RC_OPCODE_IF:
push_branch_mask(d, &branch_depth);
break;
@@ -784,7 +806,8 @@ static void get_readers_for_single_write(
if (tmp == writer) {
tmp = endloop;
endloop = NULL;
d->ReaderData->AbortOnRead = abort_on_read_at_endloop;
d->ReaderData->AbortOnRead = abort_on_read_at_endloop
| abort_on_read_at_break;
continue;
}
rc_for_all_writes_mask(tmp, get_readers_write_callback, d);