Mesa (gallium-0.2): nouveau: nv04-nv40 linear <-> swizzled conversion.

Younes Manton ymanton at kemper.freedesktop.org
Tue Dec 2 21:16:21 UTC 2008


Module: Mesa
Branch: gallium-0.2
Commit: a6b7c0bcbebb7532b6728500a868b7c985e3f822
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a6b7c0bcbebb7532b6728500a868b7c985e3f822

Author: Younes Manton <younes.m at gmail.com>
Date:   Mon Dec  1 22:24:19 2008 -0500

nouveau: nv04-nv40 linear <-> swizzled conversion.

---

 src/gallium/drivers/nouveau/nouveau_winsys.h  |    2 +
 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 a89b056..5535ebb 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 d08955d..4f37af7 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;
 }




More information about the mesa-commit mailing list