[PATCH 2/2] nv50: support PIPE_CAP_OPENGL_CLEAR

Christoph Bumiller e0425955 at student.tuwien.ac.at
Sat Apr 10 10:41:52 PDT 2010


---
 src/gallium/drivers/nv50/nv50_clear.c  |   46 ++++++++++++++++++++-----------
 src/gallium/drivers/nv50/nv50_screen.c |    6 ++++
 2 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c
index 5447904..d86f91b 100644
--- a/src/gallium/drivers/nv50/nv50_clear.c
+++ b/src/gallium/drivers/nv50/nv50_clear.c
@@ -26,6 +26,10 @@
 
 #include "nv50_context.h"
 
+/* don't need NEW_BLEND, NV50TCL_COLOR_MASK doesn't affect CLEAR_BUFFERS */
+#define NV50_CLEAR_BUFFERS_STATE \
+ (NV50_NEW_FRAMEBUFFER | NV50_NEW_RASTERIZER | NV50_NEW_ZSA | NV50_NEW_SCISSOR)
+
 void
 nv50_clear(struct pipe_context *pipe, unsigned buffers,
 	   const float *rgba, double depth, unsigned stencil)
@@ -35,37 +39,47 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
 	struct nouveau_grobj *tesla = nv50->screen->tesla;
 	struct pipe_framebuffer_state *fb = &nv50->framebuffer;
 	unsigned mode = 0, i;
-	const unsigned dirty = nv50->dirty;
+	const unsigned dirty = nv50->dirty & ~NV50_CLEAR_BUFFERS_STATE;
 
-	/* don't need NEW_BLEND, NV50TCL_COLOR_MASK doesn't affect CLEAR_BUFFERS */
-	nv50->dirty &= NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR;
+	nv50->dirty &= NV50_CLEAR_BUFFERS_STATE;
 	if (!nv50_state_validate(nv50, 64))
 		return;
 
-	if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
+	if (buffers & PIPE_CLEAR_COLOR) {
+		assert(fb->nr_cbufs);
 		BEGIN_RING(chan, tesla, NV50TCL_CLEAR_COLOR(0), 4);
-		OUT_RING  (chan, fui(rgba[0]));
-		OUT_RING  (chan, fui(rgba[1]));
-		OUT_RING  (chan, fui(rgba[2]));
-		OUT_RING  (chan, fui(rgba[3]));
-		mode |= 0x3c;
+		OUT_RINGf (chan, rgba[0]);
+		OUT_RINGf (chan, rgba[1]);
+		OUT_RINGf (chan, rgba[2]);
+		OUT_RINGf (chan, rgba[3]);
 	}
 
-	if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
+	if (buffers & PIPE_CLEAR_DEPTH) {
 		BEGIN_RING(chan, tesla, NV50TCL_CLEAR_DEPTH, 1);
-		OUT_RING  (chan, fui(depth));
+		OUT_RINGf (chan, depth);
+		mode |= NV50TCL_CLEAR_BUFFERS_Z;
+	}
+	if (buffers & PIPE_CLEAR_STENCIL) {
 		BEGIN_RING(chan, tesla, NV50TCL_CLEAR_STENCIL, 1);
 		OUT_RING  (chan, stencil & 0xff);
+		mode |= NV50TCL_CLEAR_BUFFERS_S;
+	}
 
-		mode |= 0x03;
+	if (!(buffers & PIPE_CLEAR_COLOR)) {
+		BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
+		OUT_RING  (chan, mode);
+		nv50->dirty = dirty;
+		return;
 	}
 
-	BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
-	OUT_RING  (chan, mode);
+	for (i = 0; i < fb->nr_cbufs; ++i, mode = 0) {
+		if (nv50->blend->pipe.independent_blend_enable)
+			mode |= nv50->blend->pipe.rt[i].colormask << 2;
+		else
+			mode |= nv50->blend->pipe.rt[0].colormask << 2;
 
-	for (i = 1; i < fb->nr_cbufs; i++) {
 		BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
-		OUT_RING  (chan, (i << 6) | 0x3c);
+		OUT_RING  (chan, (i << 6) | mode);
 	}
 	nv50->dirty = dirty;
 }
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index a0fe4c5..f7db403 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -148,6 +148,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
 	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
 	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
 		return 0;
+	case PIPE_CAP_OPENGL_CLEAR:
+		return 1;
 	default:
 		NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
 		return 0;
@@ -397,6 +399,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 	BEGIN_RING(chan, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
 	OUT_RING  (chan, 8);
 
+	/* let CLEAR_BUFFERS honour SCISSOR_* and STENCIL_FRONT_MASK */
+	BEGIN_RING(chan, screen->tesla, 0x143c, 1);
+	OUT_RING  (chan, 0x01);
+
 	/* constant buffers for immediates and VP/FP parameters */
 	ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (32 * 4) * 4,
 			     &screen->constbuf_misc[0]);
-- 
1.6.4.4


--------------060706050609060800020905--


More information about the mesa-dev mailing list