Fix the DRI swrast driver for big endian platforms.
[mesa.git] / src / mesa / drivers / dri / swrast / swrast.c
index 282db7f86c6b09c7bca0018a6544b420ebe83dd3..a858af30c1153ae1e1132526fdd980c560130b18 100644 (file)
  * The back-buffer is allocated by the driver and is private.
  */
 
-#include "context.h"
-#include "extensions.h"
-#include "framebuffer.h"
-#include "imports.h"
-#include "renderbuffer.h"
+#include "main/context.h"
+#include "main/extensions.h"
+#include "main/framebuffer.h"
+#include "main/imports.h"
+#include "main/renderbuffer.h"
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
 #include "tnl/tnl.h"
 
 /* sw extensions not associated with some GL version */
 #define need_GL_ARB_shader_objects
+#define need_GL_ARB_vertex_array_object
 #define need_GL_ARB_vertex_program
+#define need_GL_ARB_sync
 #define need_GL_APPLE_vertex_array_object
 #define need_GL_ATI_fragment_shader
+#define need_GL_ATI_separate_stencil
 #define need_GL_EXT_depth_bounds_test
 #define need_GL_EXT_framebuffer_object
 #define need_GL_EXT_framebuffer_blit
 #define need_GL_EXT_gpu_program_parameters
 #define need_GL_EXT_paletted_texture
-#define need_GL_IBM_multimode_draw_arrays
+#define need_GL_EXT_stencil_two_side
 #define need_GL_MESA_resize_buffers
 #define need_GL_NV_vertex_program
 #define need_GL_NV_fragment_program
@@ -93,15 +96,18 @@ const struct dri_extension card_extensions[] =
     { "GL_SGI_color_table",            GL_SGI_color_table_functions },
 
     { "GL_ARB_shader_objects",         GL_ARB_shader_objects_functions },
+    { "GL_ARB_vertex_array_object",    GL_ARB_vertex_array_object_functions },
     { "GL_ARB_vertex_program",         GL_ARB_vertex_program_functions },
+    { "GL_ARB_sync",                   GL_ARB_sync_functions },
     { "GL_APPLE_vertex_array_object",  GL_APPLE_vertex_array_object_functions },
     { "GL_ATI_fragment_shader",                GL_ATI_fragment_shader_functions },
+    { "GL_ATI_separate_stencil",       GL_ATI_separate_stencil_functions },
     { "GL_EXT_depth_bounds_test",      GL_EXT_depth_bounds_test_functions },
     { "GL_EXT_framebuffer_object",     GL_EXT_framebuffer_object_functions },
     { "GL_EXT_framebuffer_blit",       GL_EXT_framebuffer_blit_functions },
     { "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions },
     { "GL_EXT_paletted_texture",       GL_EXT_paletted_texture_functions },
-    { "GL_IBM_multimode_draw_arrays",  GL_IBM_multimode_draw_arrays_functions },
+    { "GL_EXT_stencil_two_side",       GL_EXT_stencil_two_side_functions },
     { "GL_MESA_resize_buffers",                GL_MESA_resize_buffers_functions },
     { "GL_NV_vertex_program",          GL_NV_vertex_program_functions },
     { "GL_NV_fragment_program",                GL_NV_fragment_program_functions },
@@ -143,8 +149,9 @@ swrastFillInModes(__DRIscreen *psp,
        GLX_NONE, GLX_SWAP_UNDEFINED_OML
     };
 
-    u_int8_t depth_bits_array[4];
-    u_int8_t stencil_bits_array[4];
+    uint8_t depth_bits_array[4];
+    uint8_t stencil_bits_array[4];
+    uint8_t msaa_samples_array[1];
 
     depth_bits_array[0] = 0;
     depth_bits_array[1] = 0;
@@ -159,26 +166,38 @@ swrastFillInModes(__DRIscreen *psp,
     stencil_bits_array[2] = 0;
     stencil_bits_array[3] = (stencil_bits == 0) ? 8 : stencil_bits;
 
+    msaa_samples_array[0] = 0;
+
     depth_buffer_factor = 4;
     back_buffer_factor = 2;
 
-    if (pixel_bits == 8) {
+    switch (pixel_bits) {
+    case 8:
        fb_format = GL_RGB;
        fb_type = GL_UNSIGNED_BYTE_2_3_3_REV;
-    }
-    else if (pixel_bits == 16) {
+       break;
+    case 16:
        fb_format = GL_RGB;
        fb_type = GL_UNSIGNED_SHORT_5_6_5;
-    }
-    else {
+       break;
+    case 24:
+       fb_format = GL_BGR;
+       fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+       break;
+    case 32:
        fb_format = GL_BGRA;
        fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+       break;
+    default:
+       fprintf(stderr, "[%s:%u] bad depth %d\n", __func__, __LINE__,
+               pixel_bits);
+       return NULL;
     }
 
     configs = driCreateConfigs(fb_format, fb_type,
                               depth_bits_array, stencil_bits_array,
                               depth_buffer_factor, back_buffer_modes,
-                              back_buffer_factor);
+                              back_buffer_factor, msaa_samples_array, 1);
     if (configs == NULL) {
        fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
                __LINE__);
@@ -194,7 +213,7 @@ driCreateNewScreen(int scrn, const __DRIextension **extensions,
 {
     static const __DRIextension *emptyExtensionList[] = { NULL };
     __DRIscreen *psp;
-    __DRIconfig **configs8, **configs16, **configs32;
+    __DRIconfig **configs8, **configs16, **configs24, **configs32;
 
     (void) data;
 
@@ -211,11 +230,13 @@ driCreateNewScreen(int scrn, const __DRIextension **extensions,
 
     configs8  = swrastFillInModes(psp,  8,  8, 0, 1);
     configs16 = swrastFillInModes(psp, 16, 16, 0, 1);
+    configs24 = swrastFillInModes(psp, 24, 24, 8, 1);
     configs32 = swrastFillInModes(psp, 32, 24, 8, 1);
 
-    configs16 = (__DRIconfig **)driConcatConfigs(configs8, configs16);
-
-    *driver_configs = driConcatConfigs(configs16, configs32);
+    configs16 = driConcatConfigs(configs8, configs16);
+    configs24 = driConcatConfigs(configs16, configs24);
+    *driver_configs = (const __DRIconfig **)
+       driConcatConfigs(configs24, configs32);
 
     driInitExtensions( NULL, card_extensions, GL_FALSE );
 
@@ -247,19 +268,24 @@ static GLuint
 choose_pixel_format(const GLvisual *v)
 {
     if (v->rgbMode) {
-       int bpp = v->rgbBits;
+       int depth = v->rgbBits;
 
-       if (bpp == 32
+       if (depth == 32
            && v->redMask   == 0xff0000
            && v->greenMask == 0x00ff00
            && v->blueMask  == 0x0000ff)
            return PF_A8R8G8B8;
-       else if (bpp == 16
+       else if (depth == 24
+           && v->redMask   == 0xff0000
+           && v->greenMask == 0x00ff00
+           && v->blueMask  == 0x0000ff)
+           return PF_X8R8G8B8;
+       else if (depth == 16
            && v->redMask   == 0xf800
            && v->greenMask == 0x07e0
            && v->blueMask  == 0x001f)
            return PF_R5G6B5;
-       else if (bpp == 8
+       else if (depth == 8
            && v->redMask   == 0x07
            && v->greenMask == 0x38
            && v->blueMask  == 0xc0)
@@ -288,7 +314,6 @@ swrast_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
                           GLenum internalFormat, GLuint width, GLuint height)
 {
     struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
-    int bpp;
     unsigned mask = PITCH_ALIGN_BITS - 1;
 
     TRACE;
@@ -297,23 +322,8 @@ swrast_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
     rb->Width = width;
     rb->Height = height;
 
-    switch (internalFormat) {
-    case GL_RGB:
-       bpp = rb->RedBits + rb->GreenBits + rb->BlueBits;
-       break;
-    case GL_RGBA:
-       bpp = rb->RedBits + rb->GreenBits + rb->BlueBits + rb->AlphaBits;
-       break;
-    case GL_COLOR_INDEX8_EXT:
-       bpp = rb->IndexBits;
-       break;
-    default:
-       _mesa_problem( NULL, "unexpected format in %s", __FUNCTION__ );
-       return GL_FALSE;
-    }
-
     /* always pad to PITCH_ALIGN_BITS */
-    xrb->pitch = ((width * bpp + mask) & ~mask) / 8;
+    xrb->pitch = ((width * xrb->bpp + mask) & ~mask) / 8;
 
     return GL_TRUE;
 }
@@ -369,6 +379,17 @@ swrast_new_renderbuffer(const GLvisual *visual, GLboolean front)
        xrb->Base.GreenBits = 8 * sizeof(GLubyte);
        xrb->Base.BlueBits  = 8 * sizeof(GLubyte);
        xrb->Base.AlphaBits = 8 * sizeof(GLubyte);
+       xrb->bpp = 32;
+       break;
+    case PF_X8R8G8B8:
+       xrb->Base.InternalFormat = GL_RGB;
+       xrb->Base._BaseFormat = GL_RGB;
+       xrb->Base.DataType = GL_UNSIGNED_BYTE;
+       xrb->Base.RedBits   = 8 * sizeof(GLubyte);
+       xrb->Base.GreenBits = 8 * sizeof(GLubyte);
+       xrb->Base.BlueBits  = 8 * sizeof(GLubyte);
+       xrb->Base.AlphaBits = 0;
+       xrb->bpp = 32;
        break;
     case PF_R5G6B5:
        xrb->Base.InternalFormat = GL_RGB;
@@ -378,6 +399,7 @@ swrast_new_renderbuffer(const GLvisual *visual, GLboolean front)
        xrb->Base.GreenBits = 6 * sizeof(GLubyte);
        xrb->Base.BlueBits  = 5 * sizeof(GLubyte);
        xrb->Base.AlphaBits = 0;
+       xrb->bpp = 16;
        break;
     case PF_R3G3B2:
        xrb->Base.InternalFormat = GL_RGB;
@@ -387,12 +409,14 @@ swrast_new_renderbuffer(const GLvisual *visual, GLboolean front)
        xrb->Base.GreenBits = 3 * sizeof(GLubyte);
        xrb->Base.BlueBits  = 2 * sizeof(GLubyte);
        xrb->Base.AlphaBits = 0;
+       xrb->bpp = 8;
        break;
     case PF_CI8:
        xrb->Base.InternalFormat = GL_COLOR_INDEX8_EXT;
        xrb->Base._BaseFormat = GL_COLOR_INDEX;
        xrb->Base.DataType = GL_UNSIGNED_BYTE;
        xrb->Base.IndexBits = 8 * sizeof(GLubyte);
+       xrb->bpp = 8;
        break;
     default:
        return NULL;
@@ -456,7 +480,7 @@ driDestroyDrawable(__DRIdrawable *buf)
        _mesa_free(buf->row);
 
        fb->DeletePending = GL_TRUE;
-       _mesa_unreference_framebuffer(&fb);
+       _mesa_reference_framebuffer(&fb, NULL);
     }
 }
 
@@ -695,7 +719,6 @@ static int driUnbindContext(__DRIcontext *ctx)
 {
     TRACE;
     (void) ctx;
-    _mesa_make_current(NULL, NULL, NULL);
     return GL_TRUE;
 }