diff options
author | Daniel Vetter <[email protected]> | 2011-09-26 09:47:38 +0200 |
---|---|---|
committer | Daniel Vetter <[email protected]> | 2011-10-07 14:31:16 +0200 |
commit | 305bcda4b583641bab5a7bfa6ce4e30a8559a868 (patch) | |
tree | 14eed9e3d4fcc508e969df7ef575202ae89f97fa | |
parent | c475a54578bf5473c6c62bc5468ef4fe555164d7 (diff) |
i915g: make fixup swizzle into a real hw state
This way it can be reused in the fastclear path.
Signed-off-by: Daniel Vetter <[email protected]>
-rw-r--r-- | src/gallium/drivers/i915/i915_context.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/i915/i915_state_emit.c | 44 | ||||
-rw-r--r-- | src/gallium/drivers/i915/i915_state_static.c | 40 |
3 files changed, 45 insertions, 41 deletions
diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h index 0f66d13104f..dacd0a669c1 100644 --- a/src/gallium/drivers/i915/i915_context.h +++ b/src/gallium/drivers/i915/i915_context.h @@ -167,6 +167,8 @@ struct i915_state unsigned dst_buf_vars; uint32_t draw_offset; uint32_t draw_size; + unsigned need_target_fixup; + uint32_t fixup_swizzle; unsigned id; /* track lost context events */ }; diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c index 563c7d07be2..426c683502a 100644 --- a/src/gallium/drivers/i915/i915_state_emit.c +++ b/src/gallium/drivers/i915/i915_state_emit.c @@ -343,47 +343,10 @@ 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, 0x00030000 /* RRRA */}, - { PIPE_FORMAT_I8_UNORM, 0x00030000 /* RRRA */}, - { PIPE_FORMAT_A8_UNORM, 0x33330000 /* AAAA */}, - { PIPE_FORMAT_NONE, 0x00000000}, -}; - -static uint need_target_fixup(struct pipe_surface* p) -{ - enum pipe_format f; - /* if we don't have a surface bound yet, we don't need to fixup the shader */ - if (!p) - return 0; - - f = p->format; - for(int i=0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++) - if (fixup_formats[i].format == f) - return 1; - - return 0; -} - -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) { - struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0]; - uint additional_size = need_target_fixup(cbuf_surface); + uint additional_size = i915->current.need_target_fixup; /* we need more batch space if we want to emulate rgba framebuffers */ *batch_space = i915->fs->program_len + 3 * additional_size; @@ -392,8 +355,7 @@ validate_program(struct i915_context *i915, unsigned *batch_space) static void emit_program(struct i915_context *i915) { - struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0]; - uint target_fixup = need_target_fixup(cbuf_surface); + uint target_fixup = i915->current.need_target_fixup; uint i; /* we should always have, at least, a pass-through program */ @@ -418,7 +380,7 @@ emit_program(struct i915_context *i915) 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(i915->current.fixup_swizzle); OUT_BATCH(0); } } diff --git a/src/gallium/drivers/i915/i915_state_static.c b/src/gallium/drivers/i915/i915_state_static.c index 0e4000bc2ab..7f60311cebb 100644 --- a/src/gallium/drivers/i915/i915_state_static.c +++ b/src/gallium/drivers/i915/i915_state_static.c @@ -162,12 +162,44 @@ struct i915_tracked_state i915_hw_framebuffer = { I915_NEW_FRAMEBUFFER }; +static const struct +{ + enum pipe_format format; + uint hw_swizzle; +} fixup_formats[] = { + { PIPE_FORMAT_R8G8B8A8_UNORM, 0x21030000 /* BGRA */}, + { PIPE_FORMAT_L8_UNORM, 0x00030000 /* RRRA */}, + { PIPE_FORMAT_I8_UNORM, 0x00030000 /* RRRA */}, + { PIPE_FORMAT_A8_UNORM, 0x33330000 /* AAAA */}, + { PIPE_FORMAT_NONE, 0x00000000}, +}; + +static uint need_target_fixup(struct pipe_surface* p, uint32_t *fixup) +{ + enum pipe_format f; + /* if we don't have a surface bound yet, we don't need to fixup the shader */ + if (!p) + return 0; + + f = p->format; + for(int i=0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++) + if (fixup_formats[i].format == f) { + *fixup = fixup_formats[i].hw_swizzle; + return 1; + } + + *fixup = 0; + return 0; +} + static void update_dst_buf_vars(struct i915_context *i915) { struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0]; struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; uint32_t dst_buf_vars, cformat, zformat; uint32_t early_z = 0; + uint32_t fixup; + int need_fixup; if (cbuf_surface) cformat = cbuf_surface->format; @@ -203,6 +235,14 @@ static void update_dst_buf_vars(struct i915_context *i915) i915->static_dirty |= I915_DST_VARS; i915->hardware_dirty |= I915_HW_STATIC; } + + need_fixup = need_target_fixup(cbuf_surface, &fixup); + if (i915->current.need_target_fixup != need_fixup || + i915->current.fixup_swizzle != fixup) { + i915->current.need_target_fixup = need_fixup; + i915->current.fixup_swizzle = fixup; + i915->hardware_dirty |= I915_HW_PROGRAM; + } } struct i915_tracked_state i915_hw_dst_buf_vars = { |