Mesa (master): r600g: improve supported format selection.

Dave Airlie airlied at kemper.freedesktop.org
Fri Aug 6 04:53:01 UTC 2010


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

Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Aug  6 14:53:38 2010 +1000

r600g: improve supported format selection.

This fixes fbo-readpixels piglit test, and adds support for swapping
the formats. Not all formats are correct yet I don't think.

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

---

 src/gallium/drivers/r600/r600_draw.c          |    6 +-
 src/gallium/drivers/r600/r600_helper.c        |   99 ----------------
 src/gallium/drivers/r600/r600_screen.c        |   76 +++++++------
 src/gallium/drivers/r600/r600_state.c         |   15 ++-
 src/gallium/drivers/r600/r600_state_inlines.h |  153 +++++++++++++++++++++++++
 src/gallium/drivers/r600/r600d.h              |    5 +
 6 files changed, 212 insertions(+), 142 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_draw.c b/src/gallium/drivers/r600/r600_draw.c
index 7130bf2..3a54cee 100644
--- a/src/gallium/drivers/r600/r600_draw.c
+++ b/src/gallium/drivers/r600/r600_draw.c
@@ -34,7 +34,7 @@
 #include "r600_screen.h"
 #include "r600_context.h"
 #include "r600_resource.h"
-#include "r600d.h"
+#include "r600_state_inlines.h"
 
 struct r600_draw {
 	struct pipe_context	*ctx;
@@ -100,9 +100,7 @@ static int r600_draw_common(struct r600_draw *draw)
 		vertex_buffer = &rctx->vertex_buffer[j];
 		rbuffer = (struct r600_resource*)vertex_buffer->buffer;
 		offset = rctx->vertex_elements->elements[i].src_offset + vertex_buffer->buffer_offset;
-		r = r600_conv_pipe_format(rctx->vertex_elements->elements[i].src_format, &format);
-		if (r)
-			return r;
+		format = r600_translate_colorformat(rctx->vertex_elements->elements[i].src_format);
 		r = radeon_state_init(&vs_resource, rscreen->rw, R600_VS_RESOURCE_TYPE, R600_VS_RESOURCE + i);
 		if (r)
 			return r;
diff --git a/src/gallium/drivers/r600/r600_helper.c b/src/gallium/drivers/r600/r600_helper.c
index c672fe7..5e0e0aa 100644
--- a/src/gallium/drivers/r600/r600_helper.c
+++ b/src/gallium/drivers/r600/r600_helper.c
@@ -30,105 +30,6 @@
 #include "r600_context.h"
 #include "r600d.h"
 
-int r600_conv_pipe_format(unsigned pformat, unsigned *format)
-{
-	switch (pformat) {
-	case PIPE_FORMAT_R32G32B32_FLOAT:
-		*format = 0x30;
-		return 0;
-	case PIPE_FORMAT_R32G32B32A32_FLOAT:
-		*format = V_0280A0_COLOR_32_32_32_32_FLOAT;
-		return 0;
-	case PIPE_FORMAT_A8R8G8B8_UNORM:
-	case PIPE_FORMAT_X8R8G8B8_UNORM:
-	case PIPE_FORMAT_B8G8R8A8_UNORM:
-	case PIPE_FORMAT_B8G8R8X8_UNORM:
-	case PIPE_FORMAT_R8G8B8A8_UNORM:
-	case PIPE_FORMAT_R8G8B8X8_UNORM:
-	case PIPE_FORMAT_R8G8B8A8_USCALED:
-	case PIPE_FORMAT_R8G8B8A8_SNORM:
-	case PIPE_FORMAT_R8G8B8A8_SSCALED:
-		*format = V_0280A0_COLOR_8_8_8_8;
-		return 0;
-	case PIPE_FORMAT_R32_FLOAT:
-		*format = V_0280A0_COLOR_32_FLOAT;
-		return 0;
-	case PIPE_FORMAT_R32G32_FLOAT:
-		*format = V_0280A0_COLOR_32_32_FLOAT;
-		return 0;
-	case PIPE_FORMAT_L8_UNORM:
-	case PIPE_FORMAT_A8_UNORM:
-	case PIPE_FORMAT_I8_UNORM:
-		*format = V_0280A0_COLOR_8;
-		return 0;
-	case PIPE_FORMAT_B4G4R4A4_UNORM:
-		*format = V_0280A0_COLOR_4_4_4_4;
-		return 0;
-	case PIPE_FORMAT_B5G6R5_UNORM:
-		*format = V_0280A0_COLOR_5_6_5;
-		return 0;
-	case PIPE_FORMAT_L16_UNORM:
-	case PIPE_FORMAT_Z16_UNORM:
-	case PIPE_FORMAT_Z32_UNORM:
-	case PIPE_FORMAT_Z32_FLOAT:
-	case PIPE_FORMAT_R64_FLOAT:
-	case PIPE_FORMAT_R64G64_FLOAT:
-	case PIPE_FORMAT_R64G64B64_FLOAT:
-	case PIPE_FORMAT_R64G64B64A64_FLOAT:
-	case PIPE_FORMAT_R32_UNORM:
-	case PIPE_FORMAT_R32G32_UNORM:
-	case PIPE_FORMAT_R32G32B32_UNORM:
-	case PIPE_FORMAT_R32G32B32A32_UNORM:
-	case PIPE_FORMAT_R32_USCALED:
-	case PIPE_FORMAT_R32G32_USCALED:
-	case PIPE_FORMAT_R32G32B32_USCALED:
-	case PIPE_FORMAT_R32G32B32A32_USCALED:
-	case PIPE_FORMAT_R32_SNORM:
-	case PIPE_FORMAT_R32G32_SNORM:
-	case PIPE_FORMAT_R32G32B32_SNORM:
-	case PIPE_FORMAT_R32G32B32A32_SNORM:
-	case PIPE_FORMAT_R32_SSCALED:
-	case PIPE_FORMAT_R32G32_SSCALED:
-	case PIPE_FORMAT_R32G32B32_SSCALED:
-	case PIPE_FORMAT_R32G32B32A32_SSCALED:
-	case PIPE_FORMAT_R16_UNORM:
-	case PIPE_FORMAT_R16G16_UNORM:
-	case PIPE_FORMAT_R16G16B16_UNORM:
-	case PIPE_FORMAT_R16G16B16A16_UNORM:
-	case PIPE_FORMAT_R16_USCALED:
-	case PIPE_FORMAT_R16G16_USCALED:
-	case PIPE_FORMAT_R16G16B16_USCALED:
-	case PIPE_FORMAT_R16G16B16A16_USCALED:
-	case PIPE_FORMAT_R16_SNORM:
-	case PIPE_FORMAT_R16G16_SNORM:
-	case PIPE_FORMAT_R16G16B16_SNORM:
-	case PIPE_FORMAT_R16G16B16A16_SNORM:
-	case PIPE_FORMAT_R16_SSCALED:
-	case PIPE_FORMAT_R16G16_SSCALED:
-	case PIPE_FORMAT_R16G16B16_SSCALED:
-	case PIPE_FORMAT_R16G16B16A16_SSCALED:
-	case PIPE_FORMAT_R8_UNORM:
-	case PIPE_FORMAT_R8G8_UNORM:
-	case PIPE_FORMAT_R8G8B8_UNORM:
-	case PIPE_FORMAT_R8_USCALED:
-	case PIPE_FORMAT_R8G8_USCALED:
-	case PIPE_FORMAT_R8G8B8_USCALED:
-	case PIPE_FORMAT_R8_SNORM:
-	case PIPE_FORMAT_R8G8_SNORM:
-	case PIPE_FORMAT_R8G8B8_SNORM:
-	case PIPE_FORMAT_R8_SSCALED:
-	case PIPE_FORMAT_R8G8_SSCALED:
-	case PIPE_FORMAT_R8G8B8_SSCALED:
-	case PIPE_FORMAT_R32_FIXED:
-	case PIPE_FORMAT_R32G32_FIXED:
-	case PIPE_FORMAT_R32G32B32_FIXED:
-	case PIPE_FORMAT_R32G32B32A32_FIXED:
-	default:
-		R600_ERR("unsupported %d\n", pformat);
-		return -EINVAL;
-	}
-}
-
 int r600_conv_pipe_prim(unsigned pprim, unsigned *prim)
 {
 	switch (pprim) {
diff --git a/src/gallium/drivers/r600/r600_screen.c b/src/gallium/drivers/r600/r600_screen.c
index 68615ca..4b87327 100644
--- a/src/gallium/drivers/r600/r600_screen.c
+++ b/src/gallium/drivers/r600/r600_screen.c
@@ -32,6 +32,7 @@
 #include "r600_context.h"
 #include "r600_public.h"
 #include "r600_resource.h"
+#include "r600_state_inlines.h"
 
 static const char* r600_get_vendor(struct pipe_screen* pscreen)
 {
@@ -133,50 +134,51 @@ static boolean r600_is_format_supported(struct pipe_screen* screen,
 					enum pipe_format format,
 					enum pipe_texture_target target,
 					unsigned sample_count,
-					unsigned bindings,
+					unsigned usage,
 					unsigned geom_flags)
 {
+	unsigned retval = 0;
 	if (target >= PIPE_MAX_TEXTURE_TYPES) {
 		R600_ERR("r600: unsupported texture type %d\n", target);
 		return FALSE;
 	}
-	switch (format) {
-	case PIPE_FORMAT_B4G4R4A4_UNORM:
-	case PIPE_FORMAT_B5G6R5_UNORM:
-	case PIPE_FORMAT_B5G5R5A1_UNORM:
-	case PIPE_FORMAT_A8_UNORM:
-	case PIPE_FORMAT_L8_UNORM:
-	case PIPE_FORMAT_A8R8G8B8_SRGB:
-	case PIPE_FORMAT_R8G8B8A8_SRGB:
-	case PIPE_FORMAT_DXT1_RGB:
-	case PIPE_FORMAT_DXT1_RGBA:
-	case PIPE_FORMAT_DXT3_RGBA:
-	case PIPE_FORMAT_DXT5_RGBA:
-	case PIPE_FORMAT_UYVY:
-	case PIPE_FORMAT_L8_SRGB:
-	case PIPE_FORMAT_L8A8_SRGB:
-	case PIPE_FORMAT_L8A8_UNORM:
-	case PIPE_FORMAT_A8R8G8B8_UNORM:
-	case PIPE_FORMAT_X8R8G8B8_UNORM:
-	case PIPE_FORMAT_R8G8B8A8_UNORM:
-	case PIPE_FORMAT_R8G8B8X8_UNORM:
-	case PIPE_FORMAT_B8G8R8A8_UNORM:
-	case PIPE_FORMAT_B8G8R8X8_UNORM:
-	case PIPE_FORMAT_A8B8G8R8_SRGB:
-	case PIPE_FORMAT_B8G8R8A8_SRGB:
-	case PIPE_FORMAT_I8_UNORM:
-	case PIPE_FORMAT_Z16_UNORM:
-	case PIPE_FORMAT_X8Z24_UNORM:
-	case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
-	case PIPE_FORMAT_Z32_UNORM:
-	case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
-	case PIPE_FORMAT_Z24X8_UNORM:
-		return TRUE;
-	default:
-		/* Unknown format... */
-		break;
+
+	/* Multisample */
+	if (sample_count > 1)
+		return FALSE;
+
+	if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
+	    r600_is_sampler_format_supported(format)) {
+		retval |= PIPE_BIND_SAMPLER_VIEW;
+	}
+
+	if ((usage & (PIPE_BIND_RENDER_TARGET |
+                  PIPE_BIND_DISPLAY_TARGET |
+                  PIPE_BIND_SCANOUT |
+                  PIPE_BIND_SHARED)) &&
+	    r600_is_colorbuffer_format_supported(format)) {
+		retval |= usage &
+			(PIPE_BIND_RENDER_TARGET |
+			 PIPE_BIND_DISPLAY_TARGET |
+			 PIPE_BIND_SCANOUT |
+			 PIPE_BIND_SHARED);
 	}
-	return FALSE;
+
+	if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
+	    r600_is_zs_format_supported(format)) {
+		retval |= PIPE_BIND_DEPTH_STENCIL;
+	}
+
+	if ((usage & PIPE_BIND_VERTEX_BUFFER) &&
+	    r600_is_vertex_format_supported(format))
+		retval |= PIPE_BIND_VERTEX_BUFFER;
+
+	if (usage & PIPE_BIND_TRANSFER_READ)
+		retval |= PIPE_BIND_TRANSFER_READ;
+	if (usage & PIPE_BIND_TRANSFER_WRITE)
+		retval |= PIPE_BIND_TRANSFER_WRITE;
+
+	return retval == usage;
 }
 
 static void r600_destroy_screen(struct pipe_screen* pscreen)
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 926a19c..b8d5045 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -668,6 +668,8 @@ static int r600_cb0(struct r600_context *rctx, struct radeon_state *rstate)
 	const struct pipe_framebuffer_state *state = &rctx->framebuffer->state.framebuffer;
 	unsigned level = state->cbufs[0]->level;
 	unsigned pitch, slice;
+	unsigned color_info;
+	unsigned format, swap;
 	int r;
 
 	r = radeon_state_init(rstate, rscreen->rw, R600_CB0_TYPE, R600_CB0);
@@ -685,8 +687,16 @@ static int r600_cb0(struct r600_context *rctx, struct radeon_state *rstate)
 	rstate->nbo = 3;
 	pitch = (rtex->pitch[level] / rtex->bpt) / 8 - 1;
 	slice = (rtex->pitch[level] / rtex->bpt) * state->cbufs[0]->height / 64 - 1;
+
+	format = r600_translate_colorformat(rtex->resource.base.b.format);
+	swap = r600_translate_colorswap(rtex->resource.base.b.format);
+	color_info = S_0280A0_FORMAT(format) |
+	  S_0280A0_COMP_SWAP(swap) |
+	  S_0280A0_BLEND_CLAMP(1) |
+	  S_0280A0_SOURCE_FORMAT(1);
+
 	rstate->states[R600_CB0__CB_COLOR0_BASE] = 0x00000000;
-	rstate->states[R600_CB0__CB_COLOR0_INFO] = 0x08110068;
+	rstate->states[R600_CB0__CB_COLOR0_INFO] = color_info;
 	rstate->states[R600_CB0__CB_COLOR0_SIZE] = S_028060_PITCH_TILE_MAX(pitch) |
 						S_028060_SLICE_TILE_MAX(slice);
 	rstate->states[R600_CB0__CB_COLOR0_VIEW] = 0x00000000;
@@ -1103,7 +1113,8 @@ static int r600_resource(struct r600_context *rctx, struct radeon_state *rstate,
 	r = radeon_state_init(rstate, rscreen->rw, R600_PS_RESOURCE_TYPE, id);
 	if (r)
 		return r;
-	if (r600_conv_pipe_format(view->texture->format, &format))
+	format = r600_translate_colorformat(view->texture->format);
+	if (format == ~0)
 		return -EINVAL;
 	desc = util_format_description(view->texture->format);
 	if (desc == NULL) {
diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h
index 321e75d..b45089d 100644
--- a/src/gallium/drivers/r600/r600_state_inlines.h
+++ b/src/gallium/drivers/r600/r600_state_inlines.h
@@ -23,6 +23,9 @@
 #ifndef R600_STATE_INLINES_H
 #define R600_STATE_INLINES_H
 
+#include "util/u_format.h"
+#include "r600d.h"
+
 static INLINE uint32_t r600_translate_blend_function(int blend_func)
 {
 	switch (blend_func) {
@@ -126,4 +129,154 @@ static INLINE uint32_t r600_translate_ds_func(int func)
 	return func;
 }
 
+static uint32_t r600_translate_colorswap(enum pipe_format format)
+{
+	switch (format) {
+		/* 8-bit buffers. */
+        case PIPE_FORMAT_A8_UNORM:
+        case PIPE_FORMAT_I8_UNORM:
+        case PIPE_FORMAT_L8_UNORM:
+        case PIPE_FORMAT_R8_UNORM:
+        case PIPE_FORMAT_R8_SNORM:
+		return SWAP_STD;
+
+		/* 16-bit buffers. */
+        case PIPE_FORMAT_B5G6R5_UNORM:
+		return SWAP_STD_REV;
+
+        case PIPE_FORMAT_B5G5R5A1_UNORM:
+        case PIPE_FORMAT_B5G5R5X1_UNORM:
+		return SWAP_ALT;
+
+        case PIPE_FORMAT_B4G4R4A4_UNORM:
+        case PIPE_FORMAT_B4G4R4X4_UNORM:
+		return SWAP_ALT;
+		/* 32-bit buffers. */
+        case PIPE_FORMAT_B8G8R8A8_UNORM:
+        case PIPE_FORMAT_B8G8R8X8_UNORM:
+		return SWAP_ALT;
+
+        case PIPE_FORMAT_A8R8G8B8_UNORM:
+        case PIPE_FORMAT_X8R8G8B8_UNORM:
+		return SWAP_ALT_REV;
+        case PIPE_FORMAT_R8G8B8A8_SNORM:
+        case PIPE_FORMAT_R8G8B8X8_UNORM:
+		return SWAP_STD;
+
+        case PIPE_FORMAT_A8B8G8R8_UNORM:
+        case PIPE_FORMAT_X8B8G8R8_UNORM:
+//        case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
+		return SWAP_STD_REV;
+
+        case PIPE_FORMAT_R10G10B10A2_UNORM:
+        case PIPE_FORMAT_R10G10B10X2_SNORM:
+        case PIPE_FORMAT_B10G10R10A2_UNORM:
+        case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
+		return SWAP_STD_REV;
+
+		/* 64-bit buffers. */
+        case PIPE_FORMAT_R16G16B16A16_UNORM:
+        case PIPE_FORMAT_R16G16B16A16_SNORM:
+//		return V_0280A0_COLOR_16_16_16_16;
+        case PIPE_FORMAT_R16G16B16A16_FLOAT:
+//		return V_0280A0_COLOR_16_16_16_16_FLOAT;
+
+		/* 128-bit buffers. */
+        case PIPE_FORMAT_R32G32B32A32_FLOAT:
+//		return V_0280A0_COLOR_32_32_32_32_FLOAT;
+		return 0;
+	default:
+		R600_ERR("unsupported colorswap format %d\n", format);
+		return ~0;
+	}
+	return ~0;
+
+}
+
+static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
+{
+	switch (format) {
+		/* 8-bit buffers. */
+        case PIPE_FORMAT_A8_UNORM:
+        case PIPE_FORMAT_I8_UNORM:
+        case PIPE_FORMAT_L8_UNORM:
+        case PIPE_FORMAT_R8_UNORM:
+        case PIPE_FORMAT_R8_SNORM:
+		return V_0280A0_COLOR_8;
+
+		/* 16-bit buffers. */
+        case PIPE_FORMAT_B5G6R5_UNORM:
+		return V_0280A0_COLOR_5_6_5;
+
+        case PIPE_FORMAT_B5G5R5A1_UNORM:
+        case PIPE_FORMAT_B5G5R5X1_UNORM:
+		return V_0280A0_COLOR_1_5_5_5;
+
+        case PIPE_FORMAT_B4G4R4A4_UNORM:
+        case PIPE_FORMAT_B4G4R4X4_UNORM:
+		return V_0280A0_COLOR_4_4_4_4;
+
+		/* 32-bit buffers. */
+        case PIPE_FORMAT_B8G8R8A8_UNORM:
+        case PIPE_FORMAT_B8G8R8X8_UNORM:
+        case PIPE_FORMAT_A8R8G8B8_UNORM:
+        case PIPE_FORMAT_X8R8G8B8_UNORM:
+        case PIPE_FORMAT_A8B8G8R8_UNORM:
+        case PIPE_FORMAT_R8G8B8A8_SNORM:
+        case PIPE_FORMAT_X8B8G8R8_UNORM:
+        case PIPE_FORMAT_R8G8B8X8_UNORM:
+        case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
+		return V_0280A0_COLOR_8_8_8_8;
+
+        case PIPE_FORMAT_R10G10B10A2_UNORM:
+        case PIPE_FORMAT_R10G10B10X2_SNORM:
+        case PIPE_FORMAT_B10G10R10A2_UNORM:
+        case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
+		return V_0280A0_COLOR_10_10_10_2;
+
+		/* 64-bit buffers. */
+        case PIPE_FORMAT_R16G16B16A16_UNORM:
+        case PIPE_FORMAT_R16G16B16A16_SNORM:
+		return V_0280A0_COLOR_16_16_16_16;
+        case PIPE_FORMAT_R16G16B16A16_FLOAT:
+		return V_0280A0_COLOR_16_16_16_16_FLOAT;
+        case PIPE_FORMAT_R32G32_FLOAT:
+		return V_0280A0_COLOR_32_32_FLOAT;
+
+		/* 128-bit buffers. */
+        case PIPE_FORMAT_R32G32B32_FLOAT:
+        case PIPE_FORMAT_R32G32B32A32_FLOAT:
+		return V_0280A0_COLOR_32_32_32_32_FLOAT;
+
+		/* YUV buffers. */
+        case PIPE_FORMAT_UYVY:
+//		return R300_COLOR_FORMAT_YVYU;
+        case PIPE_FORMAT_YUYV:
+//		return R300_COLOR_FORMAT_VYUY;
+        default:
+		return ~0; /* Unsupported. */
+	}
+}
+
+static INLINE boolean r600_is_sampler_format_supported(enum pipe_format format)
+{
+	return r600_translate_colorformat(format) != ~0;
+}
+
+static INLINE boolean r600_is_colorbuffer_format_supported(enum pipe_format format)
+{
+	return r600_translate_colorformat(format) != ~0 &&
+		r600_translate_colorswap(format) != ~0;
+}
+
+static INLINE boolean r600_is_zs_format_supported(enum pipe_format format)
+{
+	return TRUE;
+}
+
+static INLINE boolean r600_is_vertex_format_supported(enum pipe_format format)
+{
+	return r600_translate_colorformat(format) != ~0;
+}
+
 #endif
diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h
index 8205bde..2d0ede2 100644
--- a/src/gallium/drivers/r600/r600d.h
+++ b/src/gallium/drivers/r600/r600d.h
@@ -1169,4 +1169,9 @@
 #define   G_0286D4_PNT_SPRITE_TOP_1(x)                 (((x) >> 14) & 0x1)
 #define   C_0286D4_PNT_SPRITE_TOP_1                    0xFFFFBFFF
 
+/* temporary swap */
+#define SWAP_STD 0
+#define SWAP_ALT 1
+#define SWAP_STD_REV 2
+#define SWAP_ALT_REV 3
 #endif




More information about the mesa-commit mailing list