i965: Fix handling of drawing to MESA_FORMAT_XRGB8888
[mesa.git] / src / mesa / drivers / dri / i965 / brw_wm_surface_state.c
index 096f74394eb6db3365eb5d939f7b60d1895886e6..74cf66f9f8b85740e1f8af86705b871c99ccea13 100644 (file)
@@ -31,7 +31,6 @@
                    
 
 #include "main/mtypes.h"
-#include "main/texformat.h"
 #include "main/texstore.h"
 #include "shader/prog_parameter.h"
 
@@ -70,7 +69,8 @@ static GLuint translate_tex_target( GLenum target )
 }
 
 
-static GLuint translate_tex_format( GLuint mesa_format, GLenum internal_format,
+static GLuint translate_tex_format( gl_format mesa_format,
+                                    GLenum internal_format,
                                    GLenum depth_mode )
 {
    switch( mesa_format ) {
@@ -86,6 +86,9 @@ static GLuint translate_tex_format( GLuint mesa_format, GLenum internal_format,
    case MESA_FORMAT_AL88:
       return BRW_SURFACEFORMAT_L8A8_UNORM;
 
+   case MESA_FORMAT_AL1616:
+      return BRW_SURFACEFORMAT_L16A16_UNORM;
+
    case MESA_FORMAT_RGB888:
       assert(0);               /* not supported for sampling */
       return BRW_SURFACEFORMAT_R8G8B8_UNORM;      
@@ -96,7 +99,11 @@ static GLuint translate_tex_format( GLuint mesa_format, GLenum internal_format,
       else
         return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
 
+   case MESA_FORMAT_XRGB8888:
+      return BRW_SURFACEFORMAT_B8G8R8X8_UNORM;
+
    case MESA_FORMAT_RGBA8888_REV:
+      _mesa_problem(NULL, "unexpected format in i965:translate_tex_format()");
       if (internal_format == GL_RGB)
         return BRW_SURFACEFORMAT_R8G8B8X8_UNORM;
       else
@@ -287,7 +294,7 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )
       key.bo = NULL;
       key.offset = intelObj->textureOffset;
    } else {
-      key.format = firstImage->TexFormat->MesaFormat;
+      key.format = firstImage->TexFormat;
       key.internal_format = firstImage->InternalFormat;
       key.pitch = intelObj->mt->pitch;
       key.depth = firstImage->Depth;
@@ -354,7 +361,10 @@ brw_create_constant_surface( struct brw_context *brw,
                         NULL, NULL);
 
    if (key->bo) {
-      /* Emit relocation to surface contents */
+      /* Emit relocation to surface contents.  Section 5.1.1 of the gen4
+       * bspec ("Data Cache") says that the data cache does not exist as
+       * a separate cache and is just the sampler cache.
+       */
       dri_bo_emit_reloc(bo,
                        I915_GEM_DOMAIN_SAMPLER, 0,
                        0,
@@ -527,8 +537,15 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
       region_bo = region->buffer;
 
       key.surface_type = BRW_SURFACE_2D;
-      switch (irb->texformat->MesaFormat) {
+      switch (irb->Base.Format) {
+      /* XRGB and ARGB are treated the same here because the chips in this
+       * family cannot render to XRGB targets.  This means that we have to
+       * mask writes to alpha (ala glColorMask) and reconfigure the alpha
+       * blending hardware to use GL_ONE (or GL_ZERO) for cases where
+       * GL_DST_ALPHA (or GL_ONE_MINUS_DST_ALPHA) is used.
+       */
       case MESA_FORMAT_ARGB8888:
+      case MESA_FORMAT_XRGB8888:
         key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
         break;
       case MESA_FORMAT_RGB565:
@@ -541,26 +558,38 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
         key.surface_format = BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
         break;
       default:
-        _mesa_problem(ctx, "Bad renderbuffer format: %d\n",
-                      irb->texformat->MesaFormat);
+        _mesa_problem(ctx, "Bad renderbuffer format: %d\n", irb->Base.Format);
       }
       key.tiling = region->tiling;
-      key.width = region->width;
-      key.height = region->height;
+      if (brw->intel.intelScreen->driScrnPriv->dri2.enabled) {
+        key.width = rb->Width;
+        key.height = rb->Height;
+      } else {
+        key.width = region->width;
+        key.height = region->height;
+      }
       key.pitch = region->pitch;
       key.cpp = region->cpp;
       key.draw_offset = region->draw_offset; /* cur 3d or cube face offset */
    } else {
       key.surface_type = BRW_SURFACE_NULL;
       key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-      key.tiling = 0;
+      key.tiling = I915_TILING_X;
       key.width = 1;
       key.height = 1;
       key.cpp = 4;
       key.draw_offset = 0;
    }
+   /* _NEW_COLOR */
    memcpy(key.color_mask, ctx->Color.ColorMask,
          sizeof(key.color_mask));
+
+   /* As mentioned above, disable writes to the alpha component when the
+    * renderbuffer is XRGB.
+    */
+   if (ctx->Visual.alphaBits == 0)
+     key.color_mask[3] = GL_FALSE;
+
    key.color_blend = (!ctx->Color._LogicOpEnabled &&
                      ctx->Color.BlendEnabled);
 
@@ -629,7 +658,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
         drm_intel_bo_emit_reloc(brw->wm.surf_bo[unit],
                                 offsetof(struct brw_surface_state, ss1),
                                 region_bo,
-                                surf.ss1.base_addr,
+                                surf.ss1.base_addr - region_bo->offset,
                                 I915_GEM_DOMAIN_RENDER,
                                 I915_GEM_DOMAIN_RENDER);
       }
@@ -655,7 +684,7 @@ brw_wm_get_binding_table(struct brw_context *brw)
 
    if (bind_bo == NULL) {
       GLuint data_size = brw->wm.nr_surfaces * sizeof(GLuint);
-      uint32_t *data = malloc(data_size);
+      uint32_t data[BRW_WM_MAX_SURF];
       int i;
 
       for (i = 0; i < brw->wm.nr_surfaces; i++)
@@ -680,8 +709,6 @@ brw_wm_get_binding_table(struct brw_context *brw)
                              brw->wm.surf_bo[i]);
         }
       }
-
-      free(data);
    }
 
    return bind_bo;
@@ -690,11 +717,10 @@ brw_wm_get_binding_table(struct brw_context *brw)
 static void prepare_wm_surfaces(struct brw_context *brw )
 {
    GLcontext *ctx = &brw->intel.ctx;
-   struct intel_context *intel = &brw->intel;
    GLuint i;
    int old_nr_surfaces;
 
-   /* _NEW_BUFFERS */
+   /* _NEW_BUFFERS | _NEW_COLOR */
    /* Update surfaces for drawing buffers */
    if (ctx->DrawBuffer->_NumColorDrawBuffers >= 1) {
       for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
@@ -707,7 +733,7 @@ static void prepare_wm_surfaces(struct brw_context *brw )
    }
 
    old_nr_surfaces = brw->wm.nr_surfaces;
-   brw->wm.nr_surfaces = MAX_DRAW_BUFFERS;
+   brw->wm.nr_surfaces = BRW_MAX_DRAW_BUFFERS;
 
    if (brw->wm.surf_bo[SURF_INDEX_FRAG_CONST_BUFFER] != NULL)
        brw->wm.nr_surfaces = SURF_INDEX_FRAG_CONST_BUFFER + 1;
@@ -719,17 +745,8 @@ static void prepare_wm_surfaces(struct brw_context *brw )
 
       /* _NEW_TEXTURE, BRW_NEW_TEXDATA */
       if (texUnit->_ReallyEnabled) {
-         if (texUnit->_Current == intel->frame_buffer_texobj) {
-            /* render to texture */
-            dri_bo_unreference(brw->wm.surf_bo[surf]);
-            brw->wm.surf_bo[surf] = brw->wm.surf_bo[0];
-            dri_bo_reference(brw->wm.surf_bo[surf]);
-            brw->wm.nr_surfaces = surf + 1;
-         } else {
-            /* regular texture */
-            brw_update_texture_surface(ctx, i);
-            brw->wm.nr_surfaces = surf + 1;
-         }
+        brw_update_texture_surface(ctx, i);
+        brw->wm.nr_surfaces = surf + 1;
       } else {
          dri_bo_unreference(brw->wm.surf_bo[surf]);
          brw->wm.surf_bo[surf] = NULL;