freedreno/a3xx: handle frag z write
authorRob Clark <robclark@freedesktop.org>
Tue, 14 Jan 2014 18:03:20 +0000 (13:03 -0500)
committerRob Clark <robclark@freedesktop.org>
Sat, 1 Feb 2014 16:58:47 +0000 (11:58 -0500)
Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/a3xx/fd3_compiler.c
src/gallium/drivers/freedreno/a3xx/fd3_draw.c
src/gallium/drivers/freedreno/a3xx/fd3_emit.c
src/gallium/drivers/freedreno/a3xx/fd3_emit.h
src/gallium/drivers/freedreno/a3xx/fd3_program.c
src/gallium/drivers/freedreno/a3xx/fd3_program.h
src/gallium/drivers/freedreno/freedreno_screen.c

index c8e66fc76dd3a0cf9cd41dde3219fc163a6afa3b..2c32c0fa2a7602c8d964f5d431aa02e3b1cfa295 100644 (file)
@@ -1341,6 +1341,7 @@ decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
 {
        struct fd3_shader_stateobj *so = ctx->so;
        unsigned base = ctx->base_reg[TGSI_FILE_OUTPUT];
+       unsigned comp = 0;
        unsigned name = decl->Semantic.Name;
        unsigned i;
 
@@ -1351,6 +1352,8 @@ decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
        if (ctx->type == TGSI_PROCESSOR_VERTEX) {
                switch (name) {
                case TGSI_SEMANTIC_POSITION:
+                       so->writes_pos = true;
+                       /* fallthrough */
                case TGSI_SEMANTIC_PSIZE:
                case TGSI_SEMANTIC_COLOR:
                case TGSI_SEMANTIC_GENERIC:
@@ -1363,6 +1366,10 @@ decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
                }
        } else {
                switch (name) {
+               case TGSI_SEMANTIC_POSITION:
+                       comp = 2;  /* tgsi will write to .z component */
+                       so->writes_pos = true;
+                       /* fallthrough */
                case TGSI_SEMANTIC_COLOR:
                        break;
                default:
@@ -1374,7 +1381,7 @@ decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
        for (i = decl->Range.First; i <= decl->Range.Last; i++) {
                unsigned n = so->outputs_count++;
                so->outputs[n].semantic = decl_semantic(&decl->Semantic);
-               so->outputs[n].regid = regid(i + base, 0);
+               so->outputs[n].regid = regid(i + base, comp);
        }
 }
 
index 4f28b0e0608b7a2be2d8a826a4c12a71fc3e8507..a482aec3decb892e3b7a3454864ba4d5df4c7b05 100644 (file)
@@ -70,7 +70,7 @@ static void
 draw_impl(struct fd_context *ctx, const struct pipe_draw_info *info,
                struct fd_ringbuffer *ring, unsigned dirty, bool binning)
 {
-       fd3_emit_state(ctx, ring, dirty, binning);
+       fd3_emit_state(ctx, ring, &ctx->prog, dirty, binning);
 
        if (dirty & FD_DIRTY_VTXBUF)
                emit_vertexbufs(ctx, ring);
@@ -114,10 +114,7 @@ fd3_clear_binning(struct fd_context *ctx, unsigned dirty)
        struct fd3_context *fd3_ctx = fd3_context(ctx);
        struct fd_ringbuffer *ring = ctx->binning_ring;
 
-       fd3_emit_state(ctx, ring, dirty & (FD_DIRTY_VIEWPORT |
-                       FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR), true);
-
-       fd3_program_emit(ring, &ctx->solid_prog, true);
+       fd3_emit_state(ctx, ring, &ctx->solid_prog, dirty, true);
 
        fd3_emit_vertex_bufs(ring, &ctx->solid_prog, (struct fd3_vertex_buf[]) {
                        { .prsc = fd3_ctx->solid_vbuf, .stride = 12, .format = PIPE_FORMAT_R32G32B32_FLOAT },
@@ -152,11 +149,13 @@ fd3_clear(struct fd_context *ctx, unsigned buffers,
        unsigned dirty = ctx->dirty;
        unsigned ce, i;
 
+       dirty &= FD_DIRTY_VIEWPORT | FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR;
+       dirty |= FD_DIRTY_PROG;
+
        fd3_clear_binning(ctx, dirty);
 
        /* emit generic state now: */
-       fd3_emit_state(ctx, ring, dirty & (FD_DIRTY_VIEWPORT |
-                       FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR), false);
+       fd3_emit_state(ctx, ring, &ctx->solid_prog, dirty, false);
 
        OUT_PKT0(ring, REG_A3XX_RB_BLEND_ALPHA, 1);
        OUT_RING(ring, A3XX_RB_BLEND_ALPHA_UINT(0xff) |
@@ -246,8 +245,6 @@ fd3_clear(struct fd_context *ctx, unsigned buffers,
        OUT_PKT0(ring, REG_A3XX_GRAS_SU_MODE_CONTROL, 1);
        OUT_RING(ring, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0));
 
-       fd3_program_emit(ring, &ctx->solid_prog, false);
-
        fd3_emit_vertex_bufs(ring, &ctx->solid_prog, (struct fd3_vertex_buf[]) {
                        { .prsc = fd3_ctx->solid_vbuf, .stride = 12, .format = PIPE_FORMAT_R32G32B32_FLOAT },
                }, 1);
index 543c116ce2f70a273fb17cad95ab0ad418b151ad..3ca49ff949b2d820d2bd08a386471a58bc2c715a 100644 (file)
@@ -338,7 +338,7 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
 
 void
 fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
-               uint32_t dirty, bool binning)
+               struct fd_program_stateobj *prog, uint32_t dirty, bool binning)
 {
        emit_marker(ring, 5);
 
@@ -370,9 +370,6 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                OUT_PKT0(ring, REG_A3XX_RB_ALPHA_REF, 1);
                OUT_RING(ring, zsa->rb_alpha_ref);
 
-               OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
-               OUT_RING(ring, zsa->rb_depth_control);
-
                OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1);
                OUT_RING(ring, zsa->rb_stencil_control);
 
@@ -383,6 +380,17 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                                A3XX_RB_STENCILREFMASK_BF_STENCILREF(sr->ref_value[1]));
        }
 
+       if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_PROG)) {
+               struct fd3_shader_stateobj *fp = prog->fp;
+               uint32_t val = fd3_zsa_stateobj(ctx->zsa)->rb_depth_control;
+               if (fp->writes_pos) {
+                       val |= A3XX_RB_DEPTH_CONTROL_FRAG_WRITES_Z;
+                       val |= A3XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE;
+               }
+               OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
+               OUT_RING(ring, val);
+       }
+
        if (dirty & FD_DIRTY_RASTERIZER) {
                struct fd3_rasterizer_stateobj *rasterizer =
                                fd3_rasterizer_stateobj(ctx->rasterizer);
@@ -397,15 +405,23 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                OUT_PKT0(ring, REG_A3XX_GRAS_SU_POLY_OFFSET_SCALE, 2);
                OUT_RING(ring, rasterizer->gras_su_poly_offset_scale);
                OUT_RING(ring, rasterizer->gras_su_poly_offset_offset);
+       }
 
+       if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_PROG)) {
+               struct fd3_shader_stateobj *fp = prog->fp;
+               uint32_t val = fd3_rasterizer_stateobj(ctx->rasterizer)
+                               ->gras_cl_clip_cntl;
+               if (fp->writes_pos) {
+                       val |= A3XX_GRAS_CL_CLIP_CNTL_ZCLIP_DISABLE;
+               }
                OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1);
-               OUT_RING(ring, rasterizer->gras_cl_clip_cntl);
+               OUT_RING(ring, val);
        }
 
        if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_PROG)) {
                struct fd3_rasterizer_stateobj *rasterizer =
                                fd3_rasterizer_stateobj(ctx->rasterizer);
-               struct fd3_shader_stateobj *fp = ctx->prog.fp;
+               struct fd3_shader_stateobj *fp = prog->fp;
                uint32_t stride_in_vpc;
 
                stride_in_vpc = align(fp->total_in, 4) / 4;
@@ -443,14 +459,14 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
        }
 
        if (dirty & FD_DIRTY_PROG)
-               fd3_program_emit(ring, &ctx->prog, binning);
+               fd3_program_emit(ring, prog, binning);
 
        OUT_PKT3(ring, CP_EVENT_WRITE, 1);
        OUT_RING(ring, HLSQ_FLUSH);
 
-       if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) {
-               struct fd_program_stateobj *prog = &ctx->prog;
-
+       if ((dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) &&
+                       /* evil hack to deal sanely with clear path: */
+                       (prog == &ctx->prog)) {
                emit_constants(ring,  SB_VERT_SHADER,
                                &ctx->constbuf[PIPE_SHADER_VERTEX],
                                (prog->dirty & FD_SHADER_DIRTY_VP) ? prog->vp : NULL);
@@ -459,7 +475,7 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                                (prog->dirty & FD_SHADER_DIRTY_FP) ? prog->fp : NULL);
        }
 
-       if (dirty & FD_DIRTY_BLEND) {
+       if ((dirty & FD_DIRTY_BLEND) && ctx->blend) {
                struct fd3_blend_stateobj *blend = fd3_blend_stateobj(ctx->blend);
                uint32_t i;
 
index 1b4774d83f999e6c0e4f6a74514b12a635137d49..8584eb5b59b91f31600f2b92e93569edc176ab2b 100644 (file)
@@ -59,7 +59,7 @@ void fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
                struct fd_program_stateobj *prog,
                struct fd3_vertex_buf *vbufs, uint32_t n);
 void fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
-               uint32_t dirty, bool binning);
+               struct fd_program_stateobj *prog, uint32_t dirty, bool binning);
 void fd3_emit_restore(struct fd_context *ctx);
 
 #endif /* FD3_EMIT_H */
index 2d95583666d342d1d1fe0ff0305123fcb3f13e5e..3df29ecc91151e260cc26042cb3d4bfb30763087 100644 (file)
@@ -247,7 +247,7 @@ fd3_program_emit(struct fd_ringbuffer *ring,
        const struct fd3_shader_stateobj *fp = prog->fp;
        const struct ir3_shader_info *vsi = &vp->info;
        const struct ir3_shader_info *fsi = &fp->info;
-       uint32_t pos_regid, psize_regid, color_regid;
+       uint32_t pos_regid, posz_regid, psize_regid, color_regid;
        int i;
 
        if (binning) {
@@ -259,6 +259,8 @@ fd3_program_emit(struct fd_ringbuffer *ring,
 
        pos_regid = find_regid(vp,
                fd3_semantic_name(TGSI_SEMANTIC_POSITION, 0));
+       posz_regid = find_regid(fp,
+               fd3_semantic_name(TGSI_SEMANTIC_POSITION, 0));
        psize_regid = find_regid(vp,
                fd3_semantic_name(TGSI_SEMANTIC_PSIZE, 0));
        color_regid = find_regid(fp,
@@ -389,7 +391,12 @@ fd3_program_emit(struct fd_ringbuffer *ring,
        OUT_RING(ring, 0x00000000);        /* SP_FS_FLAT_SHAD_MODE_REG_1 */
 
        OUT_PKT0(ring, REG_A3XX_SP_FS_OUTPUT_REG, 1);
-       OUT_RING(ring, 0x00000000);        /* SP_FS_OUTPUT_REG */
+       if (fp->writes_pos) {
+               OUT_RING(ring, A3XX_SP_FS_OUTPUT_REG_DEPTH_ENABLE |
+                               A3XX_SP_FS_OUTPUT_REG_DEPTH_REGID(posz_regid));
+       } else {
+               OUT_RING(ring, 0x00000000);
+       }
 
        OUT_PKT0(ring, REG_A3XX_SP_FS_MRT_REG(0), 4);
        OUT_RING(ring, A3XX_SP_FS_MRT_REG_REGID(color_regid) |
index e7aaa4763168c9ef9489d98fe030db0cbbf33a6d..4aeeb2e30062c8be3ef222f3b0693bb881151c31 100644 (file)
@@ -81,6 +81,7 @@ struct fd3_shader_stateobj {
                fd3_semantic semantic;
                uint8_t regid;
        } outputs[16];
+       bool writes_pos;
 
        /* vertices/inputs: */
        unsigned inputs_count;
index f36bd8be0cdccc1a983d11ed4cafda05ef000bfb..d6d3c6c3fd94b4a6681d202ad433cf18e142945e 100644 (file)
@@ -153,7 +153,6 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
        case PIPE_CAP_TEXTURE_SWIZZLE:
-       case PIPE_CAP_SHADER_STENCIL_EXPORT:
        case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
        case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
@@ -176,6 +175,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_USER_CONSTANT_BUFFERS:
                return 1;
 
+       case PIPE_CAP_SHADER_STENCIL_EXPORT:
        case PIPE_CAP_TGSI_TEXCOORD:
        case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
                return 0;