intel: Add support for argb1555, argb4444 FBOs and fix rgb565 fbo readpixels.
authorEric Anholt <eric@anholt.net>
Fri, 10 Apr 2009 01:30:12 +0000 (18:30 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 16 Apr 2009 19:04:30 +0000 (12:04 -0700)
Also enable them all regardless of screen bpp, as 32 bpp what I've been
testing against, and haven't been able to detect any screen bpp-specific
troubles with them.

src/mesa/drivers/dri/common/spantmp2.h
src/mesa/drivers/dri/i915/i830_vtbl.c
src/mesa/drivers/dri/i915/i915_vtbl.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c
src/mesa/drivers/dri/intel/intel_blit.c
src/mesa/drivers/dri/intel/intel_context.h
src/mesa/drivers/dri/intel/intel_fbo.c
src/mesa/drivers/dri/intel/intel_fbo.h
src/mesa/drivers/dri/intel/intel_span.c

index f2868cb58a6a964942e2985827bd29a6c8fabafd..89c815722f6a2a7e70ae6020c6c7a7454d44453c 100644 (file)
       rgba[3] = 0xff;                                                  \
    } while (0)
 
+#elif (SPANTMP_PIXEL_FMT == GL_BGRA)  && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_4_4_4_4_REV)
+
+/**
+ ** GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV
+ **/
+
+#ifndef GET_VALUE
+#ifndef GET_PTR
+#define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch)
+#endif
+
+#define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y))
+#define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v)
+#endif /* GET_VALUE */
+
+#define INIT_MONO_PIXEL(p, color) \
+   p = PACK_COLOR_4444(color[3], color[0], color[1], color[2])
+
+#define WRITE_RGBA( _x, _y, r, g, b, a )                               \
+   PUT_VALUE(_x, _y, PACK_COLOR_4444(a, r, g, b))                      \
+
+#define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p)
+
+#define READ_RGBA( rgba, _x, _y )                                      \
+   do {                                                                        \
+      GLushort p = GET_VALUE(_x, _y);                                  \
+      rgba[0] = ((p >> 8) & 0xf) * 0x11;                               \
+      rgba[1] = ((p >> 4) & 0xf) * 0x11;                               \
+      rgba[2] = ((p >> 0) & 0xf) * 0x11;                               \
+      rgba[3] = ((p >> 12) & 0xf) * 0x11;                              \
+   } while (0)
+
+
+#elif (SPANTMP_PIXEL_FMT == GL_BGRA)  && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_1_5_5_5_REV)
+
+/**
+ ** GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV
+ **/
+
+#ifndef GET_VALUE
+#ifndef GET_PTR
+#define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch)
+#endif
+
+#define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y))
+#define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v)
+#endif /* GET_VALUE */
+
+#define INIT_MONO_PIXEL(p, color) \
+   p = PACK_COLOR_1555(color[3], color[0], color[1], color[2])
+
+#define WRITE_RGBA( _x, _y, r, g, b, a )                               \
+   PUT_VALUE(_x, _y, PACK_COLOR_1555(a, r, g, b))                      \
+
+#define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p)
+
+#define READ_RGBA( rgba, _x, _y )                                      \
+   do {                                                                        \
+      GLushort p = GET_VALUE(_x, _y);                                  \
+      rgba[0] = ((p >> 7) & 0xf8) * 255 / 0xf8;                                \
+      rgba[1] = ((p >> 2) & 0xf8) * 255 / 0xf8;                                \
+      rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8;                                \
+      rgba[3] = ((p >> 15) & 0x1) * 0xff;                              \
+   } while (0)
+
 #elif (SPANTMP_PIXEL_FMT == GL_BGRA) && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV)
 
 /**
index 1a94921078980028f4c1f96b1ebd2fcc458cd9b4..3bf02de61f8d29263a43cf9697a360271650535b 100644 (file)
  **************************************************************************/
 
 #include "glapi/glapi.h"
+#include "main/texformat.h"
 
 #include "i830_context.h"
 #include "i830_reg.h"
 #include "intel_batchbuffer.h"
 #include "intel_regions.h"
 #include "intel_tris.h"
+#include "intel_fbo.h"
 #include "tnl/t_context.h"
 #include "tnl/t_vertex.h"
 
@@ -614,6 +616,8 @@ i830_state_draw_region(struct intel_context *intel,
 {
    struct i830_context *i830 = i830_context(&intel->ctx);
    GLcontext *ctx = &intel->ctx;
+   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
+   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
    GLuint value;
 
    ASSERT(state == &i830->state || state == &i830->meta);
@@ -651,13 +655,27 @@ i830_state_draw_region(struct intel_context *intel,
     */
    value = (DSTORG_HORT_BIAS(0x8) |     /* .5 */
             DSTORG_VERT_BIAS(0x8) | DEPTH_IS_Z);    /* .5 */
-            
-   if (color_region && color_region->cpp == 4) {
-      value |= DV_PF_8888;
-   }
-   else {
-      value |= DV_PF_565;
+
+   if (irb != NULL) {
+      switch (irb->texformat->MesaFormat) {
+      case MESA_FORMAT_ARGB8888:
+        value |= DV_PF_8888;
+        break;
+      case MESA_FORMAT_RGB565:
+        value |= DV_PF_565;
+        break;
+      case MESA_FORMAT_ARGB1555:
+        value |= DV_PF_1555;
+        break;
+      case MESA_FORMAT_ARGB4444:
+        value |= DV_PF_4444;
+        break;
+      default:
+        _mesa_problem(ctx, "Bad renderbuffer format: %d\n",
+                      irb->texformat->MesaFormat);
+      }
    }
+
    if (depth_region && depth_region->cpp == 4) {
       value |= DEPTH_FRMT_24_FIXED_8_OTHER;
    }
index 3f6d282d3420bd845a7b47447216873accf3cca1..115004616ff5cf74a49833ad23c7cfd843c28128 100644 (file)
@@ -32,6 +32,7 @@
 #include "main/imports.h"
 #include "main/macros.h"
 #include "main/colormac.h"
+#include "main/texformat.h"
 
 #include "tnl/t_context.h"
 #include "tnl/t_vertex.h"
@@ -40,6 +41,7 @@
 #include "intel_tex.h"
 #include "intel_regions.h"
 #include "intel_tris.h"
+#include "intel_fbo.h"
 
 #include "i915_reg.h"
 #include "i915_context.h"
@@ -542,6 +544,8 @@ i915_state_draw_region(struct intel_context *intel,
 {
    struct i915_context *i915 = i915_context(&intel->ctx);
    GLcontext *ctx = &intel->ctx;
+   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
+   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
    GLuint value;
 
    ASSERT(state == &i915->state || state == &i915->meta);
@@ -580,12 +584,26 @@ i915_state_draw_region(struct intel_context *intel,
    value = (DSTORG_HORT_BIAS(0x8) |     /* .5 */
             DSTORG_VERT_BIAS(0x8) |     /* .5 */
             LOD_PRECLAMP_OGL | TEX_DEFAULT_COLOR_OGL);
-   if (color_region && color_region->cpp == 4) {
-      value |= DV_PF_8888;
-   }
-   else {
-      value |= (DITHER_FULL_ALWAYS | DV_PF_565);
+   if (irb != NULL) {
+      switch (irb->texformat->MesaFormat) {
+      case MESA_FORMAT_ARGB8888:
+        value |= DV_PF_8888;
+        break;
+      case MESA_FORMAT_RGB565:
+        value |= DV_PF_565 | DITHER_FULL_ALWAYS;
+        break;
+      case MESA_FORMAT_ARGB1555:
+        value |= DV_PF_1555 | DITHER_FULL_ALWAYS;
+        break;
+      case MESA_FORMAT_ARGB4444:
+        value |= DV_PF_4444 | DITHER_FULL_ALWAYS;
+        break;
+      default:
+        _mesa_problem(ctx, "Bad renderbuffer format: %d\n",
+                      irb->texformat->MesaFormat);
+      }
    }
+
    if (depth_region && depth_region->cpp == 4) {
       value |= DEPTH_FRMT_24_FIXED_8_OTHER;
    }
index ce5dbb334b829747dc06f7f6c721d9feb3cc7387..0dc377be656fadb70bd2879e30f50bb5ada2925e 100644 (file)
@@ -38,7 +38,7 @@
 #include "intel_mipmap_tree.h"
 #include "intel_batchbuffer.h"
 #include "intel_tex.h"
-
+#include "intel_fbo.h"
 
 #include "brw_context.h"
 #include "brw_state.h"
@@ -505,15 +505,18 @@ brw_update_vs_constant_surface( GLcontext *ctx,
  * usable for further buffers when doing ARB_draw_buffer support.
  */
 static void
-brw_update_region_surface(struct brw_context *brw, struct intel_region *region,
-                         unsigned int unit, GLboolean cached)
+brw_update_renderbuffer_surface(struct brw_context *brw,
+                               struct gl_renderbuffer *rb,
+                               unsigned int unit, GLboolean cached)
 {
    GLcontext *ctx = &brw->intel.ctx;
    dri_bo *region_bo = NULL;
+   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+   struct intel_region *region = irb ? irb->region : NULL;
    struct {
       unsigned int surface_type;
       unsigned int surface_format;
-      unsigned int width, height, cpp;
+      unsigned int width, height, pitch, cpp;
       GLubyte color_mask[4];
       GLboolean color_blend;
       uint32_t tiling;
@@ -525,13 +528,27 @@ brw_update_region_surface(struct brw_context *brw, struct intel_region *region,
       region_bo = region->buffer;
 
       key.surface_type = BRW_SURFACE_2D;
-      if (region->cpp == 4)
+      switch (irb->texformat->MesaFormat) {
+      case MESA_FORMAT_ARGB8888:
         key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-      else
+        break;
+      case MESA_FORMAT_RGB565:
         key.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
+        break;
+      case MESA_FORMAT_ARGB1555:
+        key.surface_format = BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
+        break;
+      case MESA_FORMAT_ARGB4444:
+        key.surface_format = BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
+        break;
+      default:
+        _mesa_problem(ctx, "Bad renderbuffer format: %d\n",
+                      irb->texformat->MesaFormat);
+      }
       key.tiling = region->tiling;
-      key.width = region->pitch; /* XXX: not really! */
-      key.height = region->height;
+      key.width = rb->Width;
+      key.height = rb->Height;
+      key.pitch = region->pitch;
       key.cpp = region->cpp;
    } else {
       key.surface_type = BRW_SURFACE_NULL;
@@ -567,7 +584,7 @@ brw_update_region_surface(struct brw_context *brw, struct intel_region *region,
       surf.ss2.width = key.width - 1;
       surf.ss2.height = key.height - 1;
       brw_set_surface_tiling(&surf, key.tiling);
-      surf.ss3.pitch = (key.width * key.cpp) - 1;
+      surf.ss3.pitch = (key.pitch * key.cpp) - 1;
 
       /* _NEW_COLOR */
       surf.ss0.color_blend = key.color_blend;
@@ -655,14 +672,17 @@ static void prepare_wm_surfaces(struct brw_context *brw )
    GLuint i;
    int old_nr_surfaces;
 
+   /* _NEW_BUFFERS */
    /* Update surfaces for drawing buffers */
-   if (brw->state.nr_color_regions > 1) {
-      for (i = 0; i < brw->state.nr_color_regions; i++) {
-         brw_update_region_surface(brw, brw->state.color_regions[i], i,
-                                  GL_FALSE);
+   if (ctx->DrawBuffer->_NumColorDrawBuffers >= 1) {
+      for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
+         brw_update_renderbuffer_surface(brw,
+                                        ctx->DrawBuffer->_ColorDrawBuffers[i],
+                                        i,
+                                        GL_FALSE);
       }
    } else {
-      brw_update_region_surface(brw, brw->state.color_regions[0], 0, GL_TRUE);
+      brw_update_renderbuffer_surface(brw, NULL, 0, GL_TRUE);
    }
 
    old_nr_surfaces = brw->wm.nr_surfaces;
index 4ae9b118a3dd9ebd108b8121e388109ec99775d8..49198281316944920b249f62a8f9ec29dc80a9ea 100644 (file)
@@ -32,6 +32,8 @@
 #include "main/mtypes.h"
 #include "main/context.h"
 #include "main/enums.h"
+#include "main/texformat.h"
+#include "main/colormac.h"
 
 #include "intel_blit.h"
 #include "intel_buffers.h"
@@ -484,10 +486,9 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
             const GLbitfield bufBit = 1 << buf;
             if ((clearMask & bufBit) && !(bufBit & skipBuffers)) {
                /* OK, clear this renderbuffer */
-               struct intel_region *irb_region =
-                 intel_get_rb_region(fb, buf);
+              struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, buf);
                dri_bo *write_buffer =
-                  intel_region_buffer(intel, irb_region,
+                  intel_region_buffer(intel, irb->region,
                                       all ? INTEL_WRITE_FULL :
                                       INTEL_WRITE_PART);
 
@@ -495,15 +496,13 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
                GLint pitch, cpp;
                GLuint BR13, CMD;
 
-               ASSERT(irb_region);
-
-               pitch = irb_region->pitch;
-               cpp = irb_region->cpp;
+               pitch = irb->region->pitch;
+               cpp = irb->region->cpp;
 
                DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
                    __FUNCTION__,
-                   irb_region->buffer, (pitch * cpp),
-                   irb_region->draw_offset,
+                   irb->region->buffer, (pitch * cpp),
+                   irb->region->draw_offset,
                    b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1);
 
               BR13 = 0xf0 << 16;
@@ -529,7 +528,7 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
                }
 
 #ifndef I915
-              if (irb_region->tiling != I915_TILING_NONE) {
+              if (irb->region->tiling != I915_TILING_NONE) {
                  CMD |= XY_DST_TILED;
                  pitch /= 4;
               }
@@ -540,9 +539,36 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
                   clearVal = clear_depth;
                }
                else {
-                  clearVal = (cpp == 4)
-                     ? intel->ClearColor8888 : intel->ClearColor565;
-               }
+                 uint8_t clear[4];
+                 GLclampf *color = ctx->Color.ClearColor;
+
+                 CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]);
+                 CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]);
+                 CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]);
+                 CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]);
+
+                 switch (irb->texformat->MesaFormat) {
+                 case MESA_FORMAT_ARGB8888:
+                    clearVal = intel->ClearColor8888;
+                    break;
+                 case MESA_FORMAT_RGB565:
+                    clearVal = intel->ClearColor565;
+                    break;
+                 case MESA_FORMAT_ARGB4444:
+                    clearVal = PACK_COLOR_4444(clear[3], clear[0],
+                                               clear[1], clear[2]);
+                    break;
+                 case MESA_FORMAT_ARGB1555:
+                    clearVal = PACK_COLOR_1555(clear[3], clear[0],
+                                               clear[1], clear[2]);
+                    break;
+                 default:
+                    _mesa_problem(ctx, "Unexpected renderbuffer format: %d\n",
+                                  irb->texformat->MesaFormat);
+                    clearVal = 0;
+                 }
+              }
+
                /*
                   _mesa_debug(ctx, "hardware blit clear buf %d rb id %d\n",
                   buf, irb->Base.Name);
@@ -558,7 +584,7 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
                OUT_BATCH((b.y2 << 16) | b.x2);
                OUT_RELOC(write_buffer,
                         I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
-                         irb_region->draw_offset);
+                         irb->region->draw_offset);
                OUT_BATCH(clearVal);
                ADVANCE_BATCH();
                clearMask &= ~bufBit;    /* turn off bit, for faster loop exit */
index bd3810549aa57875a60eb12c1c026a11a40fb0c9..d798225ddd9d0f89f6059f023883920f89682711 100644 (file)
@@ -48,6 +48,8 @@
 #define DV_PF_555  (1<<8)
 #define DV_PF_565  (2<<8)
 #define DV_PF_8888 (3<<8)
+#define DV_PF_4444 (8<<8)
+#define DV_PF_1555 (9<<8)
 
 struct intel_region;
 struct intel_context;
@@ -337,6 +339,7 @@ extern char *__progname;
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
 #define ALIGN(value, alignment)  ((value + alignment - 1) & ~(alignment - 1))
+#define IS_POWER_OF_TWO(val) (((val) & (val - 1)) == 0)
 
 #define INTEL_FIREVERTICES(intel)              \
 do {                                           \
index a401f730ba219c71656d65f86148ba163a546a08..52647ddf8b2cdd32df6bb794feee6c9877527719 100644 (file)
@@ -119,6 +119,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
       rb->RedBits = 5;
       rb->GreenBits = 6;
       rb->BlueBits = 5;
+      irb->texformat = &_mesa_texformat_rgb565;
       cpp = 2;
       break;
    case GL_RGB:
@@ -132,6 +133,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
       rb->GreenBits = 8;
       rb->BlueBits = 8;
       rb->AlphaBits = 0;
+      irb->texformat = &_mesa_texformat_argb8888; /* XXX: Need xrgb8888 */
       cpp = 4;
       break;
    case GL_RGBA:
@@ -148,6 +150,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
       rb->GreenBits = 8;
       rb->BlueBits = 8;
       rb->AlphaBits = 8;
+      irb->texformat = &_mesa_texformat_argb8888;
       cpp = 4;
       break;
    case GL_STENCIL_INDEX:
@@ -160,12 +163,14 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
       rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
       rb->StencilBits = 8;
       cpp = 4;
+      irb->texformat = &_mesa_texformat_s8_z24;
       break;
    case GL_DEPTH_COMPONENT16:
       rb->_ActualFormat = GL_DEPTH_COMPONENT16;
       rb->DataType = GL_UNSIGNED_SHORT;
       rb->DepthBits = 16;
       cpp = 2;
+      irb->texformat = &_mesa_texformat_z16;
       break;
    case GL_DEPTH_COMPONENT:
    case GL_DEPTH_COMPONENT24:
@@ -174,6 +179,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
       rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
       rb->DepthBits = 24;
       cpp = 4;
+      irb->texformat = &_mesa_texformat_s8_z24;
       break;
    case GL_DEPTH_STENCIL_EXT:
    case GL_DEPTH24_STENCIL8_EXT:
@@ -182,6 +188,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
       rb->DepthBits = 24;
       rb->StencilBits = 8;
       cpp = 4;
+      irb->texformat = &_mesa_texformat_s8_z24;
       break;
    default:
       _mesa_problem(ctx,
@@ -322,6 +329,7 @@ intel_create_renderbuffer(GLenum intFormat)
       irb->Base.GreenBits = 6;
       irb->Base.BlueBits = 5;
       irb->Base.DataType = GL_UNSIGNED_BYTE;
+      irb->texformat = &_mesa_texformat_rgb565;
       break;
    case GL_RGB8:
       irb->Base._ActualFormat = GL_RGB8;
@@ -331,6 +339,7 @@ intel_create_renderbuffer(GLenum intFormat)
       irb->Base.BlueBits = 8;
       irb->Base.AlphaBits = 0;
       irb->Base.DataType = GL_UNSIGNED_BYTE;
+      irb->texformat = &_mesa_texformat_argb8888; /* XXX: Need xrgb8888 */
       break;
    case GL_RGBA8:
       irb->Base._ActualFormat = GL_RGBA8;
@@ -340,24 +349,28 @@ intel_create_renderbuffer(GLenum intFormat)
       irb->Base.BlueBits = 8;
       irb->Base.AlphaBits = 8;
       irb->Base.DataType = GL_UNSIGNED_BYTE;
+      irb->texformat = &_mesa_texformat_argb8888;
       break;
    case GL_STENCIL_INDEX8_EXT:
       irb->Base._ActualFormat = GL_STENCIL_INDEX8_EXT;
       irb->Base._BaseFormat = GL_STENCIL_INDEX;
       irb->Base.StencilBits = 8;
       irb->Base.DataType = GL_UNSIGNED_BYTE;
+      irb->texformat = &_mesa_texformat_s8_z24;
       break;
    case GL_DEPTH_COMPONENT16:
       irb->Base._ActualFormat = GL_DEPTH_COMPONENT16;
       irb->Base._BaseFormat = GL_DEPTH_COMPONENT;
       irb->Base.DepthBits = 16;
       irb->Base.DataType = GL_UNSIGNED_SHORT;
+      irb->texformat = &_mesa_texformat_z16;
       break;
    case GL_DEPTH_COMPONENT24:
       irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
       irb->Base._BaseFormat = GL_DEPTH_COMPONENT;
       irb->Base.DepthBits = 24;
       irb->Base.DataType = GL_UNSIGNED_INT;
+      irb->texformat = &_mesa_texformat_s8_z24;
       break;
    case GL_DEPTH24_STENCIL8_EXT:
       irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
@@ -365,6 +378,7 @@ intel_create_renderbuffer(GLenum intFormat)
       irb->Base.DepthBits = 24;
       irb->Base.StencilBits = 8;
       irb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT;
+      irb->texformat = &_mesa_texformat_s8_z24;
       break;
    default:
       _mesa_problem(NULL,
@@ -449,6 +463,8 @@ static GLboolean
 intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb, 
                     struct gl_texture_image *texImage)
 {
+   irb->texformat = texImage->TexFormat;
+
    if (texImage->TexFormat == &_mesa_texformat_argb8888) {
       irb->Base._ActualFormat = GL_RGBA8;
       irb->Base._BaseFormat = GL_RGBA;
@@ -458,9 +474,21 @@ intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb,
    else if (texImage->TexFormat == &_mesa_texformat_rgb565) {
       irb->Base._ActualFormat = GL_RGB5;
       irb->Base._BaseFormat = GL_RGB;
-      irb->Base.DataType = GL_UNSIGNED_SHORT;
+      irb->Base.DataType = GL_UNSIGNED_BYTE;
       DBG("Render to RGB5 texture OK\n");
    }
+   else if (texImage->TexFormat == &_mesa_texformat_argb1555) {
+      irb->Base._ActualFormat = GL_RGB5_A1;
+      irb->Base._BaseFormat = GL_RGBA;
+      irb->Base.DataType = GL_UNSIGNED_BYTE;
+      DBG("Render to ARGB1555 texture OK\n");
+   }
+   else if (texImage->TexFormat == &_mesa_texformat_argb4444) {
+      irb->Base._ActualFormat = GL_RGBA4;
+      irb->Base._BaseFormat = GL_RGBA;
+      irb->Base.DataType = GL_UNSIGNED_BYTE;
+      DBG("Render to ARGB4444 texture OK\n");
+   }
    else if (texImage->TexFormat == &_mesa_texformat_z16) {
       irb->Base._ActualFormat = GL_DEPTH_COMPONENT16;
       irb->Base._BaseFormat = GL_DEPTH_COMPONENT;
@@ -631,11 +659,11 @@ intel_finish_render_texture(GLcontext * ctx,
 static void
 intel_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
 {
-   struct intel_context *intel = intel_context(ctx);
    const struct intel_renderbuffer *depthRb =
       intel_get_renderbuffer(fb, BUFFER_DEPTH);
    const struct intel_renderbuffer *stencilRb =
       intel_get_renderbuffer(fb, BUFFER_STENCIL);
+   int i;
 
    if (stencilRb && stencilRb != depthRb) {
       /* we only support combined depth/stencil buffers, not separate
@@ -644,32 +672,21 @@ intel_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
       fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
    }
 
-   /* check that texture color buffers are a format we can render into */
-   {
-      const struct gl_texture_format *supportedFormat;
-      GLuint i;
+   for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
+      struct intel_renderbuffer *irb = intel_renderbuffer(rb);
 
-      /* The texture format we can render into seems to depend on the
-       * screen depth.  There currently seems to be a problem when
-       * rendering into a rgb565 texture when the screen is abgr8888.
-       */
+      if (rb == NULL)
+        continue;
 
-      if (intel->ctx.Visual.rgbBits >= 24)
-         supportedFormat = &_mesa_texformat_argb8888;
-      else 
-         supportedFormat = &_mesa_texformat_rgb565;
-
-      for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
-         const struct gl_texture_object *texObj =
-            fb->Attachment[BUFFER_COLOR0 + i].Texture;
-         if (texObj) {
-            const struct gl_texture_image *texImg =
-               texObj->Image[0][texObj->BaseLevel];
-            if (texImg && texImg->TexFormat != supportedFormat) {
-               fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
-               break;
-            }
-         }
+      switch (irb->texformat->MesaFormat) {
+      case MESA_FORMAT_ARGB8888:
+      case MESA_FORMAT_RGB565:
+      case MESA_FORMAT_ARGB1555:
+      case MESA_FORMAT_ARGB4444:
+        break;
+      default:
+        fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
       }
    }
 }
index 7226ee026f67af80247d1ae180653d24b40d7fac..f0665af482e787de9fec3ffee426ea60ae228add 100644 (file)
@@ -61,6 +61,8 @@ struct intel_renderbuffer
    struct gl_renderbuffer Base;
    struct intel_region *region;
 
+   const struct gl_texture_format *texformat;
+
    GLuint vbl_pending;   /**< vblank sequence number of pending flip */
 
    uint8_t *span_cache;
index c3a873f1abdc42e299c0ce46ec1aac1b7fd9cb89..34b78ebc1ab35bf8c3700a3ff239afe992193df4 100644 (file)
@@ -29,6 +29,7 @@
 #include "main/macros.h"
 #include "main/mtypes.h"
 #include "main/colormac.h"
+#include "main/texformat.h"
 
 #include "intel_buffers.h"
 #include "intel_fbo.h"
@@ -313,6 +314,22 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
 #define INTEL_TAG(x) x##_RGB565
 #include "intel_spantmp.h"
 
+/* a4r4g4b4 color span and pixel functions */
+#define INTEL_PIXEL_FMT GL_BGRA
+#define INTEL_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV
+#define INTEL_READ_VALUE(offset) pread_16(irb, offset)
+#define INTEL_WRITE_VALUE(offset, v) pwrite_16(irb, offset, v)
+#define INTEL_TAG(x) x##_ARGB4444
+#include "intel_spantmp.h"
+
+/* a1r5g5b5 color span and pixel functions */
+#define INTEL_PIXEL_FMT GL_BGRA
+#define INTEL_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV
+#define INTEL_READ_VALUE(offset) pread_16(irb, offset)
+#define INTEL_WRITE_VALUE(offset, v) pwrite_16(irb, offset, v)
+#define INTEL_TAG(x) x##_ARGB1555
+#include "intel_spantmp.h"
+
 /* a8r8g8b8 color span and pixel functions */
 #define INTEL_PIXEL_FMT GL_BGRA
 #define INTEL_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
@@ -561,8 +578,8 @@ intel_set_span_functions(struct intel_context *intel,
    else
       tiling = I915_TILING_NONE;
 
-   if (rb->_ActualFormat == GL_RGB5) {
-      /* 565 RGB */
+   switch (irb->texformat->MesaFormat) {
+   case MESA_FORMAT_RGB565:
       switch (tiling) {
       case I915_TILING_NONE:
       default:
@@ -575,38 +592,67 @@ intel_set_span_functions(struct intel_context *intel,
         intel_YTile_InitPointers_RGB565(rb);
         break;
       }
-   }
-   else if (rb->_ActualFormat == GL_RGB8) {
-      /* 8888 RGBx */
+      break;
+   case MESA_FORMAT_ARGB4444:
       switch (tiling) {
       case I915_TILING_NONE:
       default:
-        intelInitPointers_xRGB8888(rb);
+        intelInitPointers_ARGB4444(rb);
         break;
       case I915_TILING_X:
-        intel_XTile_InitPointers_xRGB8888(rb);
+        intel_XTile_InitPointers_ARGB4444(rb);
         break;
       case I915_TILING_Y:
-        intel_YTile_InitPointers_xRGB8888(rb);
+        intel_YTile_InitPointers_ARGB4444(rb);
         break;
       }
-   }
-   else if (rb->_ActualFormat == GL_RGBA8) {
-      /* 8888 RGBA */
+      break;
+   case MESA_FORMAT_ARGB1555:
       switch (tiling) {
       case I915_TILING_NONE:
       default:
-        intelInitPointers_ARGB8888(rb);
+        intelInitPointers_ARGB1555(rb);
         break;
       case I915_TILING_X:
-        intel_XTile_InitPointers_ARGB8888(rb);
+        intel_XTile_InitPointers_ARGB1555(rb);
         break;
       case I915_TILING_Y:
-        intel_YTile_InitPointers_ARGB8888(rb);
+        intel_YTile_InitPointers_ARGB1555(rb);
         break;
       }
-   }
-   else if (rb->_ActualFormat == GL_DEPTH_COMPONENT16) {
+      break;
+   case MESA_FORMAT_ARGB8888:
+      if (rb->AlphaBits == 0) { /* XXX: Need xRGB8888 Mesa format */
+        /* 8888 RGBx */
+        switch (tiling) {
+        case I915_TILING_NONE:
+        default:
+           intelInitPointers_xRGB8888(rb);
+           break;
+        case I915_TILING_X:
+           intel_XTile_InitPointers_xRGB8888(rb);
+           break;
+        case I915_TILING_Y:
+           intel_YTile_InitPointers_xRGB8888(rb);
+           break;
+        }
+      } else {
+        /* 8888 RGBA */
+        switch (tiling) {
+        case I915_TILING_NONE:
+        default:
+           intelInitPointers_ARGB8888(rb);
+           break;
+        case I915_TILING_X:
+           intel_XTile_InitPointers_ARGB8888(rb);
+           break;
+        case I915_TILING_Y:
+           intel_YTile_InitPointers_ARGB8888(rb);
+           break;
+        }
+      }
+      break;
+   case MESA_FORMAT_Z16:
       switch (tiling) {
       case I915_TILING_NONE:
       default:
@@ -619,51 +665,57 @@ intel_set_span_functions(struct intel_context *intel,
         intel_YTile_InitDepthPointers_z16(rb);
         break;
       }
-   }
-   else if (rb->_ActualFormat == GL_DEPTH_COMPONENT24) {
-      switch (tiling) {
-      case I915_TILING_NONE:
-      default:
-        intelInitDepthPointers_z24(rb);
-        break;
-      case I915_TILING_X:
-        intel_XTile_InitDepthPointers_z24(rb);
-        break;
-      case I915_TILING_Y:
-        intel_YTile_InitDepthPointers_z24(rb);
-        break;
-      }
-   }
-   else if (rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) {
-      switch (tiling) {
-      case I915_TILING_NONE:
-      default:
-        intelInitDepthPointers_z24_s8(rb);
-        break;
-      case I915_TILING_X:
-        intel_XTile_InitDepthPointers_z24_s8(rb);
-        break;
-      case I915_TILING_Y:
-        intel_YTile_InitDepthPointers_z24_s8(rb);
-        break;
-      }
-   }
-   else if (rb->_ActualFormat == GL_STENCIL_INDEX8_EXT) {
-      switch (tiling) {
-      case I915_TILING_NONE:
-      default:
-        intelInitStencilPointers_z24_s8(rb);
-        break;
-      case I915_TILING_X:
-        intel_XTile_InitStencilPointers_z24_s8(rb);
-        break;
-      case I915_TILING_Y:
-        intel_YTile_InitStencilPointers_z24_s8(rb);
-        break;
+      break;
+   case MESA_FORMAT_S8_Z24:
+      /* There are a few different ways SW asks us to access the S8Z24 data:
+       * Z24 depth-only depth reads
+       * S8Z24 depth reads
+       * S8Z24 stencil reads.
+       */
+      if (rb->_ActualFormat == GL_DEPTH_COMPONENT24) {
+        switch (tiling) {
+        case I915_TILING_NONE:
+        default:
+           intelInitDepthPointers_z24(rb);
+           break;
+        case I915_TILING_X:
+           intel_XTile_InitDepthPointers_z24(rb);
+           break;
+        case I915_TILING_Y:
+           intel_YTile_InitDepthPointers_z24(rb);
+           break;
+        }
+      } else if (rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) {
+        switch (tiling) {
+        case I915_TILING_NONE:
+        default:
+           intelInitDepthPointers_z24_s8(rb);
+           break;
+        case I915_TILING_X:
+           intel_XTile_InitDepthPointers_z24_s8(rb);
+           break;
+        case I915_TILING_Y:
+           intel_YTile_InitDepthPointers_z24_s8(rb);
+           break;
+        }
+      } else if (rb->_ActualFormat == GL_STENCIL_INDEX8_EXT) {
+        switch (tiling) {
+        case I915_TILING_NONE:
+        default:
+           intelInitStencilPointers_z24_s8(rb);
+           break;
+        case I915_TILING_X:
+           intel_XTile_InitStencilPointers_z24_s8(rb);
+           break;
+        case I915_TILING_Y:
+           intel_YTile_InitStencilPointers_z24_s8(rb);
+           break;
+        }
       }
-   }
-   else {
+      break;
+   default:
       _mesa_problem(NULL,
-                    "Unexpected _ActualFormat in intelSetSpanFunctions");
+                    "Unexpected MesaFormat in intelSetSpanFunctions");
+      break;
    }
 }