r300g: add RGTC texture support
authorMarek Olšák <maraeo@gmail.com>
Thu, 1 Apr 2010 00:14:52 +0000 (02:14 +0200)
committerMarek Olšák <maraeo@gmail.com>
Thu, 1 Apr 2010 00:14:52 +0000 (02:14 +0200)
The CS checker already knows about this.

src/gallium/drivers/r300/r300_reg.h
src/gallium/drivers/r300/r300_screen.c
src/gallium/drivers/r300/r300_texture.c

index 1c2b252887784f3a090419ac2440ee59dac0e62c..0d6b7654f3012c4faa5706a0e67d3b7871da8c3a 100644 (file)
@@ -1556,6 +1556,26 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #      define R300_TX_FORMAT_32F_32F               0x1C
 #      define R300_TX_FORMAT_32F_32F_32F_32F       0x1D
 #       define R300_TX_FORMAT_W24_FP                0x1E
+#       define R400_TX_FORMAT_ATI2N                 0x1F
+
+/* These need TX_FORMAT2_[0-15].TXFORMAT_MSB set.
+
+   My guess is the 10-bit formats are the 8-bit ones but with filtering being
+   performed with the precision of 10 bits per channel. This makes sense
+   with sRGB textures since the conversion to linear space reduces the precision
+   significantly so the shader gets approximately the 8-bit precision
+   in the end. It might also improve the quality of HDR rendering where
+   high-precision filtering is desirable.
+
+   Again, this is guessed, the formats might mean something entirely else.
+   The others should be fine. */
+#       define R500_TX_FORMAT_X1                    0x0
+#       define R500_TX_FORMAT_X1_REV                0x1
+#       define R500_TX_FORMAT_X10                   0x2
+#       define R500_TX_FORMAT_Y10X10                0x3
+#       define R500_TX_FORMAT_W10Z10Y10X10          0x4
+#       define R500_TX_FORMAT_ATI1N                 0x5
+
 
 #       define R300_TX_FORMAT_SIGNED_W             (1 << 5)
 #       define R300_TX_FORMAT_SIGNED_Z             (1 << 6)
index 090964b0254744b52c3b21739b21caf7c13a4e14..50e5e9307e9a9295cb1037c89f8f684301c80a14 100644 (file)
@@ -207,9 +207,14 @@ 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;
+    boolean is_ati1n = format == PIPE_FORMAT_RGTC1_UNORM ||
+                       format == PIPE_FORMAT_RGTC1_SNORM;
+    boolean is_ati2n = format == PIPE_FORMAT_RGTC2_UNORM ||
+                       format == PIPE_FORMAT_RGTC2_SNORM;
 
     if (target >= PIPE_MAX_TEXTURE_TYPES) {
         fprintf(stderr, "r300: Implementation error: Received bogus texture "
@@ -221,6 +226,10 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
     if ((usage & PIPE_TEXTURE_USAGE_SAMPLER) &&
         /* 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. */
+        (is_r400 || is_r500 || !is_ati2n) &&
         r300_is_sampler_format_supported(format)) {
         retval |= PIPE_TEXTURE_USAGE_SAMPLER;
     }
index 92c29b53fd8205b5794005753577522425340a10..d4a64092c70413be1936b8007e320dd1c406daf0 100644 (file)
@@ -158,7 +158,7 @@ static uint32_t r300_translate_texformat(enum pipe_format format)
         }
     }
 
-    /* Compressed formats. */
+    /* S3TC formats. */
     if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
         switch (format) {
             case PIPE_FORMAT_DXT1_RGB:
@@ -184,6 +184,20 @@ static uint32_t r300_translate_texformat(enum pipe_format format)
         }
     }
 
+    /* RGTC formats. */
+    if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
+        switch (format) {
+            case PIPE_FORMAT_RGTC1_UNORM:
+            case PIPE_FORMAT_RGTC1_SNORM:
+                return R500_TX_FORMAT_ATI1N | result;
+            case PIPE_FORMAT_RGTC2_UNORM:
+            case PIPE_FORMAT_RGTC2_SNORM:
+                return R400_TX_FORMAT_ATI2N | result;
+            default:
+                return ~0; /* Unsupported/unknown. */
+        }
+    }
+
     /* See whether the components are of the same size. */
     for (i = 1; i < desc->nr_channels; i++) {
         uniform = uniform && desc->channel[0].size == desc->channel[i].size;
@@ -295,6 +309,17 @@ static uint32_t r300_translate_texformat(enum pipe_format format)
     return ~0; /* Unsupported/unknown. */
 }
 
+static uint32_t r500_tx_format_msb_bit(enum pipe_format format)
+{
+    switch (format) {
+        case PIPE_FORMAT_RGTC1_UNORM:
+        case PIPE_FORMAT_RGTC1_SNORM:
+            return R500_TXFORMAT_MSB;
+        default:
+            return 0;
+    }
+}
+
 /* Buffer formats. */
 
 /* Colorbuffer formats. This is the unswizzled format of the RB3D block's
@@ -520,6 +545,7 @@ static void r300_setup_texture_state(struct r300_screen* screen, struct r300_tex
         if (pt->height0 > 2048) {
             state->format2 |= R500_TXHEIGHT_BIT11;
         }
+        state->format2 |= r500_tx_format_msb_bit(pt->format);
     }
 
     SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n",