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:
@@ -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
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user