r300g: implement D24X8 texture sampling for r3xx-r4xx
authorMarek Olšák <maraeo@gmail.com>
Sun, 25 Jul 2010 21:40:51 +0000 (23:40 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sun, 25 Jul 2010 21:40:51 +0000 (23:40 +0200)
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.

src/gallium/drivers/r300/r300_screen.c
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r300/r300_state_derived.c
src/gallium/drivers/r300/r300_texture.c
src/gallium/drivers/r300/r300_texture.h

index 5a11b98eb6c5c49ba026f702874919c370bee5cf..676430f5fee61e24e11df23b5b7cc17ec54618f9 100644 (file)
@@ -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. */
index bbea7e1589e279314b0e22d8ba4778a0ba9c07cc..3e221f2e02de0d781fff819abf1c1dbf6200e724 100644 (file)
@@ -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);
         }
     }
index 48912e1555c28ac67f2696db4942993ce6fdf878..a85db27064cea647406d69c879a4e8909efd4515 100644 (file)
@@ -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);
index f1118dfd7ddc89be2c5748069269fed4d39fef1d..fcdca5605e934cd569227bbb0c9d8d285802f15d 100644 (file)
@@ -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,
index 585036ab3b3db5da920f4b0390c32c676a5ea739..a4524320fdac7cdb6e9b445abaa842be6ad7a254 100644 (file)
@@ -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);