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:
@@ -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,
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user