From 71584d0cc75dda3c579a2a0cb6c1ac9591f7d5c9 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 8 May 2010 18:51:03 +0200 Subject: r300g: pass depth texture swizzle to the compiler if compare mode is enabled --- src/gallium/drivers/r300/r300_context.h | 18 +++-- src/gallium/drivers/r300/r300_fs.c | 14 +++- src/gallium/drivers/r300/r300_state.c | 11 ++- src/gallium/drivers/r300/r300_state_derived.c | 21 +++++ src/gallium/drivers/r300/r300_texture.c | 112 ++++++++++++++------------ src/gallium/drivers/r300/r300_texture.h | 3 + 6 files changed, 111 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 2e91a5b265..b3c5459594 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -151,6 +151,10 @@ struct r300_texture_format_state { struct r300_sampler_view { struct pipe_sampler_view base; + /* Swizzles in the UTIL_FORMAT_SWIZZLE_* representation, + * derived from base. */ + unsigned char swizzle[4]; + /* Copy of r300_texture::texture_format_state with format-specific bits * added. */ struct r300_texture_format_state format; @@ -166,6 +170,13 @@ struct r300_texture_fb_state { uint32_t zb_format; /* R300_ZB_FORMAT */ }; +struct r300_texture_sampler_state { + struct r300_texture_format_state format; + uint32_t filter0; /* R300_TX_FILTER0: 0x4400 */ + uint32_t filter1; /* R300_TX_FILTER1: 0x4440 */ + uint32_t border_color; /* R300_TX_BORDER_COLOR: 0x45c0 */ +}; + struct r300_textures_state { /* Textures. */ struct r300_sampler_view *sampler_views[16]; @@ -177,12 +188,7 @@ struct r300_textures_state { /* This is the merge of the texture and sampler states. */ unsigned count; uint32_t tx_enable; /* R300_TX_ENABLE: 0x4101 */ - struct r300_texture_sampler_state { - struct r300_texture_format_state format; - uint32_t filter0; /* R300_TX_FILTER0: 0x4400 */ - uint32_t filter1; /* R300_TX_FILTER1: 0x4440 */ - uint32_t border_color; /* R300_TX_BORDER_COLOR: 0x45c0 */ - } regs[16]; + struct r300_texture_sampler_state regs[16]; }; struct r300_vertex_stream_state { diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index 19023457bf..30aa065139 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -137,6 +137,7 @@ static void get_external_state( { struct r300_textures_state *texstate = r300->textures_state.state; unsigned i; + unsigned char *swizzle; for (i = 0; i < texstate->sampler_state_count; i++) { struct r300_sampler_state* s = texstate->sampler_states[i]; @@ -148,9 +149,16 @@ static void get_external_state( if (s->state.compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { state->unit[i].compare_mode_enabled = 1; - /* XXX Gallium doesn't provide us with any information regarding - * this mode, so we are screwed. Let's set INTENSITY for now. */ - state->unit[i].depth_texture_swizzle = RC_SWIZZLE_XYZW; + /* Pass depth texture swizzling to the compiler. */ + if (texstate->sampler_views[i]) { + swizzle = texstate->sampler_views[i]->swizzle; + + state->unit[i].depth_texture_swizzle = + RC_MAKE_SWIZZLE(swizzle[0], swizzle[1], + swizzle[2], swizzle[3]); + } else { + state->unit[i].depth_texture_swizzle = RC_SWIZZLE_XYZW; + } /* Fortunately, no need to translate this. */ state->unit[i].texture_compare_func = s->state.compare_func; diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 446422ca0f..fe3eae9805 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1021,7 +1021,6 @@ r300_create_sampler_view(struct pipe_context *pipe, { struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view); struct r300_texture *tex = r300_texture(texture); - unsigned char swizzle[4]; if (view) { view->base = *templ; @@ -1030,14 +1029,14 @@ r300_create_sampler_view(struct pipe_context *pipe, view->base.texture = NULL; pipe_resource_reference(&view->base.texture, texture); - swizzle[0] = templ->swizzle_r; - swizzle[1] = templ->swizzle_g; - swizzle[2] = templ->swizzle_b; - swizzle[3] = templ->swizzle_a; + view->swizzle[0] = templ->swizzle_r; + view->swizzle[1] = templ->swizzle_g; + view->swizzle[2] = templ->swizzle_b; + view->swizzle[3] = templ->swizzle_a; view->format = tex->tx_format; view->format.format1 |= r300_translate_texformat(templ->format, - swizzle); + view->swizzle); if (r300_screen(pipe->screen)->caps.is_r500) { view->format.format2 |= r500_tx_format_msb_bit(templ->format); } diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index e3adace0fa..193a60c034 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -34,6 +34,7 @@ #include "r300_state.h" #include "r300_state_derived.h" #include "r300_state_inlines.h" +#include "r300_texture.h" #include "r300_vs.h" /* r300_state_derived: Various bits of state which are dependent upon @@ -493,6 +494,12 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) unsigned min_level, max_level, i, size; unsigned count = MIN2(state->sampler_view_count, state->sampler_state_count); + unsigned char depth_swizzle[4] = { + UTIL_FORMAT_SWIZZLE_X, + UTIL_FORMAT_SWIZZLE_X, + UTIL_FORMAT_SWIZZLE_X, + UTIL_FORMAT_SWIZZLE_X + }; state->tx_enable = 0; state->count = 0; @@ -512,6 +519,20 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) texstate->filter1 = sampler->filter1; texstate->border_color = sampler->border_color; + /* If compare mode is disabled, the sampler view swizzles + * are stored in the format. + * Otherwise, swizzles must be applied after the compare mode + * in the fragment shader. */ + if (util_format_is_depth_or_stencil(tex->b.b.format)) { + if (sampler->state.compare_mode == PIPE_TEX_COMPARE_NONE) { + texstate->format.format1 |= + r300_get_swizzle_combined(depth_swizzle, view->swizzle); + } else { + texstate->format.format1 |= + r300_get_swizzle_combined(depth_swizzle, 0); + } + } + /* to emulate 1D textures through 2D ones correctly */ if (tex->b.b.target == PIPE_TEXTURE_1D) { texstate->filter0 &= ~R300_TX_WRAP_T_MASK; diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index a2fefde352..c0911aef38 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -47,6 +47,60 @@ static const unsigned microblock_table[5][3][2] = { {{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */ }; +unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format, + const unsigned char *swizzle_view) +{ + unsigned i; + unsigned char swizzle[4]; + unsigned result = 0; + const uint32_t swizzle_shift[4] = { + R300_TX_FORMAT_R_SHIFT, + R300_TX_FORMAT_G_SHIFT, + R300_TX_FORMAT_B_SHIFT, + R300_TX_FORMAT_A_SHIFT + }; + const uint32_t swizzle_bit[4] = { + R300_TX_FORMAT_X, + R300_TX_FORMAT_Y, + R300_TX_FORMAT_Z, + R300_TX_FORMAT_W + }; + + if (swizzle_view) { + /* Combine two sets of swizzles. */ + for (i = 0; i < 4; i++) { + swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ? + swizzle_format[swizzle_view[i]] : swizzle_view[i]; + } + } else { + memcpy(swizzle, swizzle_format, 4); + } + + /* Get swizzle. */ + for (i = 0; i < 4; i++) { + switch (swizzle[i]) { + case UTIL_FORMAT_SWIZZLE_Y: + result |= swizzle_bit[1] << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_Z: + result |= swizzle_bit[2] << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_W: + result |= swizzle_bit[3] << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_0: + result |= R300_TX_FORMAT_ZERO << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_1: + result |= R300_TX_FORMAT_ONE << swizzle_shift[i]; + break; + default: /* UTIL_FORMAT_SWIZZLE_X */ + result |= swizzle_bit[0] << swizzle_shift[i]; + } + } + return result; +} + /* Translate a pipe_format into a useful texture format for sampling. * * Some special formats are translated directly using R300_EASY_TX_FORMAT, @@ -66,38 +120,26 @@ uint32_t r300_translate_texformat(enum pipe_format format, const struct util_format_description *desc; unsigned i; boolean uniform = TRUE; - const uint32_t swizzle_shift[4] = { - R300_TX_FORMAT_R_SHIFT, - R300_TX_FORMAT_G_SHIFT, - R300_TX_FORMAT_B_SHIFT, - R300_TX_FORMAT_A_SHIFT - }; - const uint32_t swizzle_bit[4] = { - R300_TX_FORMAT_X, - R300_TX_FORMAT_Y, - R300_TX_FORMAT_Z, - R300_TX_FORMAT_W - }; const uint32_t sign_bit[4] = { R300_TX_FORMAT_SIGNED_X, R300_TX_FORMAT_SIGNED_Y, R300_TX_FORMAT_SIGNED_Z, R300_TX_FORMAT_SIGNED_W, }; - unsigned char swizzle[4]; desc = util_format_description(format); /* Colorspace (return non-RGB formats directly). */ switch (desc->colorspace) { - /* Depth stencil formats. */ + /* Depth stencil formats. + * Swizzles are added in r300_merge_textures_and_samplers. */ case UTIL_FORMAT_COLORSPACE_ZS: switch (format) { case PIPE_FORMAT_Z16_UNORM: - return R300_EASY_TX_FORMAT(X, X, X, X, X16); + return R300_TX_FORMAT_X16; case PIPE_FORMAT_X8Z24_UNORM: case PIPE_FORMAT_S8_USCALED_Z24_UNORM: - return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP); + return R300_TX_FORMAT_W24_FP; default: return ~0; /* Unsupported. */ } @@ -131,43 +173,7 @@ uint32_t r300_translate_texformat(enum pipe_format format, } } - /* Get swizzle. */ - if (swizzle_view) { - /* Compose two sets of swizzles. */ - for (i = 0; i < 4; i++) { - swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ? - desc->swizzle[swizzle_view[i]] : swizzle_view[i]; - } - } else { - memcpy(swizzle, desc->swizzle, sizeof(swizzle)); - } - - /* Add swizzle. */ - for (i = 0; i < 4; i++) { - switch (swizzle[i]) { - case UTIL_FORMAT_SWIZZLE_X: - case UTIL_FORMAT_SWIZZLE_NONE: - result |= swizzle_bit[0] << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_Y: - result |= swizzle_bit[1] << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_Z: - result |= swizzle_bit[2] << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_W: - result |= swizzle_bit[3] << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_0: - result |= R300_TX_FORMAT_ZERO << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_1: - result |= R300_TX_FORMAT_ONE << swizzle_shift[i]; - break; - default: - return ~0; /* Unsupported. */ - } - } + result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view); /* S3TC formats. */ if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index ba79ec068a..2d8f0e1439 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -27,6 +27,9 @@ struct r300_texture; +unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format, + const unsigned char *swizzle_view); + uint32_t r300_translate_texformat(enum pipe_format format, const unsigned char *swizzle_view); -- cgit v1.2.3