nv50: implement depth clamp
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Fri, 23 Jul 2010 10:03:33 +0000 (12:03 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Fri, 23 Jul 2010 13:53:15 +0000 (15:53 +0200)
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_state.c
src/gallium/drivers/nv50/nv50_state_validate.c

index 9c672a0..12c4a93 100644 (file)
@@ -50,6 +50,7 @@
 #define NV50_NEW_SAMPLER       (1 << 15)
 #define NV50_NEW_TEXTURE       (1 << 16)
 #define NV50_NEW_STENCIL_REF   (1 << 17)
+#define NV50_NEW_CLIP          (1 << 18)
 
 struct nv50_blend_stateobj {
        struct pipe_blend_state pipe;
@@ -140,6 +141,7 @@ struct nv50_context {
        struct pipe_scissor_state scissor;
        struct pipe_viewport_state viewport;
        struct pipe_framebuffer_state framebuffer;
+       struct pipe_clip_state clip;
        struct nv50_program *vertprog;
        struct nv50_program *fragprog;
        struct nv50_program *geomprog;
index 21908bc..ca4b01b 100644 (file)
@@ -186,6 +186,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_MAX_VS_TEMPS:
        case PIPE_CAP_MAX_FS_TEMPS: /* no spilling atm */
                return 128 / 4;
+       case PIPE_CAP_DEPTH_CLAMP:
+               return 1;
        default:
                NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
                return 0;
@@ -525,6 +527,9 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
        OUT_RINGf (chan, 0.0f);
        OUT_RINGf (chan, 1.0f);
 
+       BEGIN_RING(chan, screen->tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
+       OUT_RING  (chan, 1);
+
        /* no dynamic combination of TIC & TSC entries => only BIND_TIC used */
        BEGIN_RING(chan, screen->tesla, NV50TCL_LINKED_TSC, 1);
        OUT_RING  (chan, 1);
index f8bff76..42c5a58 100644 (file)
@@ -658,6 +658,10 @@ static void
 nv50_set_clip_state(struct pipe_context *pipe,
                    const struct pipe_clip_state *clip)
 {
+       struct nv50_context *nv50 = nv50_context(pipe);
+
+       nv50->clip.depth_clamp = clip->depth_clamp;
+       nv50->dirty |= NV50_NEW_CLIP;
 }
 
 static void
index 14c3490..524696f 100644 (file)
@@ -277,7 +277,7 @@ static struct nouveau_stateobj *
 validate_viewport(struct nv50_context *nv50)
 {
        struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nouveau_stateobj *so = so_new(5, 9, 0);
+       struct nouveau_stateobj *so = so_new(3, 7, 0);
 
        so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
        so_data  (so, fui(nv50->viewport.translate[0]));
@@ -288,15 +288,6 @@ validate_viewport(struct nv50_context *nv50)
        so_data  (so, fui(nv50->viewport.scale[1]));
        so_data  (so, fui(nv50->viewport.scale[2]));
 
-       so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
-       so_data  (so, 1);
-       /* 0x0000 = remove whole primitive only (xyz)
-        * 0x1018 = remove whole primitive only (xy), clamp z
-        * 0x1080 = clip primitive (xyz)
-        * 0x1098 = clip primitive (xy), clamp z
-        */
-       so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
-       so_data  (so, 0x1080);
        /* no idea what 0f90 does */
        so_method(so, tesla, 0x0f90, 1);
        so_data  (so, 0);
@@ -341,6 +332,26 @@ validate_vtxattr(struct nv50_context *nv50)
        return so;
 }
 
+static struct nouveau_stateobj *
+validate_clip(struct nv50_context *nv50)
+{
+       struct nouveau_grobj *tesla = nv50->screen->tesla;
+       struct nouveau_stateobj *so = so_new(1, 1, 0);
+       uint32_t vvcc;
+
+       /* 0x0000 = remove whole primitive only (xyz)
+        * 0x1018 = remove whole primitive only (xy), clamp z
+        * 0x1080 = clip primitive (xyz)
+        * 0x1098 = clip primitive (xy), clamp z
+        */
+       vvcc = nv50->clip.depth_clamp ? 0x1098 : 0x1080;
+
+       so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
+       so_data  (so, vvcc);
+
+       return so;
+}
+
 struct state_validate {
        struct nouveau_stateobj *(*func)(struct nv50_context *nv50);
        unsigned states;
@@ -365,6 +376,7 @@ struct state_validate {
        { nv50_vbo_validate       , NV50_NEW_ARRAYS                           },
        { validate_vtxbuf         , NV50_NEW_ARRAYS                           },
        { validate_vtxattr        , NV50_NEW_ARRAYS                           },
+       { validate_clip           , NV50_NEW_CLIP                             },
        {}
 };
 #define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))