[Nouveau] [PATCH 1/2] nv30/draw: rework some of the output vertex buffer logic

Ilia Mirkin imirkin at alum.mit.edu
Mon May 25 12:29:11 PDT 2015


This makes the vertex buffer go to GART, not VRAM, and redoes the
mapping to not use the UNSYNCHRONIZED access (which is meaningless on a
VRAM buffer anyways). While we're at it, add some flushes for VBO data.

Moving the vertex buffer from VRAM to GART makes glxgears work fully
with NV30_SWTNL=1. The other changes just seem like a good idea. I'm not
sure *why* moving the buffer from VRAM makes it work... perhaps
something doesn't get flushed in time? However this is a single use by
the GPU buffer, so STREAM seems like the correct usage semantic for it.

Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
Cc: "10.5 10.6" <mesa-stable at lists.freedesktop.org>
---
 src/gallium/drivers/nouveau/nv30/nv30_draw.c | 30 +++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/nouveau/nv30/nv30_draw.c b/src/gallium/drivers/nouveau/nv30/nv30_draw.c
index 6a0d06f..a681135 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_draw.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_draw.c
@@ -71,12 +71,12 @@ nv30_render_allocate_vertices(struct vbuf_render *render,
    struct nv30_render *r = nv30_render(render);
    struct nv30_context *nv30 = r->nv30;
 
-   r->length = vertex_size * nr_vertices;
+   r->length = (uint32_t)vertex_size * (uint32_t)nr_vertices;
 
    if (r->offset + r->length >= render->max_vertex_buffer_bytes) {
       pipe_resource_reference(&r->buffer, NULL);
       r->buffer = pipe_buffer_create(&nv30->screen->base.base,
-                                     PIPE_BIND_VERTEX_BUFFER, 0,
+                                     PIPE_BIND_VERTEX_BUFFER, PIPE_USAGE_STREAM,
                                      render->max_vertex_buffer_bytes);
       if (!r->buffer)
          return FALSE;
@@ -91,10 +91,14 @@ static void *
 nv30_render_map_vertices(struct vbuf_render *render)
 {
    struct nv30_render *r = nv30_render(render);
-   char *map = pipe_buffer_map(&r->nv30->base.pipe, r->buffer,
-                               PIPE_TRANSFER_WRITE |
-                               PIPE_TRANSFER_UNSYNCHRONIZED, &r->transfer);
-   return map + r->offset;
+   char *map = pipe_buffer_map_range(
+         &r->nv30->base.pipe, r->buffer,
+         r->offset, r->length,
+         PIPE_TRANSFER_WRITE |
+         PIPE_TRANSFER_DISCARD_RANGE,
+         &r->transfer);
+   assert(map);
+   return map;
 }
 
 static void
@@ -127,12 +131,18 @@ nv30_render_draw_elements(struct vbuf_render *render,
    for (i = 0; i < r->vertex_info.num_attribs; i++) {
       PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP,
                        nv04_resource(r->buffer), r->offset + r->vtxptr[i],
-                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, 0);
+                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, NV30_3D_VTXBUF_DMA1);
    }
 
    if (!nv30_state_validate(nv30, ~0, FALSE))
       return;
 
+   if (nv30->base.vbo_dirty) {
+      BEGIN_NV04(push, NV30_3D(VTX_CACHE_INVALIDATE_1710), 1);
+      PUSH_DATA (push, 0);
+      nv30->base.vbo_dirty = FALSE;
+   }
+
    BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
    PUSH_DATA (push, r->prim);
 
@@ -178,6 +188,12 @@ nv30_render_draw_arrays(struct vbuf_render *render, unsigned start, uint nr)
    if (!nv30_state_validate(nv30, ~0, FALSE))
       return;
 
+   if (nv30->base.vbo_dirty) {
+      BEGIN_NV04(push, NV30_3D(VTX_CACHE_INVALIDATE_1710), 1);
+      PUSH_DATA (push, 0);
+      nv30->base.vbo_dirty = FALSE;
+   }
+
    BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
    PUSH_DATA (push, r->prim);
 
-- 
2.3.6



More information about the Nouveau mailing list