Mesa (master): r600g: improve texture format checker.

Dave Airlie airlied at kemper.freedesktop.org
Thu Aug 12 06:21:01 UTC 2010


Module: Mesa
Branch: master
Commit: e2df0a8b234efde140b340c2c9b67b06b789b758
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e2df0a8b234efde140b340c2c9b67b06b789b758

Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Aug 12 16:06:40 2010 +1000

r600g: improve texture format checker.

This takes the r300g texture format checker and fixes it up for r600g,
it passes glean texSwizzle, pixelformats, and texture_srgb tests,

however I think it L8S8_SRGB is broken as is L8_SRGB, need to investigate.

Signed-off-by: Dave Airlie <airlied at redhat.com>

---

 src/gallium/drivers/r600/r600_context.h       |    3 +
 src/gallium/drivers/r600/r600_state.c         |   22 +-
 src/gallium/drivers/r600/r600_state_inlines.h |    2 +-
 src/gallium/drivers/r600/r600_texture.c       |  248 +++++++++++++++++++++++++
 4 files changed, 263 insertions(+), 12 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_context.h b/src/gallium/drivers/r600/r600_context.h
index c606dbb..76d5de8 100644
--- a/src/gallium/drivers/r600/r600_context.h
+++ b/src/gallium/drivers/r600/r600_context.h
@@ -175,4 +175,7 @@ extern int r600_pipe_shader_update(struct pipe_context *ctx,
 #define R600_ERR(fmt, args...) \
 	fprintf(stderr, "EE %s/%s:%d - "fmt, __FILE__, __func__, __LINE__, ##args)
 
+uint32_t r600_translate_texformat(enum pipe_format format,
+				  const unsigned char *swizzle_view, 
+				  uint32_t *word4_p, uint32_t *yuv_format_p);
 #endif
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index ed2d9f9..46e8f2a 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -1169,8 +1169,16 @@ static struct radeon_state *r600_resource(struct r600_context *rctx,
 	struct r600_resource *rbuffer;
 	struct radeon_state *rstate;
 	unsigned format;
-
-	format = r600_translate_colorformat(view->texture->format);
+	uint32_t word4 = 0, yuv_format = 0;
+	unsigned char swizzle[4];
+
+	swizzle[0] = view->swizzle_r;
+	swizzle[1] = view->swizzle_g;
+	swizzle[2] = view->swizzle_b;
+	swizzle[3] = view->swizzle_a;
+	format = r600_translate_texformat(view->texture->format,
+					  swizzle,
+					  &word4, &yuv_format);
 	if (format == ~0)
 		return NULL;
 	desc = util_format_description(view->texture->format);
@@ -1204,18 +1212,10 @@ static struct radeon_state *r600_resource(struct r600_context *rctx,
 	rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = 0;
 	rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD3] = tmp->offset[1] >> 8;
 	rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD4] =
-			S_038010_FORMAT_COMP_X(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) |
-			S_038010_FORMAT_COMP_Y(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) |
-			S_038010_FORMAT_COMP_Z(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) |
-			S_038010_FORMAT_COMP_W(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) |
+		        word4 | 
 			S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_NORM) |
 			S_038010_SRF_MODE_ALL(V_038010_SFR_MODE_NO_ZERO) |
 			S_038010_REQUEST_SIZE(1) |
-			S_038010_DST_SEL_X(r600_tex_swizzle(view->swizzle_b)) |
-			S_038010_DST_SEL_Y(r600_tex_swizzle(view->swizzle_g)) |
-			S_038010_DST_SEL_Z(r600_tex_swizzle(view->swizzle_r)) |
-			S_038010_DST_SEL_W(r600_tex_swizzle(view->swizzle_a)) |
-		        S_038010_FORCE_DEGAMMA(desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB ? 1 : 0) |
 			S_038010_BASE_LEVEL(view->first_level);
 	rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD5] =
 			S_038014_LAST_LEVEL(view->last_level) |
diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h
index 8271ad1..060a27c 100644
--- a/src/gallium/drivers/r600/r600_state_inlines.h
+++ b/src/gallium/drivers/r600/r600_state_inlines.h
@@ -289,7 +289,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
 
 static INLINE boolean r600_is_sampler_format_supported(enum pipe_format format)
 {
-	return r600_translate_colorformat(format) != ~0;
+	return r600_translate_texformat(format, NULL, NULL, NULL) != ~0;
 }
 
 static INLINE boolean r600_is_colorbuffer_format_supported(enum pipe_format format)
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 1bce911..30d79eb 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -33,6 +33,7 @@
 #include "r600_screen.h"
 #include "r600_context.h"
 #include "r600_resource.h"
+#include "r600d.h"
 
 extern struct u_resource_vtbl r600_texture_vtbl;
 
@@ -277,3 +278,250 @@ void r600_init_screen_texture_functions(struct pipe_screen *screen)
 	screen->get_tex_surface = r600_get_tex_surface;
 	screen->tex_surface_destroy = r600_tex_surface_destroy;
 }
+
+static unsigned r600_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] = {
+	    16, 19, 22, 25,
+    };
+    const uint32_t swizzle_bit[4] = {
+	    0, 1, 2, 3,
+    };
+
+    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 |= V_038010_SQ_SEL_0 << swizzle_shift[i];
+                break;
+            case UTIL_FORMAT_SWIZZLE_1:
+                result |= V_038010_SQ_SEL_1 << swizzle_shift[i];
+                break;
+            default: /* UTIL_FORMAT_SWIZZLE_X */
+                result |= swizzle_bit[0] << swizzle_shift[i];
+        }
+    }
+    return result;
+}
+
+/* texture format translate */
+uint32_t r600_translate_texformat(enum pipe_format format,
+				  const unsigned char *swizzle_view, 
+				  uint32_t *word4_p, uint32_t *yuv_format_p)
+{
+	uint32_t result = 0, word4 = 0, yuv_format = 0;
+	const struct util_format_description *desc;
+	boolean uniform = TRUE;
+	int i;
+	const uint32_t sign_bit[4] = {
+		S_038010_FORMAT_COMP_X(V_038010_SQ_FORMAT_COMP_SIGNED),
+		S_038010_FORMAT_COMP_Y(V_038010_SQ_FORMAT_COMP_SIGNED),
+		S_038010_FORMAT_COMP_Z(V_038010_SQ_FORMAT_COMP_SIGNED),
+		S_038010_FORMAT_COMP_W(V_038010_SQ_FORMAT_COMP_SIGNED)
+	};
+	desc = util_format_description(format);
+
+	/* Colorspace (return non-RGB formats directly). */
+	switch (desc->colorspace) {
+		/* Depth stencil formats */
+	case UTIL_FORMAT_COLORSPACE_ZS:
+		switch (format) {
+		case PIPE_FORMAT_Z16_UNORM:
+			result = V_028010_DEPTH_16;
+			goto out_word4;
+		case PIPE_FORMAT_Z24X8_UNORM:
+			result = V_028010_DEPTH_X8_24;
+			goto out_word4;
+		case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+			result = V_028010_DEPTH_8_24;
+			goto out_word4;
+		default:
+			goto out_unknown;
+		}
+
+	case UTIL_FORMAT_COLORSPACE_YUV:
+		yuv_format |= (1 << 30);
+		switch (format) {
+                case PIPE_FORMAT_UYVY:
+                case PIPE_FORMAT_YUYV:
+		default:
+			break;
+		}
+		goto out_unknown; /* TODO */
+		
+	case UTIL_FORMAT_COLORSPACE_SRGB:
+		word4 |= S_038010_FORCE_DEGAMMA(1);
+		if (format == PIPE_FORMAT_L8A8_SRGB || format == PIPE_FORMAT_L8_SRGB)
+			goto out_unknown; /* fails for some reason - TODO */
+		break;
+
+	default:
+		break;
+	}
+	
+	word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view);
+
+	/* S3TC formats. TODO */
+	if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
+		goto out_unknown;
+	}
+
+
+	for (i = 0; i < desc->nr_channels; i++) {	
+		if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
+			word4 |= sign_bit[i];
+		}
+	}
+
+	/* R8G8Bx_SNORM - TODO CxV8U8 */
+
+	/* RGTC - TODO */
+
+	/* 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;
+	}
+	
+	/* Non-uniform formats. */
+	if (!uniform) {
+		switch(desc->nr_channels) {
+		case 3:
+			if (desc->channel[0].size == 5 &&
+			    desc->channel[1].size == 6 &&
+			    desc->channel[2].size == 5) {
+				result |= V_0280A0_COLOR_5_6_5;
+				goto out_word4;
+			}
+			goto out_unknown;
+		case 4:
+			if (desc->channel[0].size == 5 &&
+			    desc->channel[1].size == 5 &&
+			    desc->channel[2].size == 5 &&
+			    desc->channel[3].size == 1) {
+				result |= V_0280A0_COLOR_1_5_5_5;
+				goto out_word4;
+			}
+			if (desc->channel[0].size == 10 &&
+			    desc->channel[1].size == 10 &&
+			    desc->channel[2].size == 10 &&
+			    desc->channel[3].size == 2) {
+				result |= V_0280A0_COLOR_10_10_10_2;
+				goto out_word4;
+			}
+			goto out_unknown;
+		}
+		goto out_unknown;
+	}
+
+	/* uniform formats */
+	switch (desc->channel[0].type) {
+	case UTIL_FORMAT_TYPE_UNSIGNED:
+	case UTIL_FORMAT_TYPE_SIGNED:
+		if (!desc->channel[0].normalized &&
+		    desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
+			goto out_unknown;
+		}
+
+		switch (desc->channel[0].size) {
+		case 4:
+			switch (desc->nr_channels) {
+			case 2:
+				result |= V_0280A0_COLOR_4_4;
+				goto out_word4;
+			case 4:
+				result |= V_0280A0_COLOR_4_4_4_4;
+				goto out_word4;
+			}
+			goto out_unknown;
+		case 8:
+			switch (desc->nr_channels) {
+			case 1:
+				result |= V_0280A0_COLOR_8;
+				goto out_word4;
+			case 2:
+				result |= V_0280A0_COLOR_8_8;
+				goto out_word4;
+			case 4:
+				result |= V_0280A0_COLOR_8_8_8_8;
+				goto out_word4;
+			}
+			goto out_unknown;
+		case 16:
+			switch (desc->nr_channels) {
+			case 1:
+				result |= V_0280A0_COLOR_16;
+				goto out_word4;
+			case 2:
+				result |= V_0280A0_COLOR_16_16;
+				goto out_word4;
+			case 4:
+				result |= V_0280A0_COLOR_16_16_16_16;
+				goto out_word4;
+			}
+		}
+		goto out_unknown;
+
+	case UTIL_FORMAT_TYPE_FLOAT:
+		switch (desc->channel[0].size) {
+		case 16:
+			switch (desc->nr_channels) {
+			case 1:
+				result |= V_0280A0_COLOR_16_FLOAT;
+				goto out_word4;
+			case 2:
+				result |= V_0280A0_COLOR_16_16_FLOAT;
+				goto out_word4;
+			case 4:
+				result |= V_0280A0_COLOR_16_16_16_16_FLOAT;
+				goto out_word4;
+			}
+			goto out_unknown;
+		case 32:
+			switch (desc->nr_channels) {
+			case 1:
+				result |= V_0280A0_COLOR_32_FLOAT;
+				goto out_word4;
+			case 2:
+				result |= V_0280A0_COLOR_32_32_FLOAT;
+				goto out_word4;
+			case 4:
+				result |= V_0280A0_COLOR_32_32_32_32_FLOAT;
+				goto out_word4;
+			}
+		}
+		
+	}
+out_word4:
+	if (word4_p)
+		*word4_p = word4;
+	if (yuv_format_p)
+		*yuv_format_p = yuv_format;
+//	fprintf(stderr,"returning %08x %08x %08x\n", result, word4, yuv_format);
+	return result;
+out_unknown:
+//	R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format));
+	return ~0;
+}




More information about the mesa-commit mailing list