summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/drm/nouveau/nv04_surface.c
diff options
context:
space:
mode:
authorYounes Manton <younes.m@gmail.com>2008-12-01 22:24:19 -0500
committerYounes Manton <younes.m@gmail.com>2008-12-02 16:15:12 -0500
commita6b7c0bcbebb7532b6728500a868b7c985e3f822 (patch)
treea6a2155a30a9fb708cd6f785296b2f072fdc11f3 /src/gallium/winsys/drm/nouveau/nv04_surface.c
parent1c22c0452526aaae13a2e618ec6e46327609d9c2 (diff)
nouveau: nv04-nv40 linear <-> swizzled conversion.
Diffstat (limited to 'src/gallium/winsys/drm/nouveau/nv04_surface.c')
-rw-r--r--src/gallium/winsys/drm/nouveau/nv04_surface.c151
1 files changed, 78 insertions, 73 deletions
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;
}