diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gallium/drivers/nouveau/nouveau_winsys.h | 2 | ||||
| -rw-r--r-- | src/gallium/winsys/drm/nouveau/nv04_surface.c | 151 | 
2 files changed, 80 insertions, 73 deletions
diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index a89b056244..5535ebb6a9 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -17,6 +17,8 @@  #define NOUVEAU_CAP_HW_VTXBUF (0xbeef0000)  #define NOUVEAU_CAP_HW_IDXBUF (0xbeef0001) +#define NOUVEAU_TEXTURE_USAGE_LINEAR (1 << 16) +  #define NOUVEAU_BUFFER_USAGE_TEXTURE (1 << 16)  #define NOUVEAU_BUFFER_USAGE_ZETA    (1 << 17) diff --git a/src/gallium/winsys/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/nv04_surface.c index d08955de71..4f37af7927 100644 --- a/src/gallium/winsys/drm/nouveau/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/nv04_surface.c @@ -37,7 +37,11 @@ nv04_surface_format(enum pipe_format format)  		return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;  	case PIPE_FORMAT_R5G6B5_UNORM:  		return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; +	case PIPE_FORMAT_R16_SNORM: +		return NV04_CONTEXT_SURFACES_2D_FORMAT_Y16; +	case PIPE_FORMAT_X8R8G8B8_UNORM:  	case PIPE_FORMAT_A8R8G8B8_UNORM: +		return NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;  	case PIPE_FORMAT_Z24S8_UNORM:  		return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32;  	default: @@ -61,6 +65,69 @@ nv04_rect_format(enum pipe_format format)  	}  } +static INLINE int +nv04_scaled_image_format(enum pipe_format format) +{ +	switch (format) { +	case PIPE_FORMAT_A1R5G5B5_UNORM: +		return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A1R5G5B5; +	case PIPE_FORMAT_A8R8G8B8_UNORM: +		return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8; +	case PIPE_FORMAT_X8R8G8B8_UNORM: +		return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8; +	case PIPE_FORMAT_R5G6B5_UNORM: +	case PIPE_FORMAT_R16_SNORM: +		return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5; +	default: +		return -1; +	} +} + +static void +nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, +		       unsigned sx, unsigned sy, unsigned w, unsigned h) +{ +	struct nouveau_channel *chan = nv->nvc->channel; +	struct pipe_surface *dst = nv->surf_dst; +	struct pipe_surface *src = nv->surf_src; + +	BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); +	OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, +	                 NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + +	BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_FORMAT, 2); +	OUT_RING  (chan, nv04_surface_format(dst->format) | +	                 log2i(w) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT | +	                 log2i(h) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT); +	OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, +	                 NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + +	BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); +	OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, +	                 NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); +	BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); +	OUT_RING  (chan, nv->nvc->NvSwzSurf->handle); + +	BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9); +	OUT_RING  (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); +	OUT_RING  (chan, nv04_scaled_image_format(src->format)); +	OUT_RING  (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); +	OUT_RING  (chan, 0); +	OUT_RING  (chan, h << 16 | w); +	OUT_RING  (chan, 0); +	OUT_RING  (chan, h << 16 | w); +	OUT_RING  (chan, 1 << 20); +	OUT_RING  (chan, 1 << 20); +	BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); +	OUT_RING  (chan, h << 16 | w); +	OUT_RING  (chan, src->stride | +	                 NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | +	                 NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); +	OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, +	                 NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); +	OUT_RING  (chan, 0); +} +  static void  nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy,  		       unsigned sx, unsigned sy, unsigned w, unsigned h) @@ -108,56 +175,6 @@ nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy,  }  static int -nv04_surface_copy_prep_swizzled(struct nouveau_context *nv, -				struct pipe_surface *dst, -				struct pipe_surface *src) -{ -	struct nouveau_channel *chan = nv->nvc->channel; - -	BEGIN_RING(chan, nv->nvc->NvSwzSurf, -		   NV04_SWIZZLED_SURFACE_FORMAT, 2); -	/* FIXME: read destination format from somewhere */ -	OUT_RING  (chan, -		NV04_SWIZZLED_SURFACE_FORMAT_COLOR_A8R8G8B8 -		| (log2i(dst->width)<<NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT) -		| (log2i(dst->height)<<NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT) ); -	OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, -		   NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - -	BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 13); -	OUT_RING  (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); -	/* FIXME: read source format from somewhere */ -	OUT_RING  (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8); -	OUT_RING  (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); -	OUT_RING  (chan, 0); -	OUT_RING  (chan, (src->height<<16) | src->width); -	OUT_RING  (chan, 0); -	OUT_RING  (chan, (src->height<<16) | src->width); -	OUT_RING  (chan, 1<<20); -	OUT_RING  (chan, 1<<20); -	OUT_RING  (chan, (src->height<<16) | src->width); -	OUT_RING  (chan, -		src->stride -		| NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER -		| NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); -	OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, -		   NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); -	OUT_RING  (chan, 0); - -	BEGIN_RING(chan, nv->nvc->NvM2MF, -		   NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); -	OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, -		   NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); -	OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, -		   NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - -	nv->surface_copy = nv04_surface_copy_m2mf; -	nv->surf_dst = dst; -	nv->surf_src = src; -	return 0; -} - -static int  nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst,  		       struct pipe_surface *src)  { @@ -169,9 +186,17 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst,  	/* Setup transfer to swizzle the texture to vram if needed */  	/* FIXME/TODO: check proper limits of this operation */ -	if (nouveau_buffer(dst->buffer)->bo->flags & NOUVEAU_BO_SWIZZLED) { -		/* FIXME: Disable it for the moment */ -		/*return nv04_surface_copy_prep_swizzled(nv, dst, src);*/ +	if (src->texture && dst->texture) { +		unsigned int src_linear = src->texture->tex_usage & +		                          NOUVEAU_TEXTURE_USAGE_LINEAR; +		unsigned int dst_linear = dst->texture->tex_usage & +		                          NOUVEAU_TEXTURE_USAGE_LINEAR; +		if (src_linear ^ dst_linear) { +			nv->surface_copy = nv04_surface_copy_swizzle; +			nv->surf_dst = dst; +			nv->surf_src = src; +			return 0; +		}  	}  	/* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback @@ -359,10 +384,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc)  	}  	BIND_RING (chan, nvc->NvSwzSurf, nvc->next_subchannel++); -	BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_NOTIFY, 1); -	OUT_RING  (chan, nvc->sync_notifier->handle); -	BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); -	OUT_RING  (chan, nvc->channel->vram->handle);  	if (chipset < 0x10) {  		class = NV04_SCALED_IMAGE_FROM_MEMORY; @@ -381,22 +402,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc)  	}  	BIND_RING (chan, nvc->NvSIFM, nvc->next_subchannel++); -	BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 1); -	OUT_RING  (chan, 0); -	BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); -	OUT_RING  (chan, nvc->channel->vram->handle); -	BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); -	OUT_RING  (chan, nvc->NvSwzSurf->handle); -	BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_PATTERN, 1); -	OUT_RING  (chan, 0); -	BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_ROP, 1); -	OUT_RING  (chan, 0); -	BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_BETA1, 1); -	OUT_RING  (chan, 0); -	BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_BETA4, 1); -	OUT_RING  (chan, 0); -	BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1); -	OUT_RING  (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);  	return 0;  }  | 
