i965/draw: Use the real size for vertex buffers
authorJason Ekstrand <jason.ekstrand@intel.com>
Tue, 17 May 2016 22:34:07 +0000 (15:34 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 24 May 2016 02:12:34 +0000 (19:12 -0700)
Previously, we were using the size of the BO which may be substantially
larger than the actual vertex buffer size.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_draw_upload.c
src/mesa/drivers/dri/i965/gen8_draw_upload.c

index 76ed1de12a8e55fb0c1807e2ef5330aa923bca87..7a3afc9e126f6c7723e9d3a7706a5931b161a84b 100644 (file)
@@ -569,6 +569,7 @@ struct brw_vertex_buffer {
    /** Buffer object containing the uploaded vertex data */
    drm_intel_bo *bo;
    uint32_t offset;
+   uint32_t size;
    /** Byte stride between elements in the uploaded array */
    GLuint stride;
    GLuint step_rate;
index d9e46ec92bf4ebe83ee89afddce495f3dee8730d..fd6ea8c3f50f5b79a088374a3c82341cac153fbc 100644 (file)
@@ -411,6 +411,7 @@ copy_array_to_vbo_array(struct brw_context *brw,
                        &buffer->bo, &buffer->offset);
 
       buffer->stride = 0;
+      buffer->size = element->glarray->_ElementSize;
       return;
    }
 
@@ -430,6 +431,7 @@ copy_array_to_vbo_array(struct brw_context *brw,
       }
    }
    buffer->stride = dst_stride;
+   buffer->size = size;
 }
 
 void
@@ -606,6 +608,8 @@ brw_prepare_vertices(struct brw_context *brw)
 
       buffer->bo = intel_bufferobj_buffer(brw, enabled_buffer[i], start, range);
       drm_intel_bo_reference(buffer->bo);
+
+      buffer->size = start + range;
    }
 
    /* If we need to upload all the arrays, then we can trim those arrays to
@@ -629,6 +633,7 @@ brw_prepare_vertices(struct brw_context *brw)
         copy_array_to_vbo_array(brw, upload[0], min_index, max_index,
                                 buffer, interleaved);
         buffer->offset -= delta * interleaved;
+         buffer->size += delta * interleaved;
 
         for (i = 0; i < nr_uploads; i++) {
            /* Then, just point upload[i] at upload[0]'s buffer. */
@@ -658,6 +663,7 @@ brw_prepare_vertices(struct brw_context *brw)
                                  buffer, upload[i]->glarray->_ElementSize);
       }
       buffer->offset -= delta * buffer->stride;
+      buffer->size += delta * buffer->stride;
       buffer->step_rate = upload[i]->glarray->InstanceDivisor;
       upload[i]->buffer = j++;
       upload[i]->offset = 0;
@@ -799,7 +805,15 @@ brw_emit_vertices(struct brw_context *brw)
       OUT_BATCH((_3DSTATE_VERTEX_BUFFERS << 16) | (4 * nr_buffers - 1));
       for (i = 0; i < brw->vb.nr_buffers; i++) {
         struct brw_vertex_buffer *buffer = &brw->vb.buffers[i];
-         EMIT_VERTEX_BUFFER_STATE(brw, i, buffer->bo, buffer->bo->size - 1,
+         /* Prior to Haswell and Bay Trail we have to use 4-component formats
+          * to fake 3-component ones.  In particular, we do this for
+          * half-float and 8 and 16-bit integer formats.  This means that the
+          * vertex element may poke over the end of the buffer by 2 bytes.
+          */
+         unsigned padding =
+            (brw->gen <= 7 && !brw->is_baytrail && !brw->is_haswell) * 2;
+         EMIT_VERTEX_BUFFER_STATE(brw, i, buffer->bo,
+                                  buffer->offset + buffer->size + padding - 1,
                                   buffer->offset, buffer->stride,
                                   buffer->step_rate);
 
index dce11dd0ff377e4ec093db00923ead5a636960f8..4bb3a59b8d2df401e81ebe48fa80f1744961f1f1 100644 (file)
@@ -151,7 +151,7 @@ gen8_emit_vertices(struct brw_context *brw)
 
          OUT_BATCH(dw0);
          OUT_RELOC64(buffer->bo, I915_GEM_DOMAIN_VERTEX, 0, buffer->offset);
-         OUT_BATCH(buffer->bo->size);
+         OUT_BATCH(buffer->size);
       }
 
       if (uses_draw_params) {