Mesa (master): r600g: handle 16/32 u/s norm formats properly

Dave Airlie airlied at kemper.freedesktop.org
Fri Feb 11 03:42:43 UTC 2011


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

Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Feb 10 14:07:06 2011 +1000

r600g: handle 16/32 u/s norm formats properly

add support for the 32-bit types, also fixup the
export setting to handle types with channels > 11 bits properly

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

---

 src/gallium/drivers/r600/eg_state_inlines.h   |   10 ++++++----
 src/gallium/drivers/r600/evergreen_state.c    |   16 ++++++++++++++--
 src/gallium/drivers/r600/evergreend.h         |    3 +++
 src/gallium/drivers/r600/r600_state.c         |   15 +++++++++++++--
 src/gallium/drivers/r600/r600_state_inlines.h |   10 ++++++----
 src/gallium/drivers/r600/r600_texture.c       |   13 +++++++++++++
 src/gallium/drivers/r600/r600d.h              |    2 ++
 7 files changed, 57 insertions(+), 12 deletions(-)

diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h
index ca00e61..46369cc 100644
--- a/src/gallium/drivers/r600/eg_state_inlines.h
+++ b/src/gallium/drivers/r600/eg_state_inlines.h
@@ -362,14 +362,13 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format)
 		/* 64-bit buffers. */
 	case PIPE_FORMAT_R16G16B16A16_UNORM:
 	case PIPE_FORMAT_R16G16B16A16_SNORM:
-		//		return V_028C70_COLOR_16_16_16_16;
 	case PIPE_FORMAT_R16G16B16A16_FLOAT:
-		//		return V_028C70_COLOR_16_16_16_16_FLOAT;
 
 		/* 128-bit buffers. */
 	case PIPE_FORMAT_R32G32B32A32_FLOAT:
-		//		return V_028C70_COLOR_32_32_32_32_FLOAT;
-		return 0;
+	case PIPE_FORMAT_R32G32B32A32_SNORM:
+	case PIPE_FORMAT_R32G32B32A32_UNORM:
+		return V_028C70_SWAP_STD;
 	default:
 		R600_ERR("unsupported colorswap format %d\n", format);
 		return ~0;
@@ -471,6 +470,9 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
 		return V_028C70_COLOR_32_32;
 
 		/* 128-bit buffers. */
+	case PIPE_FORMAT_R32G32B32A32_SNORM:
+	case PIPE_FORMAT_R32G32B32A32_UNORM:
+		return V_028C70_COLOR_32_32_32_32;
 	case PIPE_FORMAT_R32G32B32_FLOAT:
 	  	return V_028C70_COLOR_32_32_32_FLOAT;
 	case PIPE_FORMAT_R32G32B32A32_FLOAT:
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 83ab0df..4821259 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -648,6 +648,7 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
 	unsigned tile_type;
 	const struct util_format_description *desc;
 	struct r600_bo *bo[3];
+	int i;
 
 	surf = (struct r600_surface *)state->cbufs[cb];
 	rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture;
@@ -679,8 +680,19 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
 		S_028C70_ARRAY_MODE(rtex->array_mode[level]) |
 		S_028C70_BLEND_CLAMP(1) |
 		S_028C70_NUMBER_TYPE(ntype);
-	if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
-		color_info |= S_028C70_SOURCE_FORMAT(1);
+
+	for (i = 0; i < 4; i++) {
+		if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
+			break;
+		}
+	}
+
+	/* we can only set the export size if any thing is snorm/unorm component is > 11 bits,
+	   if we aren't a float, sint or uint */
+	if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
+	    desc->channel[i].size < 12 && desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT &&
+	    ntype != 4 && ntype != 5)
+		color_info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC);
 
 	if (rtex->tiled) {
 		tile_type = rtex->tile_type;
diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h
index dec32b5..f0a1ee0 100644
--- a/src/gallium/drivers/r600/evergreend.h
+++ b/src/gallium/drivers/r600/evergreend.h
@@ -327,6 +327,9 @@
 #define   S_028C70_SOURCE_FORMAT(x)                    (((x) & 0x3) << 24)
 #define   G_028C70_SOURCE_FORMAT(x)                    (((x) >> 24) & 0x3)
 #define   C_028C70_SOURCE_FORMAT                       0xFCFFFFFF
+#define     V_028C70_EXPORT_4C_32BPC                   0x0
+#define     V_028C70_EXPORT_4C_16BPC                   0x1
+#define     V_028C70_EXPORT_2C_32BPC                   0x2 /* Do not use */
 #define   S_028C70_RAT(x)                              (((x) & 0x1) << 26)
 #define   G_028C70_RAT(x)                              (((x) >> 26) & 0x1)
 #define   C_028C70_RAT                                 0xFBFFFFFF
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 74dad45..0834bf4 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -692,6 +692,7 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
 	unsigned offset;
 	const struct util_format_description *desc;
 	struct r600_bo *bo[3];
+	int i;
 
 	surf = (struct r600_surface *)state->cbufs[cb];
 	rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture;
@@ -716,6 +717,12 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
 	if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
 		ntype = V_0280A0_NUMBER_SRGB;
 
+	for (i = 0; i < 4; i++) {
+		if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
+			break;
+		}
+	}
+
 	format = r600_translate_colorformat(surf->base.format);
 	swap = r600_translate_colorswap(surf->base.format);
 	color_info = S_0280A0_FORMAT(format) |
@@ -723,8 +730,12 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
 		S_0280A0_ARRAY_MODE(rtex->array_mode[level]) |
 		S_0280A0_BLEND_CLAMP(1) |
 		S_0280A0_NUMBER_TYPE(ntype);
-	if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
-		color_info |= S_0280A0_SOURCE_FORMAT(1);
+
+	/* on R600 this can't be set if BLEND_CLAMP isn't set,
+	   if BLEND_FLOAT32 is set of > 11 bits in a UNORM or SNORM */
+	if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
+	    desc->channel[i].size < 12)
+		color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM);
 
 	r600_pipe_state_add_reg(rstate,
 				R_028040_CB_COLOR0_BASE + cb * 4,
diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h
index f68bc84..8180515 100644
--- a/src/gallium/drivers/r600/r600_state_inlines.h
+++ b/src/gallium/drivers/r600/r600_state_inlines.h
@@ -355,14 +355,13 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format)
 		/* 64-bit buffers. */
 	case PIPE_FORMAT_R16G16B16A16_UNORM:
 	case PIPE_FORMAT_R16G16B16A16_SNORM:
-		//		return FMT_16_16_16_16;
 	case PIPE_FORMAT_R16G16B16A16_FLOAT:
-		//		return FMT_16_16_16_16_FLOAT;
 
 		/* 128-bit buffers. */
 	case PIPE_FORMAT_R32G32B32A32_FLOAT:
-		//		return FMT_32_32_32_32_FLOAT;
-		return 0;
+	case PIPE_FORMAT_R32G32B32A32_SNORM:
+	case PIPE_FORMAT_R32G32B32A32_UNORM:
+		return V_0280A0_SWAP_STD;
 	default:
 		R600_ERR("unsupported colorswap format %d\n", format);
 		return ~0;
@@ -469,6 +468,9 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
 	  	return V_0280A0_COLOR_32_32_32_FLOAT;
 	case PIPE_FORMAT_R32G32B32A32_FLOAT:
 		return V_0280A0_COLOR_32_32_32_32_FLOAT;
+	case PIPE_FORMAT_R32G32B32A32_SNORM:
+	case PIPE_FORMAT_R32G32B32A32_UNORM:
+		return V_0280A0_COLOR_32_32_32_32;
 
 		/* YUV buffers. */
 	case PIPE_FORMAT_UYVY:
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index b7bfdd8..df8072f 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -990,6 +990,19 @@ uint32_t r600_translate_texformat(enum pipe_format format,
 				result = FMT_16_16_16_16;
 				goto out_word4;
 			}
+			goto out_unknown;
+		case 32:
+			switch (desc->nr_channels) {
+			case 1:
+				result = FMT_32;
+				goto out_word4;
+			case 2:
+				result = FMT_32_32;
+				goto out_word4;
+			case 4:
+				result = FMT_32_32_32_32;
+				goto out_word4;
+			}
 		}
 		goto out_unknown;
 
diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h
index 1814f50..e8558c4 100644
--- a/src/gallium/drivers/r600/r600d.h
+++ b/src/gallium/drivers/r600/r600d.h
@@ -248,6 +248,8 @@
 #define   S_0280A0_SOURCE_FORMAT(x)                    (((x) & 0x1) << 27)
 #define   G_0280A0_SOURCE_FORMAT(x)                    (((x) >> 27) & 0x1)
 #define   C_0280A0_SOURCE_FORMAT                       0xF7FFFFFF
+#define     V_0280A0_EXPORT_FULL                       0
+#define     V_0280A0_EXPORT_NORM                       1
 #define R_028060_CB_COLOR0_SIZE                      0x028060
 #define   S_028060_PITCH_TILE_MAX(x)                   (((x) & 0x3FF) << 0)
 #define   G_028060_PITCH_TILE_MAX(x)                   (((x) >> 0) & 0x3FF)




More information about the mesa-commit mailing list