fd6_zsa_state_create(struct pipe_context *pctx,
const struct pipe_depth_stencil_alpha_state *cso)
{
+ struct fd_context *ctx = fd_context(pctx);
struct fd6_zsa_stateobj *so;
so = CALLOC_STRUCT(fd6_zsa_stateobj);
so->base = *cso;
- switch (cso->depth.func) {
- case PIPE_FUNC_LESS:
- case PIPE_FUNC_LEQUAL:
- so->gras_lrz_cntl = A6XX_GRAS_LRZ_CNTL_ENABLE;
- break;
-
- case PIPE_FUNC_GREATER:
- case PIPE_FUNC_GEQUAL:
- so->gras_lrz_cntl = A6XX_GRAS_LRZ_CNTL_ENABLE | A6XX_GRAS_LRZ_CNTL_GREATER;
- break;
-
- default:
- /* LRZ not enabled */
- so->gras_lrz_cntl = 0;
- break;
- }
-
- if (!(cso->stencil->enabled || cso->alpha.enabled || !cso->depth.writemask))
- so->lrz_write = true;
-
so->rb_depth_cntl |=
A6XX_RB_DEPTH_CNTL_ZFUNC(cso->depth.func); /* maps 1:1 */
- if (cso->depth.enabled)
+ if (cso->depth.enabled) {
so->rb_depth_cntl |=
A6XX_RB_DEPTH_CNTL_Z_ENABLE |
A6XX_RB_DEPTH_CNTL_Z_TEST_ENABLE;
+ so->gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_Z_TEST_ENABLE;
+
+ if (cso->depth.writemask) {
+ so->lrz_write = true;
+ }
+
+ switch (cso->depth.func) {
+ case PIPE_FUNC_LESS:
+ case PIPE_FUNC_LEQUAL:
+ so->gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_ENABLE;
+ so->rb_lrz_cntl |= A6XX_RB_LRZ_CNTL_ENABLE;
+ break;
+
+ case PIPE_FUNC_GREATER:
+ case PIPE_FUNC_GEQUAL:
+ so->gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_ENABLE | A6XX_GRAS_LRZ_CNTL_GREATER;
+ so->rb_lrz_cntl |= A6XX_RB_LRZ_CNTL_ENABLE;
+ break;
+
+ case PIPE_FUNC_NEVER:
+ so->gras_lrz_cntl |= A6XX_GRAS_LRZ_CNTL_ENABLE;
+ so->rb_lrz_cntl |= A6XX_RB_LRZ_CNTL_ENABLE;
+ so->lrz_write = false;
+ break;
+
+ case PIPE_FUNC_EQUAL:
+ case PIPE_FUNC_NOTEQUAL:
+ case PIPE_FUNC_ALWAYS:
+ so->lrz_write = false;
+ so->invalidate_lrz = true;
+ break;
+ }
+ }
+
if (cso->depth.writemask)
so->rb_depth_cntl |= A6XX_RB_DEPTH_CNTL_Z_WRITE_ENABLE;
if (cso->stencil[0].enabled) {
const struct pipe_stencil_state *s = &cso->stencil[0];
+ /* stencil test happens before depth test, so without performing
+ * stencil test we don't really know what the updates to the
+ * depth buffer will be.
+ */
+ so->lrz_write = false;
+ so->invalidate_lrz = true;
+
so->rb_stencil_control |=
A6XX_RB_STENCIL_CONTROL_STENCIL_READ |
A6XX_RB_STENCIL_CONTROL_STENCIL_ENABLE |
A6XX_RB_STENCIL_CONTROL_ZPASS_BF(fd_stencil_op(bs->zpass_op)) |
A6XX_RB_STENCIL_CONTROL_ZFAIL_BF(fd_stencil_op(bs->zfail_op));
- // TODO backface stencil state?
+ so->rb_stencilmask |= A6XX_RB_STENCILMASK_BFMASK(bs->valuemask);
+ so->rb_stencilwrmask |= A6XX_RB_STENCILWRMASK_BFWRMASK(bs->writemask);
}
}
// A6XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE;
}
+ so->stateobj = fd_ringbuffer_new_object(ctx->pipe, 9 * 4);
+ struct fd_ringbuffer *ring = so->stateobj;
+
+ OUT_PKT4(ring, REG_A6XX_RB_ALPHA_CONTROL, 1);
+ OUT_RING(ring, so->rb_alpha_control);
+
+ OUT_PKT4(ring, REG_A6XX_RB_STENCIL_CONTROL, 1);
+ OUT_RING(ring, so->rb_stencil_control);
+
+ OUT_PKT4(ring, REG_A6XX_RB_DEPTH_CNTL, 1);
+ OUT_RING(ring, so->rb_depth_cntl);
+
+ OUT_PKT4(ring, REG_A6XX_RB_STENCILMASK, 2);
+ OUT_RING(ring, so->rb_stencilmask);
+ OUT_RING(ring, so->rb_stencilwrmask);
+
+ so->stateobj_no_alpha = fd_ringbuffer_new_object(ctx->pipe, 9 * 4);
+ ring = so->stateobj_no_alpha;
+
+ OUT_PKT4(ring, REG_A6XX_RB_ALPHA_CONTROL, 1);
+ OUT_RING(ring, so->rb_alpha_control & ~A6XX_RB_ALPHA_CONTROL_ALPHA_TEST);
+
+ OUT_PKT4(ring, REG_A6XX_RB_STENCIL_CONTROL, 1);
+ OUT_RING(ring, so->rb_stencil_control);
+
+ OUT_PKT4(ring, REG_A6XX_RB_DEPTH_CNTL, 1);
+ OUT_RING(ring, so->rb_depth_cntl);
+
+ OUT_PKT4(ring, REG_A6XX_RB_STENCILMASK, 2);
+ OUT_RING(ring, so->rb_stencilmask);
+ OUT_RING(ring, so->rb_stencilwrmask);
+
return so;
}
+
+void
+fd6_depth_stencil_alpha_state_delete(struct pipe_context *pctx, void *hwcso)
+{
+ struct fd6_zsa_stateobj *so = hwcso;
+
+ fd_ringbuffer_del(so->stateobj);
+ fd_ringbuffer_del(so->stateobj_no_alpha);
+ FREE(hwcso);
+}