From d84ee4902750c1363507af5b3d65b0d6012d7d24 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Fri, 5 Apr 2019 05:16:32 +0000 Subject: [PATCH] panfrost: Add tilebuffer load? branch Also document branches better. Signed-off-by: Alyssa Rosenzweig --- .../drivers/panfrost/midgard/disassemble.c | 4 +++ .../drivers/panfrost/midgard/midgard.h | 34 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/panfrost/midgard/disassemble.c b/src/gallium/drivers/panfrost/midgard/disassemble.c index 376c8f46956..e9ff3808318 100644 --- a/src/gallium/drivers/panfrost/midgard/disassemble.c +++ b/src/gallium/drivers/panfrost/midgard/disassemble.c @@ -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; diff --git a/src/gallium/drivers/panfrost/midgard/midgard.h b/src/gallium/drivers/panfrost/midgard/midgard.h index b2849aa0fee..335ea5c56cc 100644 --- a/src/gallium/drivers/panfrost/midgard/midgard.h +++ b/src/gallium/drivers/panfrost/midgard/midgard.h @@ -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 -- 2.30.2