diff options
| author | Dave Airlie <airlied@redhat.com> | 2010-08-06 14:53:38 +1000 | 
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2010-08-06 14:53:38 +1000 | 
| commit | 2b9036476511edd549d1c2cea6044eef4652a19c (patch) | |
| tree | 2ecfc1be35e18303d074afdf423403323d80df40 | |
| parent | 121a625c1651ddc181e374ebdf16bc5c46f6eaa9 (diff) | |
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@redhat.com>
| -rw-r--r-- | src/gallium/drivers/r600/r600_draw.c | 6 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_helper.c | 99 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_screen.c | 76 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_state.c | 15 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_state_inlines.h | 153 | ||||
| -rw-r--r-- | 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 7130bf2fa8..3a54cee2d9 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 c672fe7386..5e0e0aab57 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 68615ca162..4b87327a7c 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 926a19cc6f..b8d50452e6 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 321e75d7a1..b45089dcc1 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 8205bdeadc..2d0ede20fa 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 | 
