Mesa (master): nv50,nvc0: fix/enable texture buffer objects

Christoph Bumiller chrisbmr at kemper.freedesktop.org
Wed Jan 30 12:11:05 UTC 2013


Module: Mesa
Branch: master
Commit: 4bdf5454a5b0846d56c610b4e7e595fbedcf4c22
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4bdf5454a5b0846d56c610b4e7e595fbedcf4c22

Author: Christoph Bumiller <e0425955 at student.tuwien.ac.at>
Date:   Sat Jan 12 14:59:43 2013 +0100

nv50,nvc0: fix/enable texture buffer objects

---

 docs/GL3.txt                                |    2 +-
 src/gallium/drivers/nv50/nv50_formats.c     |   10 +++--
 src/gallium/drivers/nv50/nv50_screen.c      |    6 ++-
 src/gallium/drivers/nv50/nv50_tex.c         |   50 +++++++++++++--------------
 src/gallium/drivers/nv50/nv50_texture.xml.h |    1 +
 src/gallium/drivers/nvc0/nvc0_screen.c      |    8 ++++-
 6 files changed, 43 insertions(+), 34 deletions(-)

diff --git a/docs/GL3.txt b/docs/GL3.txt
index 21c37c0..88621e3 100644
--- a/docs/GL3.txt
+++ b/docs/GL3.txt
@@ -149,7 +149,7 @@ ARB_robust_buffer_access_behavior                    not started
 ARB_shader_image_size                                not started
 ARB_shader_storage_buffer_object                     not started
 ARB_stencil_texturing                                not started
-ARB_texture_buffer_range                             not started
+ARB_texture_buffer_range                             DONE (nv50, nvc0)
 ARB_texture_query_levels                             not started
 ARB_texture_storage_multisample                      not started
 ARB_texture_view                                     not started
diff --git a/src/gallium/drivers/nv50/nv50_formats.c b/src/gallium/drivers/nv50/nv50_formats.c
index 41757d2..658f1c4 100644
--- a/src/gallium/drivers/nv50/nv50_formats.c
+++ b/src/gallium/drivers/nv50/nv50_formats.c
@@ -54,9 +54,11 @@
 #if NOUVEAU_DRIVER == 0xc0
 # define U_TC  U_TB
 # define U_TCV U_TBV
+# define U_tV  U_TV
 #else
 # define U_TC  U_TR
 # define U_TCV U_TRV
+# define U_tV  U_V
 #endif
 
 #define NV50_SURFACE_FORMAT_NONE 0
@@ -65,7 +67,7 @@
 /* for vertex buffers: */
 #define NV50_TIC_0_FMT_8_8_8    NV50_TIC_0_FMT_8_8_8_8
 #define NV50_TIC_0_FMT_16_16_16 NV50_TIC_0_FMT_16_16_16_16
-#define NV50_TIC_0_FMT_32_32_32 NV50_TIC_0_FMT_32_32_32_32
+#define NV50_TIC_0_FMT_32_32_32 NVC0_TIC_0_FMT_32_32_32
 
 #if NOUVEAU_DRIVER == 0xc0
 # define NVXX_3D_VAF_SIZE(s) NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_##s
@@ -344,11 +346,11 @@ const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] =
 
    C4A(R32G32B32A32_SSCALED, NONE, C0, C1, C2, C3, SSCALED, 32_32_32_32, V, 0),
    C4A(R32G32B32A32_USCALED, NONE, C0, C1, C2, C3, USCALED, 32_32_32_32, V, 0),
-   F3A(R32G32B32_FLOAT, NONE, C0, C1, C2, xx, FLOAT, 32_32_32, V),
+   F3A(R32G32B32_FLOAT, NONE, C0, C1, C2, xx, FLOAT, 32_32_32, tV),
    F3A(R32G32B32_UNORM, NONE, C0, C1, C2, xx, UNORM, 32_32_32, V),
    F3A(R32G32B32_SNORM, NONE, C0, C1, C2, xx, SNORM, 32_32_32, V),
-   I3A(R32G32B32_SINT, NONE, C0, C1, C2, xx, SINT, 32_32_32, V),
-   I3A(R32G32B32_UINT, NONE, C0, C1, C2, xx, UINT, 32_32_32, V),
+   I3A(R32G32B32_SINT, NONE, C0, C1, C2, xx, SINT, 32_32_32, tV),
+   I3A(R32G32B32_UINT, NONE, C0, C1, C2, xx, UINT, 32_32_32, tV),
    F3A(R32G32B32_SSCALED, NONE, C0, C1, C2, xx, SSCALED, 32_32_32, V),
    F3A(R32G32B32_USCALED, NONE, C0, C1, C2, xx, USCALED, 32_32_32, V),
    F2A(R32G32_SSCALED, NONE, C0, C1, xx, xx, SSCALED, 32_32, V),
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index b1a9c4d..be74350 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -108,6 +108,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_NPOT_TEXTURES:
    case PIPE_CAP_ANISOTROPIC_FILTER:
    case PIPE_CAP_SCALED_RESOLVE:
+   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
       return 1;
    case PIPE_CAP_SEAMLESS_CUBE_MAP:
       return nv50_screen(pscreen)->tesla->oclass >= NVA0_3D_CLASS;
@@ -125,7 +126,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_SM3:
       return 1;
    case PIPE_CAP_GLSL_FEATURE_LEVEL:
-      return 130;
+      return 140;
    case PIPE_CAP_MAX_RENDER_TARGETS:
       return 8;
    case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
@@ -176,13 +177,14 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
       return 1;
    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
       return 256;
+   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
+      return 1; /* 256 for binding as RT, but that's not possible in GL */
    case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
       return NOUVEAU_MIN_BUFFER_MAP_ALIGN;
    case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
    case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
    case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
    case PIPE_CAP_TEXTURE_MULTISAMPLE:
-   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
       return 0;
    default:
       NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index dfc97a2..40b264d 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -51,24 +51,6 @@ 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 *res,
@@ -76,7 +58,7 @@ nv50_create_sampler_view(struct pipe_context *pipe,
 {
    uint32_t flags = 0;
 
-   if (res->target == PIPE_TEXTURE_RECT)
+   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);
@@ -141,21 +123,37 @@ nv50_create_texture_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 (!(flags & NV50_TEXVIEW_SCALED_COORDS))
-      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)) |
diff --git a/src/gallium/drivers/nv50/nv50_texture.xml.h b/src/gallium/drivers/nv50/nv50_texture.xml.h
index fc76ec7..63daf9e 100644
--- a/src/gallium/drivers/nv50/nv50_texture.xml.h
+++ b/src/gallium/drivers/nv50/nv50_texture.xml.h
@@ -115,6 +115,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NV50_TIC_0_FMT__MASK					0x0000003f
 #define NV50_TIC_0_FMT__SHIFT					0
 #define NV50_TIC_0_FMT_32_32_32_32				0x00000001
+#define NVC0_TIC_0_FMT_32_32_32					0x00000002
 #define NV50_TIC_0_FMT_16_16_16_16				0x00000003
 #define NV50_TIC_0_FMT_32_32					0x00000004
 #define NV50_TIC_0_FMT_32_8_X24					0x00000005
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index 46bb797..acc28d1 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -57,6 +57,10 @@ nvc0_screen_is_format_supported(struct pipe_screen *pscreen,
       break;
    }
 
+   if ((bindings & PIPE_BIND_SAMPLER_VIEW) && (target != PIPE_BUFFER))
+      if (util_format_get_blocksizebits(format) == 3 * 32)
+         return FALSE;
+
    /* transfers & shared are always supported */
    bindings &= ~(PIPE_BIND_TRANSFER_READ |
                  PIPE_BIND_TRANSFER_WRITE |
@@ -103,6 +107,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_ANISOTROPIC_FILTER:
    case PIPE_CAP_SEAMLESS_CUBE_MAP:
    case PIPE_CAP_CUBE_MAP_ARRAY:
+   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
       return 1;
    case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
       return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
@@ -162,13 +167,14 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
       return 1;
    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
       return 256;
+   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
+      return 1; /* 256 for binding as RT, but that's not possible in GL */
    case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
       return NOUVEAU_MIN_BUFFER_MAP_ALIGN;
    case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
    case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
    case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
    case PIPE_CAP_TEXTURE_MULTISAMPLE:
-   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
       return 0;
    default:
       NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);




More information about the mesa-commit mailing list