Mesa (master): i915g: Support more texture and render target formats.

Stephane Marchesin marcheu at kemper.freedesktop.org
Wed Jun 22 23:45:06 UTC 2011


Module: Mesa
Branch: master
Commit: 465183c6ae594ad399f72ade027e49adcb1f763b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=465183c6ae594ad399f72ade027e49adcb1f763b

Author: Stéphane Marchesin <marcheu at chromium.org>
Date:   Wed Jun 22 16:23:02 2011 -0700

i915g: Support more texture and render target formats.

---

 src/gallium/drivers/i915/i915_clear.c         |    2 +-
 src/gallium/drivers/i915/i915_screen.c        |    6 ++
 src/gallium/drivers/i915/i915_state_emit.c    |   67 ++++++++++++++++++++++---
 src/gallium/drivers/i915/i915_state_sampler.c |    2 -
 src/gallium/drivers/i915/i915_state_static.c  |    9 +++-
 5 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/i915/i915_clear.c b/src/gallium/drivers/i915/i915_clear.c
index 4a97746..fcb208d 100644
--- a/src/gallium/drivers/i915/i915_clear.c
+++ b/src/gallium/drivers/i915/i915_clear.c
@@ -66,7 +66,7 @@ i915_clear_emit(struct pipe_context *pipe, unsigned buffers, const float *rgba,
       else
          clear_color = (u_color.ui & 0xffff) | (u_color.ui << 16);
 
-      util_pack_color(rgba, PIPE_FORMAT_B8G8R8A8_UNORM, &u_color);
+      util_pack_color(rgba, cbuf->format, &u_color);
       clear_color8888 = u_color.ui;
    } else
       clear_color = clear_color8888 = 0;
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index c86baa5..ec07056 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -264,6 +264,8 @@ i915_is_format_supported(struct pipe_screen *screen,
    static const enum pipe_format tex_supported[] = {
       PIPE_FORMAT_B8G8R8A8_UNORM,
       PIPE_FORMAT_B8G8R8X8_UNORM,
+      PIPE_FORMAT_R8G8B8A8_UNORM,
+      PIPE_FORMAT_R8G8B8X8_UNORM,
       PIPE_FORMAT_B5G6R5_UNORM,
       PIPE_FORMAT_L8_UNORM,
       PIPE_FORMAT_A8_UNORM,
@@ -283,7 +285,11 @@ i915_is_format_supported(struct pipe_screen *screen,
    };
    static const enum pipe_format render_supported[] = {
       PIPE_FORMAT_B8G8R8A8_UNORM,
+      PIPE_FORMAT_R8G8B8A8_UNORM,
       PIPE_FORMAT_B5G6R5_UNORM,
+      PIPE_FORMAT_L8_UNORM,
+      PIPE_FORMAT_A8_UNORM,
+      PIPE_FORMAT_I8_UNORM,
       PIPE_FORMAT_NONE  /* list terminator */
    };
    static const enum pipe_format depth_supported[] = {
diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c
index 0155cd8..b7ccba8 100644
--- a/src/gallium/drivers/i915/i915_state_emit.c
+++ b/src/gallium/drivers/i915/i915_state_emit.c
@@ -34,7 +34,9 @@
 
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
+#include "pipe/p_format.h"
 
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
@@ -341,21 +343,72 @@ emit_constants(struct i915_context *i915)
    }
 }
 
+static const struct
+{
+   enum pipe_format format;
+   uint hw_swizzle;
+} fixup_formats[] = {
+   { PIPE_FORMAT_R8G8B8A8_UNORM, 0x21030000 /* BGRA */},
+   { PIPE_FORMAT_L8_UNORM,       0x00000000 /* RRRR */},
+   { PIPE_FORMAT_I8_UNORM,       0x00000000 /* RRRR */},
+   { PIPE_FORMAT_A8_UNORM,       0x33330000 /* AAAA */},
+   { PIPE_FORMAT_NONE,           0x00000000},
+};
+
+static boolean need_fixup(enum pipe_format f)
+{
+   for(int i=0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++)
+      if (fixup_formats[i].format == f)
+         return TRUE;
+
+   return FALSE;
+}
+
+static uint fixup_swizzle(enum pipe_format f)
+{
+   for(int i=0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++)
+      if (fixup_formats[i].format == f)
+         return fixup_formats[i].hw_swizzle;
+
+   return 0;
+}
+
 static void
 validate_program(struct i915_context *i915, unsigned *batch_space)
 {
-   *batch_space = i915->fs->program_len;
+   struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
+
+   /* we need more batch space if we want to emulate rgba framebuffers */
+   *batch_space = i915->fs->program_len + (need_fixup(cbuf_surface->format) ? 3 : 0);
 }
 
 static void
 emit_program(struct i915_context *i915)
 {
-      uint i;
-      /* we should always have, at least, a pass-through program */
-      assert(i915->fs->program_len > 0);
-      for (i = 0; i < i915->fs->program_len; i++) {
-         OUT_BATCH(i915->fs->program[i]);
-      }
+   struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
+   boolean need_format_fixup = need_fixup(cbuf_surface->format);
+   uint i;
+
+   /* we should always have, at least, a pass-through program */
+   assert(i915->fs->program_len > 0);
+   for (i = 0; i < i915->fs->program_len; i++) {
+         if ((i == 0) && need_format_fixup)
+            OUT_BATCH(i915->fs->program[i] + 3);
+         else
+            OUT_BATCH(i915->fs->program[i]);
+   }
+
+   /* we emit an additional mov with swizzle to fake RGBA framebuffers */
+   if (need_format_fixup) {
+      /* mov out_color, out_color.zyxw */
+      OUT_BATCH(A0_MOV |
+                (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) |
+                A0_DEST_CHANNEL_ALL |
+                (REG_TYPE_OC << A0_SRC0_TYPE_SHIFT) |
+                (T_DIFFUSE << A0_SRC0_NR_SHIFT));
+      OUT_BATCH(fixup_swizzle(cbuf_surface->format));
+      OUT_BATCH(0);
+   }
 }
 
 static void
diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c
index be70e7a..aa1dd44 100644
--- a/src/gallium/drivers/i915/i915_state_sampler.c
+++ b/src/gallium/drivers/i915/i915_state_sampler.c
@@ -208,10 +208,8 @@ static uint translate_texture_format(enum pipe_format pipeFormat)
       return MAPSURF_32BIT | MT_32BIT_XRGB8888;
    case PIPE_FORMAT_R8G8B8A8_UNORM:
       return MAPSURF_32BIT | MT_32BIT_ABGR8888;
-#if 0
    case PIPE_FORMAT_R8G8B8X8_UNORM:
       return MAPSURF_32BIT | MT_32BIT_XBGR8888;
-#endif
    case PIPE_FORMAT_YUYV:
       return (MAPSURF_422 | MT_422_YCRCB_NORMAL);
    case PIPE_FORMAT_UYVY:
diff --git a/src/gallium/drivers/i915/i915_state_static.c b/src/gallium/drivers/i915/i915_state_static.c
index 2865298..7116c0a 100644
--- a/src/gallium/drivers/i915/i915_state_static.c
+++ b/src/gallium/drivers/i915/i915_state_static.c
@@ -42,6 +42,12 @@ static unsigned translate_format(enum pipe_format format)
       return COLOR_BUF_ARGB8888;
    case PIPE_FORMAT_B5G6R5_UNORM:
       return COLOR_BUF_RGB565;
+   case PIPE_FORMAT_R8G8B8A8_UNORM:
+      return COLOR_BUF_ARGB8888;
+   case PIPE_FORMAT_L8_UNORM:
+   case PIPE_FORMAT_A8_UNORM:
+   case PIPE_FORMAT_I8_UNORM:
+      return COLOR_BUF_8BIT;
    default:
       assert(0);
       return 0;
@@ -137,7 +143,8 @@ static void update_framebuffer(struct i915_context *i915)
       i915->static_dirty |= I915_DST_RECT;
    }
 
-   i915->hardware_dirty |= I915_HW_STATIC;
+   /* we also send a new program to make sure the fixup for RGBA surfaces happens */
+   i915->hardware_dirty |= I915_HW_STATIC | I915_HW_PROGRAM;
 
    /* flush the cache in case we sample from the old renderbuffers */
    i915_set_flush_dirty(i915, I915_FLUSH_CACHE);




More information about the mesa-commit mailing list