From e63598aecb5d1cc2a20b8db1ef85790e301f4241 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 5 Aug 2014 14:24:29 -0700 Subject: [PATCH] vc4: Add support for gl_FragCoord. This isn't passing all tests (glsl-fs-fragcoord-zw-ortho, for example), but it does get a bunch more tests passing. v2: Rebase on helpers change. --- src/gallium/drivers/vc4/vc4_program.c | 21 +++++++++++++++++- src/gallium/drivers/vc4/vc4_qir.c | 5 +++++ src/gallium/drivers/vc4/vc4_qir.h | 18 ++++++++++++++++ src/gallium/drivers/vc4/vc4_qpu_emit.c | 30 +++++++++++++++++++++++++- src/gallium/drivers/vc4/vc4_screen.c | 6 ++++-- 5 files changed, 76 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c index 8109f635e3b..d871dcd88d3 100644 --- a/src/gallium/drivers/vc4/vc4_program.c +++ b/src/gallium/drivers/vc4/vc4_program.c @@ -569,6 +569,20 @@ emit_vertex_input(struct tgsi_to_qir *trans, int attr) } } +static void +emit_fragcoord_input(struct tgsi_to_qir *trans, int attr) +{ + struct qcompile *c = trans->c; + + trans->inputs[attr * 4 + 0] = qir_FRAG_X(c); + trans->inputs[attr * 4 + 1] = qir_FRAG_Y(c); + trans->inputs[attr * 4 + 2] = + qir_FMUL(c, + qir_FRAG_Z(c), + qir_uniform_f(trans, 1.0 / 0xffffff)); + trans->inputs[attr * 4 + 3] = qir_FRAG_RCP_W(c); +} + static void emit_fragment_input(struct tgsi_to_qir *trans, int attr) { @@ -599,7 +613,12 @@ emit_tgsi_declaration(struct tgsi_to_qir *trans, i <= decl->Range.Last; i++) { if (c->stage == QSTAGE_FRAG) { - emit_fragment_input(trans, i); + if (decl->Semantic.Name == + TGSI_SEMANTIC_POSITION) { + emit_fragcoord_input(trans, i); + } else { + emit_fragment_input(trans, i); + } } else { emit_vertex_input(trans, i); } diff --git a/src/gallium/drivers/vc4/vc4_qir.c b/src/gallium/drivers/vc4/vc4_qir.c index 9462da58660..6509a2bb621 100644 --- a/src/gallium/drivers/vc4/vc4_qir.c +++ b/src/gallium/drivers/vc4/vc4_qir.c @@ -65,6 +65,11 @@ static const struct qir_op_info qir_op_info[] = { [QOP_TLB_COLOR_WRITE] = { "tlb_color", 0, 1, true }, [QOP_VARY_ADD_C] = { "vary_add_c", 1, 1 }, + [QOP_FRAG_X] = { "frag_x", 1, 0 }, + [QOP_FRAG_Y] = { "frag_y", 1, 0 }, + [QOP_FRAG_Z] = { "frag_z", 1, 0 }, + [QOP_FRAG_RCP_W] = { "frag_rcp_w", 1, 0 }, + [QOP_TEX_S] = { "tex_s", 0, 2 }, [QOP_TEX_T] = { "tex_t", 0, 2 }, [QOP_TEX_R] = { "tex_r", 0, 2 }, diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h index 5d1f088ee37..7d9806268fe 100644 --- a/src/gallium/drivers/vc4/vc4_qir.h +++ b/src/gallium/drivers/vc4/vc4_qir.h @@ -74,6 +74,11 @@ enum qop { QOP_TLB_COLOR_WRITE, QOP_VARY_ADD_C, + QOP_FRAG_X, + QOP_FRAG_Y, + QOP_FRAG_Z, + QOP_FRAG_RCP_W, + /** Texture x coordinate parameter write */ QOP_TEX_S, /** Texture y coordinate parameter write */ @@ -204,6 +209,15 @@ bool qir_opt_algebraic(struct qcompile *c); bool qir_opt_copy_propagation(struct qcompile *c); bool qir_opt_dead_code(struct qcompile *c); +#define QIR_ALU0(name) \ +static inline struct qreg \ +qir_##name(struct qcompile *c) \ +{ \ + struct qreg t = qir_get_temp(c); \ + qir_emit(c, qir_inst(QOP_##name, t, c->undef, c->undef)); \ + return t; \ +} + #define QIR_ALU1(name) \ static inline struct qreg \ qir_##name(struct qcompile *c, struct qreg a) \ @@ -257,6 +271,10 @@ QIR_NODST_2(TEX_S) QIR_NODST_2(TEX_T) QIR_NODST_2(TEX_R) QIR_NODST_2(TEX_B) +QIR_ALU0(FRAG_X) +QIR_ALU0(FRAG_Y) +QIR_ALU0(FRAG_Z) +QIR_ALU0(FRAG_RCP_W) static inline struct qreg qir_CMP(struct qcompile *c, struct qreg cmp, struct qreg a, struct qreg b) diff --git a/src/gallium/drivers/vc4/vc4_qpu_emit.c b/src/gallium/drivers/vc4/vc4_qpu_emit.c index 33abf6dcde4..63f37dd8fa0 100644 --- a/src/gallium/drivers/vc4/vc4_qpu_emit.c +++ b/src/gallium/drivers/vc4/vc4_qpu_emit.c @@ -213,7 +213,8 @@ vc4_generate_code(struct qcompile *c) if (qinst->src[i].file == QFILE_TEMP) reg_uses_remaining[qinst->src[i].index]++; } - if (qinst->op == QOP_TLB_PASSTHROUGH_Z_WRITE) + if (qinst->op == QOP_TLB_PASSTHROUGH_Z_WRITE || + qinst->op == QOP_FRAG_Z) reg_in_use[3 + 32 + QPU_R_FRAG_PAYLOAD_ZW] = true; } @@ -460,6 +461,33 @@ vc4_generate_code(struct qcompile *c) break; + case QOP_FRAG_X: + queue(c, qpu_inst(qpu_a_ITOF(dst, + qpu_ra(QPU_R_XY_PIXEL_COORD)), + qpu_m_NOP())); + break; + + case QOP_FRAG_Y: + queue(c, qpu_inst(qpu_a_ITOF(dst, + qpu_rb(QPU_R_XY_PIXEL_COORD)), + qpu_m_NOP())); + break; + + case QOP_FRAG_Z: + queue(c, qpu_inst(qpu_a_ITOF(dst, + qpu_rb(QPU_R_FRAG_PAYLOAD_ZW)), + qpu_m_NOP())); + break; + + case QOP_FRAG_RCP_W: + queue(c, qpu_inst(qpu_a_MOV(qpu_rb(QPU_W_SFU_RECIP), + qpu_ra(QPU_R_FRAG_PAYLOAD_ZW)), + qpu_m_NOP())); + + queue(c, qpu_inst(qpu_a_MOV(dst, qpu_r4()), + qpu_m_NOP())); + break; + case QOP_TLB_PASSTHROUGH_Z_WRITE: queue(c, qpu_inst(qpu_a_MOV(qpu_ra(QPU_W_TLB_Z), qpu_rb(QPU_R_FRAG_PAYLOAD_ZW)), diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c index 940596e47bd..4ddc9acba93 100644 --- a/src/gallium/drivers/vc4/vc4_screen.c +++ b/src/gallium/drivers/vc4/vc4_screen.c @@ -102,6 +102,10 @@ vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_MAX_VIEWPORTS: return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + /* Unsupported features. */ case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: case PIPE_CAP_ANISOTROPIC_FILTER: @@ -111,8 +115,6 @@ vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_SWIZZLE: case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: case PIPE_CAP_SEAMLESS_CUBE_MAP: case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: case PIPE_CAP_TGSI_INSTANCEID: -- 2.30.2