From 465183c6ae594ad399f72ade027e49adcb1f763b Mon Sep 17 00:00:00 2001 From: =?utf8?q?St=C3=A9phane=20Marchesin?= Date: Wed, 22 Jun 2011 16:23:02 -0700 Subject: [PATCH] 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); -- 2.7.4