diff options
| author | Marek Olšák <maraeo@gmail.com> | 2010-07-25 23:40:51 +0200 | 
|---|---|---|
| committer | Marek Olšák <maraeo@gmail.com> | 2010-07-25 23:40:51 +0200 | 
| commit | 6f2936c654c68388b9c43a189a1b8c06f3a9d241 (patch) | |
| tree | f9bb4191f6b07f59b604e5067005b22e41756fa5 | |
| parent | 451a0ddb190e5185372fed9ec57d24a822442ecc (diff) | |
r300g: implement D24X8 texture sampling for r3xx-r4xx
Because the hw can't sample it, I reinterpret the format as G16R16 and
sample the G component. This gives 16 bits of precision, which should be
enough for depth texturing (surprisingly, the sampled values are exactly
the same as in D16 textures).
This also enables EXT_packed_depth_stencil on those old chipsets, finally.
| -rw-r--r-- | src/gallium/drivers/r300/r300_screen.c | 4 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_state.c | 6 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_state_derived.c | 33 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_texture.c | 10 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_texture.h | 3 | 
5 files changed, 34 insertions, 22 deletions
| diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 5a11b98eb6..676430f5fe 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -257,8 +257,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,      uint32_t retval = 0;      boolean is_r500 = r300_screen(screen)->caps.is_r500;      boolean is_r400 = r300_screen(screen)->caps.is_r400; -    boolean is_z24 = format == PIPE_FORMAT_X8Z24_UNORM || -                     format == PIPE_FORMAT_S8_USCALED_Z24_UNORM;      boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM ||                                format == PIPE_FORMAT_R10G10B10X2_SNORM ||                                format == PIPE_FORMAT_B10G10R10A2_UNORM || @@ -293,8 +291,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,      /* Check sampler format support. */      if ((usage & PIPE_BIND_SAMPLER_VIEW) && -        /* Z24 cannot be sampled from on non-r5xx. */ -        (is_r500 || !is_z24) &&          /* ATI1N is r5xx-only. */          (is_r500 || !is_ati1n) &&          /* ATI2N is supported on r4xx-r5xx. */ diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index bbea7e1589..3e221f2e02 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1330,6 +1330,7 @@ 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); +    boolean is_r500 = r300_screen(pipe->screen)->caps.is_r500;      if (view) {          view->base = *templ; @@ -1345,8 +1346,9 @@ r300_create_sampler_view(struct pipe_context *pipe,          view->format = tex->tx_format;          view->format.format1 |= r300_translate_texformat(templ->format, -                                                         view->swizzle); -        if (r300_screen(pipe->screen)->caps.is_r500) { +                                                         view->swizzle, +                                                         is_r500); +        if (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 48912e1555..a85db27064 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -528,15 +528,9 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)      struct r300_sampler_state *sampler;      struct r300_sampler_view *view;      struct r300_texture *tex; -    unsigned min_level, max_level, i, size; +    unsigned min_level, max_level, i, j, 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 -    };      /* The KIL opcode fix, see below. */      if (!count && !r300->screen->caps.is_r500) @@ -563,14 +557,29 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)              /* Assign a texture cache region. */              texstate->format.format1 |= view->texcache_region; -            /* 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. */ +            /* Depth textures are kinda special. */              if (util_format_is_depth_or_stencil(tex->desc.b.b.format)) { +                unsigned char depth_swizzle[4]; + +                if (!r300->screen->caps.is_r500 && +                    util_format_get_blocksizebits(tex->desc.b.b.format) == 32) { +                    /* X24x8 is sampled as Y16X16 on r3xx-r4xx. +                     * The depth here is at the Y component. */ +                    for (j = 0; j < 4; j++) +                        depth_swizzle[j] = UTIL_FORMAT_SWIZZLE_Y; +                } else { +                    for (j = 0; j < 4; j++) +                        depth_swizzle[j] = UTIL_FORMAT_SWIZZLE_X; +                } + +                /* If compare mode is disabled, sampler view swizzles +                 * are stored in the format. +                 * Otherwise, the swizzles must be applied after the compare +                 * mode in the fragment shader. */                  if (sampler->state.compare_mode == PIPE_TEX_COMPARE_NONE) {                      texstate->format.format1 |= -                        r300_get_swizzle_combined(depth_swizzle, view->swizzle); +                        r300_get_swizzle_combined(depth_swizzle, +                                                  view->swizzle);                  } else {                      texstate->format.format1 |=                          r300_get_swizzle_combined(depth_swizzle, 0); diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index f1118dfd7d..fcdca5605e 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -105,7 +105,8 @@ unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,   * The FORMAT specifies how the texture sampler will treat the texture, and   * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */  uint32_t r300_translate_texformat(enum pipe_format format, -                                  const unsigned char *swizzle_view) +                                  const unsigned char *swizzle_view, +                                  boolean is_r500)  {      uint32_t result = 0;      const struct util_format_description *desc; @@ -130,7 +131,10 @@ uint32_t r300_translate_texformat(enum pipe_format format,                      return R300_TX_FORMAT_X16;                  case PIPE_FORMAT_X8Z24_UNORM:                  case PIPE_FORMAT_S8_USCALED_Z24_UNORM: -                    return R500_TX_FORMAT_Y8X24; +                    if (is_r500) +                        return R500_TX_FORMAT_Y8X24; +                    else +                        return R300_TX_FORMAT_Y16X16;                  default:                      return ~0; /* Unsupported. */              } @@ -533,7 +537,7 @@ boolean r300_is_zs_format_supported(enum pipe_format format)  boolean r300_is_sampler_format_supported(enum pipe_format format)  { -    return r300_translate_texformat(format, 0) != ~0; +    return r300_translate_texformat(format, 0, TRUE) != ~0;  }  static void r300_texture_setup_immutable_state(struct r300_screen* screen, diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 585036ab3b..a4524320fd 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -35,7 +35,8 @@ 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); +                                  const unsigned char *swizzle_view, +                                  boolean is_r500);  uint32_t r500_tx_format_msb_bit(enum pipe_format format); | 
