r300g: pass depth texture swizzle to the compiler if compare mode is enabled
authorMarek Olšák <maraeo@gmail.com>
Sat, 8 May 2010 16:51:03 +0000 (18:51 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sat, 8 May 2010 21:03:45 +0000 (23:03 +0200)
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_fs.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 2e91a5b26598cf5e0608a0df908e1f18cf4e86e9..b3c54595941155e9cf124f59b27e5172aa51d292 100644 (file)
@@ -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 {
index 19023457bf3528f6b461c5bc4cc90a35a3756fee..30aa0651399aeadbb3d2f57496418c934f26dba6 100644 (file)
@@ -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;
index 446422ca0f045e58dc71055e71feeab3025ddbf8..fe3eae9805f2825b22045bced046fb188fe79c43 100644 (file)
@@ -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);
         }
index e3adace0faa8e08c9525aefbda8450fbc5b1b764..193a60c034f5abaa1bac667564ad66c308388d28 100644 (file)
@@ -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;
index a2fefde3529858bd2fde0fedd6db4163be06896f..c0911aef385736e20698a106e2b96fffd509d090 100644 (file)
@@ -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) {
index ba79ec068a13e7c3f2727e89a6da9a61d1014b8c..2d8f0e1439396e43706a305f6f1611a33496a8b1 100644 (file)
@@ -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);