summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2011-08-30 13:08:27 +0200
committerChristoph Bumiller <[email protected]>2011-08-30 13:55:07 +0200
commit0a3f0ff2645d03d5f572cc26932595b8df400505 (patch)
treee85f772a412a0b2b73f84f39023a4c52c0d22c62
parent55bab45a7c6c8e659e31b398b4ccd6e790c2738b (diff)
nv50: add support for linear textures and render targets
-rw-r--r--src/gallium/drivers/nouveau/nouveau_winsys.h2
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c3
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c27
-rw-r--r--src/gallium/drivers/nv50/nv50_surface.c12
-rw-r--r--src/gallium/drivers/nv50/nv50_tex.c29
-rw-r--r--src/gallium/drivers/nv50/nv50_winsys.h2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_winsys.h2
7 files changed, 63 insertions, 14 deletions
diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h
index 484f870bd86..37416f78bc1 100644
--- a/src/gallium/drivers/nouveau/nouveau_winsys.h
+++ b/src/gallium/drivers/nouveau/nouveau_winsys.h
@@ -17,6 +17,8 @@
#define NV04_PFIFO_MAX_PACKET_LEN 2047
#endif
+#define NOUVEAU_RESOURCE_FLAG_LINEAR (PIPE_RESOURCE_FLAG_DRV_PRIV << 0)
+
static INLINE uint32_t
nouveau_screen_transfer_flags(unsigned pipe)
{
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index 3537681d4d7..239be19d604 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -107,6 +107,9 @@ nv50_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed)
if (!compressed)
tile_flags &= ~0x30000;
+ if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
+ tile_flags &= ~0x3ff00;
+
return tile_flags;
}
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index 369daf8ffa6..05f32ea78d2 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -31,13 +31,26 @@ nv50_validate_fb(struct nv50_context *nv50)
OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
OUT_RING (chan, nv50_format_table[sf->base.format].rt);
- OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
- OUT_RING (chan, mt->layer_stride >> 2);
- BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2);
- OUT_RING (chan, sf->width);
- OUT_RING (chan, sf->height);
- BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
- OUT_RING (chan, sf->depth);
+ if (likely(nouveau_bo_tile_layout(bo))) {
+ OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
+ OUT_RING (chan, mt->layer_stride >> 2);
+ BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2);
+ OUT_RING (chan, sf->width);
+ OUT_RING (chan, sf->height);
+ BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
+ OUT_RING (chan, sf->depth);
+ } else {
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 0);
+ BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2);
+ OUT_RING (chan, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
+ OUT_RING (chan, sf->height);
+ BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
+ OUT_RING (chan, 0);
+
+ assert(!fb->zsbuf);
+ assert(!mt->ms_mode);
+ }
ms_mode = mt->ms_mode;
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index 57339f89a36..b0a8497c1e7 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -290,11 +290,19 @@ nv50_clear_render_target(struct pipe_context *pipe,
OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
OUT_RING (chan, 0);
BEGIN_RING(chan, RING_3D(RT_HORIZ(0)), 2);
- OUT_RING (chan, sf->width);
+ if (nouveau_bo_tile_layout(bo))
+ OUT_RING(chan, sf->width);
+ else
+ OUT_RING(chan, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
OUT_RING (chan, sf->height);
BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
OUT_RING (chan, 1);
+ if (!nouveau_bo_tile_layout(bo)) {
+ BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
+ OUT_RING (chan, 0);
+ }
+
/* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */
BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
@@ -324,6 +332,8 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
struct nouveau_bo *bo = mt->base.bo;
uint32_t mode = 0;
+ assert(nouveau_bo_tile_layout(bo)); /* ZETA cannot be linear */
+
if (clear_flags & PIPE_CLEAR_DEPTH) {
BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
OUT_RINGf (chan, depth);
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index 73db9ca4fd1..9436ac295de 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -51,6 +51,24 @@ nv50_tic_swizzle(uint32_t tc, unsigned swz, boolean tex_int)
}
}
+static void
+nv50_init_tic_entry_linear(uint32_t *tic, struct pipe_resource *res)
+{
+ if (res->target == PIPE_BUFFER) {
+ tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_BUFFER;
+ tic[4] = res->width0;
+ } else {
+ struct nv50_miptree *mt = nv50_miptree(res);
+
+ tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_RECT;
+ if (res->target != PIPE_TEXTURE_RECT)
+ tic[2] |= NV50_TIC_2_NORMALIZED_COORDS;
+ tic[3] = mt->level[0].pitch;
+ tic[4] = res->width0;
+ tic[5] = (1 << 16) | res->height0;
+ }
+}
+
struct pipe_sampler_view *
nv50_create_sampler_view(struct pipe_context *pipe,
struct pipe_resource *texture,
@@ -105,6 +123,11 @@ nv50_create_sampler_view(struct pipe_context *pipe,
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
tic[2] |= NV50_TIC_2_COLORSPACE_SRGB;
+ if (unlikely(!nouveau_bo_tile_layout(nv04_resource(texture)->bo))) {
+ nv50_init_tic_entry_linear(tic, texture);
+ return &view->pipe;
+ }
+
if (mt->base.base.target != PIPE_TEXTURE_RECT)
tic[2] |= NV50_TIC_2_NORMALIZED_COORDS;
@@ -147,6 +170,7 @@ nv50_create_sampler_view(struct pipe_context *pipe,
tic[2] |= NV50_TIC_2_TARGET_2D_ARRAY;
break;
case PIPE_BUFFER:
+ assert(0); /* should be linear and handled above ! */
tic[2] |= NV50_TIC_2_TARGET_BUFFER | NV50_TIC_2_LINEAR;
break;
default:
@@ -154,10 +178,7 @@ nv50_create_sampler_view(struct pipe_context *pipe,
return FALSE;
}
- if (mt->base.base.target == PIPE_BUFFER)
- tic[3] = mt->base.base.width0;
- else
- tic[3] = 0x00300000;
+ tic[3] = 0x00300000;
tic[4] = (1 << 31) | (mt->base.base.width0 << mt->ms_x);
diff --git a/src/gallium/drivers/nv50/nv50_winsys.h b/src/gallium/drivers/nv50/nv50_winsys.h
index afa2a00c7a2..694c78a2fbd 100644
--- a/src/gallium/drivers/nv50/nv50_winsys.h
+++ b/src/gallium/drivers/nv50/nv50_winsys.h
@@ -41,7 +41,7 @@
int nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min);
static inline uint32_t
-nouveau_bo_tile_layout(struct nouveau_bo *bo)
+nouveau_bo_tile_layout(const struct nouveau_bo *bo)
{
return bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK;
}
diff --git a/src/gallium/drivers/nvc0/nvc0_winsys.h b/src/gallium/drivers/nvc0/nvc0_winsys.h
index 6519ce8e19f..0fcf9944c14 100644
--- a/src/gallium/drivers/nvc0/nvc0_winsys.h
+++ b/src/gallium/drivers/nvc0/nvc0_winsys.h
@@ -39,7 +39,7 @@
int nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min);
static inline uint32_t
-nouveau_bo_tile_layout(struct nouveau_bo *bo)
+nouveau_bo_tile_layout(const struct nouveau_bo *bo)
{
return bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK;
}