pan/bi: Use canonical flow control enum

Merges multiple bits and adds some new combinations. The semantics are
the compiler are evidently wrong, we'll fix that next.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7081>
This commit is contained in:
Alyssa Rosenzweig
2020-10-02 15:03:58 -04:00
parent d2328646b2
commit 0f181f4eae
5 changed files with 71 additions and 17 deletions
+3 -2
View File
@@ -45,8 +45,9 @@ bi_pack_header(bi_clause *clause, bi_clause *next_1, bi_clause *next_2, bool is_
dependency_wait |= next_2 ? next_2->dependencies : 0;
struct bifrost_header header = {
.back_to_back = clause->back_to_back,
.no_end_of_shader = (next_1 != NULL),
.flow_control =
(next_1 == NULL) ? BIFROST_FLOW_END :
(clause->back_to_back ? BIFROST_FLOW_NBTB : BIFROST_FLOW_NBTB_UNCONDITIONAL),
.terminate_discarded_threads = is_fragment,
.next_clause_prefetch = clause->next_clause_prefetch,
.staging_barrier = clause->staging_barrier,
+16
View File
@@ -98,3 +98,19 @@ bi_interp_mode_name(enum bifrost_interp_mode mode)
default: return ".unknown";
}
}
const char *
bi_flow_control_name(enum bifrost_flow mode)
{
switch (mode) {
case BIFROST_FLOW_END: return "eos";
case BIFROST_FLOW_NBTB_PC: return "nbb br_pc";
case BIFROST_FLOW_NBTB_UNCONDITIONAL: return "nbb r_uncond";
case BIFROST_FLOW_NBTB: return "nbb";
case BIFROST_FLOW_BTB_UNCONDITIONAL: return "bb r_uncond";
case BIFROST_FLOW_BTB_NONE: return "bb";
case BIFROST_FLOW_WE_UNCONDITIONAL: return "we r_uncond";
case BIFROST_FLOW_WE: return "we";
default: return "XXX";
}
}
+1
View File
@@ -35,5 +35,6 @@ const char * bi_output_mod_name(enum bifrost_outmod mod);
const char * bi_minmax_mode_name(enum bifrost_minmax_mode mod);
const char * bi_round_mode_name(enum bifrost_roundmode mod);
const char * bi_interp_mode_name(enum bifrost_interp_mode mode);
const char * bi_flow_control_name(enum bifrost_flow mode);
#endif
+48 -5
View File
@@ -67,6 +67,48 @@ enum bifrost_exceptions {
BIFROST_EXCEPTIONS_PRECISE_SQRT = 3,
};
/* Describes clause flow control, with respect to control flow and branch
* reconvergence.
*
* Control flow may be considered back-to-back (execute clauses back-to-back),
* non-back-to-back (switch warps after clause before the next clause), write
* elision (back-to-back and elide register slot #3 write from the clause), or
* end of shader.
*
* Branch reconvergence may be disabled, enabled unconditionally, or enabled
* based on the program counter. A clause requires reconvergence if it has a
* successor that can be executed without first executing the clause itself.
* Separate iterations of a loop are treated separately here, so it is also the
* case for a loop exit where the iteration count is not warp-invariant.
*
*/
enum bifrost_flow {
/* End-of-shader */
BIFROST_FLOW_END = 0,
/* Non back-to-back, PC-encoded reconvergence */
BIFROST_FLOW_NBTB_PC = 1,
/* Non back-to-back, unconditional reconvergence */
BIFROST_FLOW_NBTB_UNCONDITIONAL = 2,
/* Non back-to-back, no reconvergence */
BIFROST_FLOW_NBTB = 3,
/* Back-to-back, unconditional reconvergence */
BIFROST_FLOW_BTB_UNCONDITIONAL = 4,
/* Back-to-back, no reconvergence */
BIFROST_FLOW_BTB_NONE = 5,
/* Write elision, unconditional reconvergence */
BIFROST_FLOW_WE_UNCONDITIONAL = 6,
/* Write elision, no reconvergence */
BIFROST_FLOW_WE = 7,
};
struct bifrost_header {
/* Reserved */
unsigned zero1 : 5;
@@ -84,11 +126,12 @@ struct bifrost_header {
/* Floating-point excception handling mode */
enum bifrost_exceptions float_exceptions : 2;
// true if the execution mask of the next clause is the same as the mask of
// the current clause.
unsigned back_to_back : 1;
unsigned no_end_of_shader: 1;
unsigned unk2 : 2;
/* Enum describing the flow control, which matters for handling
* divergence and reconvergence efficiently */
enum bifrost_flow flow_control : 3;
/* Reserved */
unsigned zero2 : 1;
/* Terminate discarded threads, rather than continuing execution. Set
* for fragment shaders for standard GL behaviour of DISCARD. */
+3 -10
View File
@@ -89,12 +89,7 @@ static void dump_header(FILE *fp, struct bifrost_header header, bool verbose)
if (header.staging_barrier)
fprintf(fp, "osrb ");
if (!header.no_end_of_shader)
fprintf(fp, "eos ");
if (!header.back_to_back) {
fprintf(fp, "nbb ");
}
fprintf(fp, "%s ", bi_flow_control_name(header.flow_control));
if (header.suppress_inf)
fprintf(fp, "inf_suppress ");
@@ -109,6 +104,7 @@ static void dump_header(FILE *fp, struct bifrost_header header, bool verbose)
fprintf(fp, "ftz_au ");
assert(!header.zero1);
assert(!header.zero2);
if (header.float_exceptions == BIFROST_EXCEPTIONS_DISABLED)
fprintf(fp, "fpe_ts ");
@@ -120,9 +116,6 @@ static void dump_header(FILE *fp, struct bifrost_header header, bool verbose)
if (header.message_type)
fprintf(fp, "%s ", bi_message_type_name(header.next_message_type));
if (header.unk2)
fprintf(fp, "unk2 ");
if (header.terminate_discarded_threads)
fprintf(fp, "td ");
@@ -663,7 +656,7 @@ static bool dump_clause(FILE *fp, uint32_t *words, unsigned *size, unsigned offs
struct bifrost_header header;
memcpy((char *) &header, (char *) &header_bits, sizeof(struct bifrost_header));
dump_header(fp, header, verbose);
if (!header.no_end_of_shader)
if (header.flow_control == BIFROST_FLOW_END)
stopbit = true;
fprintf(fp, "{\n");