nv50: depth_stencil_alpha stateobj
authorBen Skeggs <skeggsb@gmail.com>
Tue, 11 Mar 2008 16:41:05 +0000 (03:41 +1100)
committerBen Skeggs <skeggsb@gmail.com>
Tue, 11 Mar 2008 16:41:05 +0000 (03:41 +1100)
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_state.c
src/gallium/drivers/nv50/nv50_state_validate.c

index 98b9aba07964c45c7283be31b86fa8858aadaeb4..930276489407ae0c93eb18cc00bcb19fcc284941 100644 (file)
 #define NOUVEAU_MSG(fmt, args...) \
        fprintf(stderr, "nouveau: "fmt, ##args);
 
-#define NV50_NEW_BLEND (1 << 0)
+#define NV50_NEW_BLEND (1 << 0)
+#define NV50_NEW_ZSA   (1 << 1)
 
 struct nv50_blend_stateobj {
        struct pipe_blend_state pipe;
        struct nouveau_stateobj *so;
 };
 
+struct nv50_zsa_stateobj {
+       struct pipe_depth_stencil_alpha_state pipe;
+       struct nouveau_stateobj *so;
+};
+
 struct nv50_context {
        struct pipe_context pipe;
 
@@ -39,6 +45,7 @@ struct nv50_context {
 
        unsigned dirty;
        struct nv50_blend_stateobj *blend;
+       struct nv50_zsa_stateobj *zsa;
 };
 
 static INLINE struct nv50_context *
index 7a01100fd74eebe411aac2a96ae058b3a8ca8659..8fd4f774e2767dd7d68157087a5f463c1f4a56d7 100644 (file)
@@ -127,17 +127,85 @@ static void *
 nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe,
                        const struct pipe_depth_stencil_alpha_state *cso)
 {
-       return NULL;
+       struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
+       struct nv50_zsa_stateobj *zsa = CALLOC_STRUCT(nv50_zsa_stateobj);
+       struct nouveau_stateobj *so = so_new(64, 0);
+
+       so_method(so, tesla, NV50TCL_DEPTH_WRITE_ENABLE, 1);
+       so_data  (so, cso->depth.writemask ? 1 : 0);
+       if (cso->depth.enabled) {
+               so_method(so, tesla, NV50TCL_DEPTH_TEST_ENABLE, 1);
+               so_data  (so, 1);
+               so_method(so, tesla, NV50TCL_DEPTH_TEST_FUNC, 1);
+               so_data  (so, nvgl_comparison_op(cso->depth.func));
+       } else {
+               so_method(so, tesla, NV50TCL_DEPTH_TEST_ENABLE, 1);
+               so_data  (so, 0);
+       }
+
+       if (cso->stencil[0].enabled) {
+               so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 5);
+               so_data  (so, 1);
+               so_data  (so, nvgl_stencil_op(cso->stencil[0].fail_op));
+               so_data  (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
+               so_data  (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
+               so_data  (so, nvgl_comparison_op(cso->stencil[0].func));
+               so_method(so, tesla, NV50TCL_STENCIL_FRONT_FUNC_REF, 3);
+               so_data  (so, cso->stencil[0].ref_value);
+               so_data  (so, cso->stencil[0].write_mask);
+               so_data  (so, cso->stencil[0].value_mask);
+       } else {
+               so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 1);
+               so_data  (so, 0);
+       }
+
+       if (cso->stencil[1].enabled) {
+               so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 8);
+               so_data  (so, 1);
+               so_data  (so, nvgl_stencil_op(cso->stencil[1].fail_op));
+               so_data  (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
+               so_data  (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
+               so_data  (so, nvgl_comparison_op(cso->stencil[1].func));
+               so_data  (so, cso->stencil[1].ref_value);
+               so_data  (so, cso->stencil[1].write_mask);
+               so_data  (so, cso->stencil[1].value_mask);
+       } else {
+               so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 1);
+               so_data  (so, 0);
+       }
+
+       if (cso->alpha.enabled) {
+               so_method(so, tesla, NV50TCL_ALPHA_TEST_ENABLE, 1);
+               so_data  (so, 1);
+               so_method(so, tesla, NV50TCL_ALPHA_TEST_REF, 2);
+               so_data  (so, fui(cso->alpha.ref));
+               so_data  (so, nvgl_comparison_op(cso->alpha.func));
+       } else {
+               so_method(so, tesla, NV50TCL_ALPHA_TEST_ENABLE, 1);
+               so_data  (so, 0);
+       }
+
+       zsa->pipe = *cso;
+       so_ref(so, &zsa->so);
+       return (void *)zsa;
 }
 
 static void
 nv50_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso)
 {
+       struct nv50_context *nv50 = nv50_context(pipe);
+
+       nv50->zsa = hwcso;
+       nv50->dirty |= NV50_NEW_ZSA;
 }
 
 static void
 nv50_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
 {
+       struct nv50_zsa_stateobj *zsa = hwcso;
+
+       so_ref(NULL, &zsa->so);
+       FREE(zsa);
 }
 
 static void *
index a89d1526c5810c7a92f036be1b2209db2d429c3c..786987c76ad8b06e62488c672e01e66aecb99434 100644 (file)
@@ -8,7 +8,10 @@ nv50_state_validate(struct nv50_context *nv50)
 
        if (nv50->dirty & NV50_NEW_BLEND)
                so_emit(nvws, nv50->blend->so);
+       if (nv50->dirty & NV50_NEW_ZSA)
+               so_emit(nvws, nv50->zsa->so);
 
+       nv50->dirty = 0;
        return TRUE;
 }