nv50: add support for linear textures and render targets
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Tue, 30 Aug 2011 11:08:27 +0000 (13:08 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Tue, 30 Aug 2011 11:55:07 +0000 (13:55 +0200)
src/gallium/drivers/nouveau/nouveau_winsys.h
src/gallium/drivers/nv50/nv50_miptree.c
src/gallium/drivers/nv50/nv50_state_validate.c
src/gallium/drivers/nv50/nv50_surface.c
src/gallium/drivers/nv50/nv50_tex.c
src/gallium/drivers/nv50/nv50_winsys.h
src/gallium/drivers/nvc0/nvc0_winsys.h

index 484f870bd86078c79e4d716cc992e0b6a876f118..37416f78bc1d707eb7199ccb4494600108a63042 100644 (file)
@@ -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)
 {
index 3537681d4d70f6c04f0605756446c04061a56209..239be19d60458869957656e84a6d94e2a660751c 100644 (file)
@@ -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;
 }
 
index 369daf8ffa63e5332f6704d050b2dd2ec30b6897..05f32ea78d2447750a9f93d495ded30b12c9fcb8 100644 (file)
@@ -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;
 
index 57339f89a361b612cd6ec7133d0ceb08ad553375..b0a8497c1e74d3e803413e4312c0ebbe419a414d 100644 (file)
@@ -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);
index 73db9ca4fd1929dae0c4194c9c29752ac54cc37e..9436ac295de25f25203444c146f26f7bbe6f5e1e 100644 (file)
@@ -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);
 
index afa2a00c7a251c2a6d86a8d2d98a6803046ba734..694c78a2fbda3e0f8da773857ba7ed38beecf52a 100644 (file)
@@ -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;
 }
index 6519ce8e19f692ece4a94ffd7a40123166df1c34..0fcf9944c1415eca81588d8541083f1bf4b473f2 100644 (file)
@@ -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;
 }