Refactor and fix core vblank support
[mesa.git] / src / mesa / drivers / dri / nouveau / nouveau_context.c
index 319c0481bd474b1487662e11e29f2d53d6d37a25..5ef24d827064a000f044c82dd75e329df48f3177 100644 (file)
@@ -180,7 +180,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
        driParseConfigFiles (&nmesa->optionCache, &screen->optionCache,
                        screen->driScreen->myNum, "nouveau");
 
-       nmesa->sarea = (drm_nouveau_sarea_t *)((char *)sPriv->pSAREA +
+       nmesa->sarea = (struct drm_nouveau_sarea *)((char *)sPriv->pSAREA +
                        screen->sarea_priv_offset);
 
        /* Enable any supported extensions */
@@ -216,14 +216,12 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
        nouveauDDInitState( nmesa );
        switch(nmesa->screen->card->type)
        {
-               case NV_03:
-                       //nv03TriInitFunctions( ctx );
-                       break;
                case NV_04:
                case NV_05:
                        nv04TriInitFunctions( ctx );
                        break;
                case NV_10:
+               case NV_11:
                case NV_17:
                case NV_20:
                case NV_30:
@@ -285,7 +283,7 @@ GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
                struct gl_framebuffer *read_fb =
                        (struct gl_framebuffer*)driReadPriv->driverPrivate;
 
-               driDrawableInitVBlank(driDrawPriv, nmesa->vblank_flags, &nmesa->vblank_seq );
+               driDrawableInitVBlank(driDrawPriv);
                nmesa->driDrawable = driDrawPriv;
 
                _mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
@@ -314,21 +312,24 @@ GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv )
        return GL_TRUE;
 }
 
-static void nouveauDoSwapBuffers(nouveauContextPtr nmesa,
-                                __DRIdrawablePrivate *dPriv)
+void
+nouveauDoSwapBuffers(nouveauContextPtr nmesa, __DRIdrawablePrivate *dPriv)
 {
        struct gl_framebuffer *fb;
-       nouveau_renderbuffer *src, *dst;
+       nouveauScreenPtr screen = dPriv->driScreenPriv->private;
+       nouveau_renderbuffer_t *src;
        drm_clip_rect_t *box;
        int nbox, i;
 
        fb = (struct gl_framebuffer *)dPriv->driverPrivate;
-       dst = (nouveau_renderbuffer*)
-               fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
-       src = (nouveau_renderbuffer*)
-               fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+       if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) {
+               src = (nouveau_renderbuffer_t *)
+                       fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+       } else {
+               src = (nouveau_renderbuffer_t *)
+                       fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+       }
 
-#ifdef ALLOW_MULTI_SUBCHANNEL
        LOCK_HARDWARE(nmesa);
        nbox = dPriv->numClipRects;
        box  = dPriv->pClipRects;
@@ -340,13 +341,14 @@ static void nouveauDoSwapBuffers(nouveauContextPtr nmesa,
                        OUT_RING       (6); /* X8R8G8B8 */
                else
                        OUT_RING       (4); /* R5G6B5 */
-               OUT_RING       ((dst->pitch << 16) | src->pitch);
-               OUT_RING       (src->offset);
-               OUT_RING       (dst->offset);
+               OUT_RING(((screen->frontPitch * screen->fbFormat) << 16) |
+                         src->pitch);
+               OUT_RING(src->offset);
+               OUT_RING(screen->frontOffset);
        }
 
        for (i=0; i<nbox; i++, box++) {
-               BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_POINT, 3);
+               BEGIN_RING_SIZE(NvSubImageBlit, NV_IMAGE_BLIT_POINT_IN, 3);
                OUT_RING       (((box->y1 - dPriv->y) << 16) |
                                (box->x1 - dPriv->x));
                OUT_RING       ((box->y1 << 16) | box->x1);
@@ -356,7 +358,6 @@ static void nouveauDoSwapBuffers(nouveauContextPtr nmesa,
        FIRE_RING();
 
        UNLOCK_HARDWARE(nmesa);
-#endif
 }
 
 void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv)
@@ -377,3 +378,39 @@ void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv,
 {
 }
 
+void nouveauClearBuffer(GLcontext *ctx, nouveau_renderbuffer_t *buffer,
+       int fill, int mask)
+{
+       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+       int dimensions;
+
+       if (!buffer) {
+               return;
+       }
+
+       /* FIXME: only support 32 bits atm */
+
+       /* Surface that we will work on */
+       nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf2D, NvCtxSurf2D);
+
+       BEGIN_RING_SIZE(NvSubCtxSurf2D, NV10_CONTEXT_SURFACES_2D_FORMAT, 4);
+       OUT_RING(0x0b); /* Y32 color format */
+       OUT_RING((buffer->pitch<<16)|buffer->pitch);
+       OUT_RING(buffer->offset);
+       OUT_RING(buffer->offset);
+
+       /* Now clear a rectangle */
+       dimensions = ((buffer->mesa.Height)<<16) | (buffer->mesa.Width);
+
+       nouveauObjectOnSubchannel(nmesa, NvSubGdiRectText, NvGdiRectText);
+
+       BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
+       OUT_RING(3);    /* SRCCOPY */
+
+       BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL1_TL, 5);
+       OUT_RING(0);    /* top left */
+       OUT_RING(dimensions);   /* bottom right */
+       OUT_RING(fill);
+       OUT_RING(0);    /* top left */
+       OUT_RING(dimensions);   /* bottom right */
+}