summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStéphane Marchesin <marcheu@chromium.org>2011-06-22 16:23:02 -0700
committerStéphane Marchesin <marcheu@chromium.org>2011-06-22 16:44:54 -0700
commit465183c6ae594ad399f72ade027e49adcb1f763b (patch)
tree7e2cda2a4069b3d9cbca3a97aaa3944552836a6f
parent5ff22ab229d40a5ffc6f5e67f58359cdef33e8dc (diff)
i915g: Support more texture and render target formats.
-rw-r--r--src/gallium/drivers/i915/i915_clear.c2
-rw-r--r--src/gallium/drivers/i915/i915_screen.c6
-rw-r--r--src/gallium/drivers/i915/i915_state_emit.c67
-rw-r--r--src/gallium/drivers/i915/i915_state_sampler.c2
-rw-r--r--src/gallium/drivers/i915/i915_state_static.c9
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 4a97746e981..fcb208d6dae 100644
--- a/src/gallium/drivers/i915/i915_clear.c
+++ b/src/gallium/drivers/i915/i915_clear.c
@@ -63,13 +63,13 @@ i915_clear_emit(struct pipe_context *pipe, unsigned buffers, const float *rgba,
util_pack_color(rgba, cbuf->format, &u_color);
if (util_format_get_blocksize(cbuf_tex->b.b.format) == 4)
clear_color = u_color.ui;
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;
clear_depth = clear_stencil = 0;
if (buffers & PIPE_CLEAR_DEPTH) {
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index c86baa58b28..ec070568f4e 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -261,12 +261,14 @@ i915_is_format_supported(struct pipe_screen *screen,
unsigned sample_count,
unsigned tex_usage)
{
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,
PIPE_FORMAT_I8_UNORM,
PIPE_FORMAT_L8A8_UNORM,
PIPE_FORMAT_UYVY,
@@ -280,13 +282,17 @@ i915_is_format_supported(struct pipe_screen *screen,
PIPE_FORMAT_Z24X8_UNORM,
PIPE_FORMAT_Z24_UNORM_S8_USCALED,
PIPE_FORMAT_NONE /* list terminator */
};
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[] = {
/* XXX why not?
PIPE_FORMAT_Z16_UNORM, */
PIPE_FORMAT_Z24X8_UNORM,
diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c
index 0155cd83510..b7ccba8cd83 100644
--- a/src/gallium/drivers/i915/i915_state_emit.c
+++ b/src/gallium/drivers/i915/i915_state_emit.c
@@ -31,13 +31,15 @@
#include "i915_batch.h"
#include "i915_debug.h"
#include "i915_resource.h"
#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"
struct i915_tracked_hw_state {
const char *name;
void (*validate)(struct i915_context *, unsigned *batch_space);
@@ -338,27 +340,78 @@ emit_constants(struct i915_context *i915)
OUT_BATCH(*c++);
OUT_BATCH(*c++);
}
}
}
+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
emit_draw_rect(struct i915_context *i915)
{
if (i915->static_dirty & I915_DST_RECT) {
diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c
index be70e7a92c9..aa1dd443fbc 100644
--- a/src/gallium/drivers/i915/i915_state_sampler.c
+++ b/src/gallium/drivers/i915/i915_state_sampler.c
@@ -205,16 +205,14 @@ static uint translate_texture_format(enum pipe_format pipeFormat)
case PIPE_FORMAT_B8G8R8A8_UNORM:
return MAPSURF_32BIT | MT_32BIT_ARGB8888;
case PIPE_FORMAT_B8G8R8X8_UNORM:
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:
return (MAPSURF_422 | MT_422_YCRCB_SWAPY);
#if 0
case PIPE_FORMAT_RGB_FXT1:
diff --git a/src/gallium/drivers/i915/i915_state_static.c b/src/gallium/drivers/i915/i915_state_static.c
index 2865298318c..7116c0a5ca1 100644
--- a/src/gallium/drivers/i915/i915_state_static.c
+++ b/src/gallium/drivers/i915/i915_state_static.c
@@ -39,12 +39,18 @@ static unsigned translate_format(enum pipe_format format)
{
switch (format) {
case PIPE_FORMAT_B8G8R8A8_UNORM:
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;
}
}
@@ -134,13 +140,14 @@ static void update_framebuffer(struct i915_context *i915)
}
if (i915->current.draw_size != draw_size) {
i915->current.draw_size = draw_size;
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);
}
struct i915_tracked_state i915_hw_framebuffer = {