panfrost: Add tilebuffer load? branch
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Fri, 5 Apr 2019 05:16:32 +0000 (05:16 +0000)
committerAlyssa Rosenzweig <alyssa@rosenzweig.io>
Sun, 7 Apr 2019 15:58:44 +0000 (15:58 +0000)
Also document branches better.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
src/gallium/drivers/panfrost/midgard/disassemble.c
src/gallium/drivers/panfrost/midgard/midgard.h

index 376c8f46956b3df9054f8f5bd361ff9b30065458..e9ff38083188b60a386055137e237c52e562c416 100644 (file)
@@ -385,6 +385,10 @@ print_branch_op(int op)
                 printf("write.");
                 break;
 
+        case midgard_jmp_writeout_op_tilebuffer_pending:
+                printf("tilebuffer.");
+                break;
+
         case midgard_jmp_writeout_op_discard:
                 printf("discard.");
                 break;
index b2849aa0fee9b15f43f09f5b36ca7e712b0e02af..335ea5c56cceef0729c529ab3765e6e61de27969 100644 (file)
@@ -219,18 +219,50 @@ __attribute__((__packed__))
 }
 midgard_reg_info;
 
+/* In addition to conditional branches and jumps (unconditional branches),
+ * Midgard implements a bit of fixed function functionality used in fragment
+ * shaders via specially crafted branches. These have special branch opcodes,
+ * which perform a fixed-function operation and/or use the results of a
+ * fixed-function operation as the branch condition.  */
+
 typedef enum {
+        /* Regular branches */
         midgard_jmp_writeout_op_branch_uncond = 1,
         midgard_jmp_writeout_op_branch_cond = 2,
+
+        /* In a fragment shader, execute a discard_if instruction, with the
+         * corresponding condition code. Terminates the shader, so generally
+         * set the branch target to out of the shader */
         midgard_jmp_writeout_op_discard = 4,
+
+        /* Branch if the tilebuffer is not yet ready. At the beginning of a
+         * fragment shader that reads from the tile buffer, for instance via
+         * ARM_shader_framebuffer_fetch or EXT_pixel_local_storage, this branch
+         * operation should be used as a loop. An instruction like
+         * "br.tilebuffer.always -1" does the trick, corresponding to
+         * "while(!is_tilebuffer_ready) */
+        midgard_jmp_writeout_op_tilebuffer_pending = 6,
+
+        /* In a fragment shader, try to write out the value pushed to r0 to the
+         * tilebuffer, subject to unknown state in r1.z and r1.w. If this
+         * succeeds, the shader terminates. If it fails, it branches to the
+         * specified branch target. Generally, this should be used in a loop to
+         * itself, acting as "do { write(r0); } while(!write_successful);" */
         midgard_jmp_writeout_op_writeout = 7,
 } midgard_jmp_writeout_op;
 
 typedef enum {
         midgard_condition_write0 = 0,
+
+        /* These condition codes denote a conditional branch on FALSE and on
+         * TRUE respectively */
         midgard_condition_false = 1,
         midgard_condition_true = 2,
-        midgard_condition_always = 3, /* Special for writeout/uncond discard */
+
+        /* This condition code always branches. For a pure branch, the
+         * unconditional branch coding should be used instead, but for
+         * fixed-function branch opcodes, this is still useful */
+        midgard_condition_always = 3,
 } midgard_condition;
 
 typedef struct