nv50/ir: add support for indirect BRA,CALL
[mesa.git] / src / gallium / drivers / nv50 / nv50_tex.c
index 4a769d5b810a7de2b4d57c1f3620fbdbeb8caca5..40b264d830ffd16d53215c5dfa3ca110e76532ea 100644 (file)
@@ -51,28 +51,25 @@ 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)
+struct pipe_sampler_view *
+nv50_create_sampler_view(struct pipe_context *pipe,
+                         struct pipe_resource *res,
+                         const struct pipe_sampler_view *templ)
 {
-   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;
-   }
+   uint32_t flags = 0;
+
+   if (res->target == PIPE_TEXTURE_RECT || res->target == PIPE_BUFFER)
+      flags |= NV50_TEXVIEW_SCALED_COORDS;
+
+   return nv50_create_texture_view(pipe, res, templ, flags, res->target);
 }
 
 struct pipe_sampler_view *
-nv50_create_sampler_view(struct pipe_context *pipe,
+nv50_create_texture_view(struct pipe_context *pipe,
                          struct pipe_resource *texture,
-                         const struct pipe_sampler_view *templ)
+                         const struct pipe_sampler_view *templ,
+                         uint32_t flags,
+                         enum pipe_texture_target target)
 {
    const struct util_format_description *desc;
    uint64_t addr;
@@ -126,27 +123,43 @@ nv50_create_sampler_view(struct pipe_context *pipe,
       depth = mt->base.base.depth0;
    }
 
-   tic[1] = addr;
-   tic[2] = (addr >> 32) & 0xff;
-
-   tic[2] |= 0x10001000 | NV50_TIC_2_NO_BORDER;
+   tic[2] = 0x10001000 | NV50_TIC_2_NO_BORDER;
 
    if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
       tic[2] |= NV50_TIC_2_COLORSPACE_SRGB;
 
+   if (!(flags & NV50_TEXVIEW_SCALED_COORDS))
+      tic[2] |= NV50_TIC_2_NORMALIZED_COORDS;
+
    if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
-      nv50_init_tic_entry_linear(tic, texture);
+      if (target == PIPE_BUFFER) {
+         addr += view->pipe.u.buf.first_element * desc->block.bits / 8;
+         tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_BUFFER;
+         tic[3] = 0;
+         tic[4] = /* width */
+            view->pipe.u.buf.last_element - view->pipe.u.buf.first_element + 1;
+         tic[5] = 0;
+      } else {
+         tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_RECT;
+         tic[3] = mt->level[0].pitch;
+         tic[4] = mt->base.base.width0;
+         tic[5] = (1 << 16) | mt->base.base.height0;
+      }
+      tic[6] =
+      tic[7] = 0;
+      tic[1] = addr;
+      tic[2] |= addr >> 32;
       return &view->pipe;
    }
 
-   if (mt->base.base.target != PIPE_TEXTURE_RECT)
-      tic[2] |= NV50_TIC_2_NORMALIZED_COORDS;
+   tic[1] = addr;
+   tic[2] |= (addr >> 32) & 0xff;
 
    tic[2] |=
       ((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) |
       ((mt->level[0].tile_mode & 0xf00) << (25 - 8));
 
-   switch (mt->base.base.target) {
+   switch (target) {
    case PIPE_TEXTURE_1D:
       tic[2] |= NV50_TIC_2_TARGET_1D;
       break;
@@ -161,10 +174,7 @@ nv50_create_sampler_view(struct pipe_context *pipe,
       break;
    case PIPE_TEXTURE_CUBE:
       depth /= 6;
-      if (depth > 1)
-         tic[2] |= NV50_TIC_2_TARGET_CUBE_ARRAY;
-      else
-         tic[2] |= NV50_TIC_2_TARGET_CUBE;
+      tic[2] |= NV50_TIC_2_TARGET_CUBE;
       break;
    case PIPE_TEXTURE_1D_ARRAY:
       tic[2] |= NV50_TIC_2_TARGET_1D_ARRAY;
@@ -172,6 +182,10 @@ nv50_create_sampler_view(struct pipe_context *pipe,
    case PIPE_TEXTURE_2D_ARRAY:
       tic[2] |= NV50_TIC_2_TARGET_2D_ARRAY;
       break;
+   case PIPE_TEXTURE_CUBE_ARRAY:
+      depth /= 6;
+      tic[2] |= NV50_TIC_2_TARGET_CUBE_ARRAY;
+      break;
    case PIPE_BUFFER:
       assert(0); /* should be linear and handled above ! */
       tic[2] |= NV50_TIC_2_TARGET_BUFFER | NV50_TIC_2_LINEAR;
@@ -181,18 +195,22 @@ nv50_create_sampler_view(struct pipe_context *pipe,
       return FALSE;
    }
 
-   tic[3] = 0x00300000;
+   tic[3] = (flags & NV50_TEXVIEW_FILTER_MSAA8) ? 0x20000000 : 0x00300000;
 
    tic[4] = (1 << 31) | (mt->base.base.width0 << mt->ms_x);
 
    tic[5] = (mt->base.base.height0 << mt->ms_y) & 0xffff;
    tic[5] |= depth << 16;
-   tic[5] |= mt->base.base.last_level << 28;
+   tic[5] |= mt->base.base.last_level << NV50_TIC_5_LAST_LEVEL__SHIFT;
 
    tic[6] = (mt->ms_x > 1) ? 0x88000000 : 0x03000000; /* sampling points */
 
    tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level;
 
+   if (unlikely(!(tic[2] & NV50_TIC_2_NORMALIZED_COORDS)))
+      if (mt->base.base.last_level)
+         tic[5] &= ~NV50_TIC_5_LAST_LEVEL__MASK;
+
    return &view->pipe;
 }