radeon: fixup some issue with fbos and sw fallbacks
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_span.c
index 49ec2c378e547528ff056d2c1312249797d437a4..3d2c5da4c0655ad34f632d2764e3821634fd13b8 100644 (file)
@@ -49,19 +49,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define DBG 0
 
+static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb);
+
 static GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb,
                             GLint x, GLint y)
 {
     GLubyte *ptr = rrb->bo->ptr;
-    const __DRIdrawablePrivate *dPriv = rrb->dPriv;
     uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
     GLint offset;
     GLint nmacroblkpl;
     GLint nmicroblkpl;
 
-    x += dPriv->x;
-    y += dPriv->y;
-
     if (rrb->has_surface || !(rrb->bo->flags & mask)) {
         offset = x * rrb->cpp + y * rrb->pitch;
     } else {
@@ -97,15 +95,11 @@ static GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb,
                             GLint x, GLint y)
 {
     GLubyte *ptr = rrb->bo->ptr;
-    const __DRIdrawablePrivate *dPriv = rrb->dPriv;
     uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
     GLint offset;
     GLint nmacroblkpl;
     GLint nmicroblkpl;
 
-    x += dPriv->x;
-    y += dPriv->y;
-
     if (rrb->has_surface || !(rrb->bo->flags & mask)) {
         offset = x * rrb->cpp + y * rrb->pitch;
     } else {
@@ -141,7 +135,6 @@ static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb,
                           GLint x, GLint y)
 {
     GLubyte *ptr = rrb->bo->ptr;
-    const __DRIdrawablePrivate *dPriv = rrb->dPriv;
     uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
     GLint offset;
     GLint microblkxs;
@@ -149,9 +142,6 @@ static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb,
     GLint nmacroblkpl;
     GLint nmicroblkpl;
 
-    x += dPriv->x;
-    y += dPriv->y;
-
     if (rrb->has_surface || !(rrb->bo->flags & mask)) {
         offset = x * rrb->cpp + y * rrb->pitch;
     } else {
@@ -195,25 +185,48 @@ static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb,
  * information.
  */
 #define LOCAL_VARS                                             \
+   struct radeon_context *radeon = RADEON_CONTEXT(ctx);                        \
    struct radeon_renderbuffer *rrb = (void *) rb;              \
-   const __DRIdrawablePrivate *dPriv = rrb->dPriv;             \
-   const GLuint bottom = dPriv->h - 1;                         \
+   const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1;                        \
+   const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\
+   unsigned int num_cliprects;                                         \
+   struct drm_clip_rect *cliprects;                                    \
+   int x_off, y_off;                                                   \
    GLuint p;                                           \
-   (void)p;
+   (void)p;                                            \
+   radeon_get_cliprects(radeon, &cliprects, &num_cliprects, &x_off, &y_off);
 
 #define LOCAL_DEPTH_VARS                               \
+   struct radeon_context *radeon = RADEON_CONTEXT(ctx);                        \
    struct radeon_renderbuffer *rrb = (void *) rb;      \
-   const __DRIdrawablePrivate *dPriv = rrb->dPriv;     \
-   const GLuint bottom = dPriv->h - 1;
+   const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1;                        \
+   const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\
+   unsigned int num_cliprects;                                         \
+   struct drm_clip_rect *cliprects;                                    \
+   int x_off, y_off;                                                   \
+  radeon_get_cliprects(radeon, &cliprects, &num_cliprects, &x_off, &y_off);
 
 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
 
-#define Y_FLIP(Y) (bottom - (Y))
+#define Y_FLIP(_y) ((_y) * yScale + yBias)
 
 #define HW_LOCK()
 
 #define HW_UNLOCK()
 
+/* XXX FBO: this is identical to the macro in spantmp2.h except we get
+ * the cliprect info from the context, not the driDrawable.
+ * Move this into spantmp2.h someday.
+ */
+#define HW_CLIPLOOP()                                                  \
+   do {                                                                        \
+      int _nc = num_cliprects;                                         \
+      while ( _nc-- ) {                                                        \
+        int minx = cliprects[_nc].x1 - x_off;                          \
+        int miny = cliprects[_nc].y1 - y_off;                          \
+        int maxx = cliprects[_nc].x2 - x_off;                          \
+        int maxy = cliprects[_nc].y2 - y_off;
+       
 /* ================================================================
  * Color buffer
  */
@@ -225,7 +238,17 @@ static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb,
 
 #define TAG(x)    radeon##x##_RGB565
 #define TAG2(x,y) radeon##x##_RGB565##y
-#define GET_PTR(X,Y) radeon_ptr16(rrb, (X), (Y))
+#define GET_PTR(X,Y) radeon_ptr16(rrb, (X) + x_off, (Y) + y_off)
+#include "spantmp2.h"
+
+/* 32 bit, xRGB8888 color spanline and pixel functions
+ */
+#define SPANTMP_PIXEL_FMT GL_BGRA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
+
+#define TAG(x)    radeon##x##_xRGB8888
+#define TAG2(x,y) radeon##x##_xRGB8888##y
+#define GET_PTR(X,Y) radeon_ptr32(rrb, (X) + x_off, (Y) + y_off)
 #include "spantmp2.h"
 
 /* 32 bit, ARGB8888 color spanline and pixel functions
@@ -235,7 +258,7 @@ static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb,
 
 #define TAG(x)    radeon##x##_ARGB8888
 #define TAG2(x,y) radeon##x##_ARGB8888##y
-#define GET_PTR(X,Y) radeon_ptr32(rrb, (X), (Y))
+#define GET_PTR(X,Y) radeon_ptr32(rrb, (X) + x_off, (Y) + y_off)
 #include "spantmp2.h"
 
 /* ================================================================
@@ -257,10 +280,10 @@ static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb,
 #define VALUE_TYPE GLushort
 
 #define WRITE_DEPTH( _x, _y, d )                                       \
-   *(GLushort *)radeon_ptr(rrb, _x, _y) = d
+   *(GLushort *)radeon_ptr(rrb, _x + x_off, _y + y_off) = d
 
 #define READ_DEPTH( d, _x, _y )                                                \
-   d = *(GLushort *)radeon_ptr(rrb, _x, _y)
+   d = *(GLushort *)radeon_ptr(rrb, _x + x_off, _y + y_off)
 
 #define TAG(x) radeon##x##_z16
 #include "depthtmp.h"
@@ -275,7 +298,7 @@ static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb,
 #ifdef COMPILE_R300
 #define WRITE_DEPTH( _x, _y, d )                                       \
 do {                                                                   \
-   GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x, _y );                \
+   GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off );                \
    GLuint tmp = *_ptr;                         \
    tmp &= 0x000000ff;                                                  \
    tmp |= ((d << 8) & 0xffffff00);                                     \
@@ -284,8 +307,8 @@ do {                                                                        \
 #else
 #define WRITE_DEPTH( _x, _y, d )                                       \
 do {                                                                   \
-   GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x, _y );                \
-   GLuint tmp = *_ptr;                         \
+   GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off );        \
+   GLuint tmp = *_ptr;                                                 \
    tmp &= 0xff000000;                                                  \
    tmp |= ((d) & 0x00ffffff);                                          \
    *_ptr = tmp;                                        \
@@ -295,11 +318,11 @@ do {                                                                      \
 #ifdef COMPILE_R300
 #define READ_DEPTH( d, _x, _y )                                                \
   do { \
-    d = (*(GLuint*)(radeon_ptr32(rrb, _x, _y)) & 0xffffff00) >> 8; \
+    d = (*(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off)) & 0xffffff00) >> 8; \
   }while(0)
 #else
 #define READ_DEPTH( d, _x, _y )                                                \
-   d = *(GLuint*)(radeon_ptr32(rrb, _x,        _y )) & 0x00ffffff;
+   d = *(GLuint*)(radeon_ptr32(rrb, _x + x_off,        _y + y_off )) & 0x00ffffff;
 #endif
 /*
     fprintf(stderr, "dval(%d, %d, %d, %d)=0x%08X\n", _x, xo, _y, yo, d);\
@@ -317,7 +340,7 @@ do {                                                                        \
 #ifdef COMPILE_R300
 #define WRITE_STENCIL( _x, _y, d )                                     \
 do {                                                                   \
-   GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x, _y);          \
+   GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x + x_off, _y + y_off);          \
    GLuint tmp = *_ptr;                         \
    tmp &= 0xffffff00;                                                  \
    tmp |= (d) & 0xff;                                                  \
@@ -326,7 +349,7 @@ do {                                                                        \
 #else
 #define WRITE_STENCIL( _x, _y, d )                                     \
 do {                                                                   \
-   GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x, _y);          \
+   GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x + x_off, _y + y_off);          \
    GLuint tmp = *_ptr;                         \
    tmp &= 0x00ffffff;                                                  \
    tmp |= (((d) & 0xff) << 24);                                                \
@@ -337,14 +360,14 @@ do {                                                                      \
 #ifdef COMPILE_R300
 #define READ_STENCIL( d, _x, _y )                                      \
 do {                                                                   \
-   GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x, _y );                \
+   GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off );                \
    GLuint tmp = *_ptr;                         \
    d = tmp & 0x000000ff;                                               \
 } while (0)
 #else
 #define READ_STENCIL( d, _x, _y )                                      \
 do {                                                                   \
-   GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x, _y );                \
+   GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off );                \
    GLuint tmp = *_ptr;                         \
    d = (tmp & 0xff000000) >> 24;                                       \
 } while (0)
@@ -354,29 +377,64 @@ do {                                                                      \
 #include "stenciltmp.h"
 
 
-static void map_buffer(struct gl_renderbuffer *rb, GLboolean write)
+void map_unmap_rb(struct gl_renderbuffer *rb, int flag)
 {
-       struct radeon_renderbuffer *rrb = (void*)rb;
+       struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
        int r;
        
-       if (rrb->bo) {
-               r = radeon_bo_map(rrb->bo, write);
+       if (rrb == NULL || !rrb->bo)
+               return;
+
+       if (flag) {
+               r = radeon_bo_map(rrb->bo, 1);
                if (r) {
                        fprintf(stderr, "(%s) error(%d) mapping buffer.\n",
                                __FUNCTION__, r);
                }
+
+               radeonSetSpanFunctions(rrb);
+       } else {
+               radeon_bo_unmap(rrb->bo);
+               rb->GetRow = NULL;
+               rb->PutRow = NULL;
        }
 }
 
-static void unmap_buffer(struct gl_renderbuffer *rb)
+static void
+radeon_map_unmap_buffers(GLcontext *ctx, GLboolean map)
 {
-       struct radeon_renderbuffer *rrb = (void*)rb;
+       radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+       GLuint i, j;
 
-       if (rrb->bo) {
-               radeon_bo_unmap(rrb->bo);
+       /* color draw buffers */
+       for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++)
+               map_unmap_rb(ctx->DrawBuffer->_ColorDrawBuffers[j], map);
+
+       /* check for render to textures */
+       for (i = 0; i < BUFFER_COUNT; i++) {
+               struct gl_renderbuffer_attachment *att =
+                       ctx->DrawBuffer->Attachment + i;
+               struct gl_texture_object *tex = att->Texture;
+               if (tex) {
+                       /* render to texture */
+                       ASSERT(att->Renderbuffer);
+                       if (map)
+                               ctx->Driver.MapTexture(ctx, tex);
+                       else
+                               ctx->Driver.UnmapTexture(ctx, tex);
+               }
        }
-}
+       
+       map_unmap_rb(ctx->ReadBuffer->_ColorReadBuffer, map);
+
+       /* depth buffer (Note wrapper!) */
+       if (ctx->DrawBuffer->_DepthBuffer)
+               map_unmap_rb(ctx->DrawBuffer->_DepthBuffer->Wrapped, map);
+       
+       if (ctx->DrawBuffer->_StencilBuffer)
+               map_unmap_rb(ctx->DrawBuffer->_StencilBuffer->Wrapped, map);
 
+}
 static void radeonSpanRenderStart(GLcontext * ctx)
 {
        radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
@@ -389,18 +447,7 @@ static void radeonSpanRenderStart(GLcontext * ctx)
                        ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current);
        }
 
-       /* color draw buffers */
-       for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
-               map_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i], GL_TRUE);
-       }
-
-       map_buffer(ctx->ReadBuffer->_ColorReadBuffer, GL_FALSE);
-
-       if (ctx->DrawBuffer->_DepthBuffer) {
-               map_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped, GL_TRUE);
-       }
-       if (ctx->DrawBuffer->_StencilBuffer)
-               map_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped, GL_TRUE);
+       radeon_map_unmap_buffers(ctx, 1);
 
        /* The locking and wait for idle should really only be needed in classic mode.
         * In a future memory manager based implementation, this should become
@@ -423,16 +470,7 @@ static void radeonSpanRenderFinish(GLcontext * ctx)
                        ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current);
        }
 
-       /* color draw buffers */
-       for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++)
-               unmap_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i]);
-
-       unmap_buffer(ctx->ReadBuffer->_ColorReadBuffer);
-
-       if (ctx->DrawBuffer->_DepthBuffer)
-               unmap_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped);
-       if (ctx->DrawBuffer->_StencilBuffer)
-               unmap_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped);
+       radeon_map_unmap_buffers(ctx, 0);
 }
 
 void radeonInitSpanFuncs(GLcontext * ctx)
@@ -446,17 +484,21 @@ void radeonInitSpanFuncs(GLcontext * ctx)
 /**
  * Plug in the Get/Put routines for the given driRenderbuffer.
  */
-void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb)
+static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb)
 {
-       if (rrb->base.InternalFormat == GL_RGB5) {
+       if (rrb->base._ActualFormat == GL_RGB5) {
                radeonInitPointers_RGB565(&rrb->base);
-       } else if (rrb->base.InternalFormat == GL_RGBA8) {
+       } else if (rrb->base._ActualFormat == GL_RGB8) {
+               radeonInitPointers_xRGB8888(&rrb->base);
+       } else if (rrb->base._ActualFormat == GL_RGBA8) {
                radeonInitPointers_ARGB8888(&rrb->base);
-       } else if (rrb->base.InternalFormat == GL_DEPTH_COMPONENT16) {
+       } else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT16) {
                radeonInitDepthPointers_z16(&rrb->base);
-       } else if (rrb->base.InternalFormat == GL_DEPTH_COMPONENT24) {
+       } else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT24) {
                radeonInitDepthPointers_z24_s8(&rrb->base);
-       } else if (rrb->base.InternalFormat == GL_STENCIL_INDEX8_EXT) {
+       } else if (rrb->base._ActualFormat == GL_DEPTH24_STENCIL8_EXT) {
+               radeonInitStencilPointers_z24_s8(&rrb->base);
+       } else if (rrb->base._ActualFormat == GL_STENCIL_INDEX8_EXT) {
                radeonInitStencilPointers_z24_s8(&rrb->base);
        }
 }