Mesa (master): ilo: add ilo_state_vertex_buffer

Chia-I Wu olv at kemper.freedesktop.org
Sat Jun 20 03:20:56 UTC 2015


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

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Fri Jun 19 15:06:50 2015 +0800

ilo: add ilo_state_vertex_buffer

Being a parameter-like state, we may want to get rid of
ilo_state_vertex_buffer_info or ilo_state_vertex_buffer eventually.  But we
want them now as they are how we do cross-validation right now.

---

 src/gallium/drivers/ilo/core/ilo_builder_3d_top.h |   56 ++++------
 src/gallium/drivers/ilo/core/ilo_state_vf.c       |  113 ++++++++++++++++++---
 src/gallium/drivers/ilo/core/ilo_state_vf.h       |   29 +++++-
 src/gallium/drivers/ilo/ilo_render_gen6.c         |    4 +-
 src/gallium/drivers/ilo/ilo_render_gen8.c         |    4 +-
 src/gallium/drivers/ilo/ilo_state.c               |   36 ++++++-
 src/gallium/drivers/ilo/ilo_state.h               |    1 +
 7 files changed, 189 insertions(+), 54 deletions(-)

diff --git a/src/gallium/drivers/ilo/core/ilo_builder_3d_top.h b/src/gallium/drivers/ilo/core/ilo_builder_3d_top.h
index 7827465..bb20c7f 100644
--- a/src/gallium/drivers/ilo/core/ilo_builder_3d_top.h
+++ b/src/gallium/drivers/ilo/core/ilo_builder_3d_top.h
@@ -305,13 +305,12 @@ gen8_3DSTATE_VF_SGVS(struct ilo_builder *builder,
 static inline void
 gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
                             const struct ilo_state_vf *vf,
-                            const struct ilo_vb_state *vb,
-                            const unsigned *vb_mapping,
+                            const struct ilo_state_vertex_buffer *vb,
                             unsigned vb_count)
 {
    uint8_t cmd_len;
    uint32_t *dw;
-   unsigned pos, hw_idx;
+   unsigned pos, i;
 
    ILO_DEV_ASSERT(builder->dev, 6, 8);
 
@@ -332,53 +331,40 @@ gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
    dw++;
    pos++;
 
-   for (hw_idx = 0; hw_idx < vb_count; hw_idx++) {
-      const unsigned pipe_idx = vb_mapping[hw_idx];
-      const struct pipe_vertex_buffer *cso = &vb->states[pipe_idx];
-      const int8_t elem = vf->vb_to_first_elem[hw_idx];
+   for (i = 0; i < vb_count; i++) {
+      const struct ilo_state_vertex_buffer *b = &vb[i];
 
-      dw[0] = hw_idx << GEN6_VB_DW0_INDEX__SHIFT;
+      /* see vertex_buffer_set_gen8_vertex_buffer_state() */
+      dw[0] = b->vb[0] |
+              i << GEN6_VB_DW0_INDEX__SHIFT;
 
       if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
          dw[0] |= builder->mocs << GEN8_VB_DW0_MOCS__SHIFT;
       else
          dw[0] |= builder->mocs << GEN6_VB_DW0_MOCS__SHIFT;
 
-      if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
-         dw[0] |= GEN7_VB_DW0_ADDR_MODIFIED;
-
       dw[1] = 0;
       dw[2] = 0;
       dw[3] = 0;
 
-      /* see vf_set_gen6_vertex_buffer_state() */
-      if (ilo_dev_gen(builder->dev) < ILO_GEN(8) && elem >= 0) {
-         dw[0] |= vf->user_instancing[elem][0];
-         dw[3] |= vf->user_instancing[elem][1];
-      }
-
-      /* use null vb if there is no VE/buffer or the stride is out of range */
-      if (elem < 0 || !cso->buffer || cso->stride > 2048) {
-         dw[0] |= GEN6_VB_DW0_IS_NULL;
-         continue;
-      }
-
-      dw[0] |= cso->stride << GEN6_VB_DW0_PITCH__SHIFT;
-
       if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
-         const struct ilo_buffer *buf = ilo_buffer(cso->buffer);
-         const uint32_t start_offset = cso->buffer_offset;
+         if (b->need_bo)
+            ilo_builder_batch_reloc64(builder, pos + 1, b->bo, b->vb[1], 0);
 
-         ilo_builder_batch_reloc64(builder, pos + 1,
-               buf->bo, start_offset, 0);
-         dw[3] = buf->bo_size;
+         dw[3] |= b->vb[2];
       } else {
-         const struct ilo_buffer *buf = ilo_buffer(cso->buffer);
-         const uint32_t start_offset = cso->buffer_offset;
-         const uint32_t end_offset = buf->bo_size - 1;
+         const int8_t elem = vf->vb_to_first_elem[i];
+
+         /* see vf_set_gen6_vertex_buffer_state() */
+         if (elem >= 0) {
+            dw[0] |= vf->user_instancing[elem][0];
+            dw[3] |= vf->user_instancing[elem][1];
+         }
 
-         ilo_builder_batch_reloc(builder, pos + 1, buf->bo, start_offset, 0);
-         ilo_builder_batch_reloc(builder, pos + 2, buf->bo, end_offset, 0);
+         if (b->need_bo) {
+            ilo_builder_batch_reloc(builder, pos + 1, b->bo, b->vb[1], 0);
+            ilo_builder_batch_reloc(builder, pos + 2, b->bo, b->vb[2], 0);
+         }
       }
 
       dw += 4;
diff --git a/src/gallium/drivers/ilo/core/ilo_state_vf.c b/src/gallium/drivers/ilo/core/ilo_state_vf.c
index 4126560..92e0380 100644
--- a/src/gallium/drivers/ilo/core/ilo_state_vf.c
+++ b/src/gallium/drivers/ilo/core/ilo_state_vf.c
@@ -26,6 +26,7 @@
  */
 
 #include "ilo_debug.h"
+#include "ilo_buffer.h"
 #include "ilo_state_vf.h"
 
 static bool
@@ -66,18 +67,6 @@ vf_validate_gen6_elements(const struct ilo_dev *dev,
 
       assert(elem->buffer < ILO_STATE_VF_MAX_BUFFER_COUNT);
       assert(elem->vertex_offset < max_vertex_offset);
-
-      /*
-       * From the Sandy Bridge PRM, volume 2 part 1, page 86:
-       *
-       *     "64-bit floating point values must be 64-bit aligned in memory,
-       *      or UNPREDICTABLE data will be fetched. When accessing an element
-       *      containing 64-bit floating point values, the Buffer Starting
-       *      Address and Source Element Offset values must add to a 64-bit
-       *      aligned address, and BufferPitch must be a multiple of 64-bits."
-       */
-      if (elem->is_double)
-         assert(elem->vertex_offset % 8 == 0);
    }
 
    return true;
@@ -483,6 +472,89 @@ vf_params_set_gen75_3DSTATE_VF(struct ilo_state_vf *vf,
    return true;
 }
 
+static bool
+vertex_buffer_validate_gen6(const struct ilo_dev *dev,
+                            const struct ilo_state_vertex_buffer_info *info)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (info->buf)
+      assert(info->offset < info->buf->bo_size && info->size);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 86:
+    *
+    *     "(Buffer Pitch)
+    *      Range  [DevCTG+]: [0,2048] Bytes"
+    */
+   assert(info->stride <= 2048);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 86:
+    *
+    *     "64-bit floating point values must be 64-bit aligned in memory, or
+    *      UNPREDICTABLE data will be fetched. When accessing an element
+    *      containing 64-bit floating point values, the Buffer Starting
+    *      Address and Source Element Offset values must add to a 64-bit
+    *      aligned address, and BufferPitch must be a multiple of 64-bits."
+    */
+   if (info->cv_has_double) {
+      assert(info->stride % 8 == 0);
+      assert((info->offset + info->cv_double_vertex_offset_mod_8) % 8 == 0);
+   }
+
+   return true;
+}
+
+static uint32_t
+vertex_buffer_get_gen6_size(const struct ilo_dev *dev,
+                            const struct ilo_state_vertex_buffer_info *info)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!info->buf)
+      return 0;
+
+   return (info->offset + info->size <= info->buf->bo_size) ? info->size :
+      info->buf->bo_size - info->offset;
+}
+
+static bool
+vertex_buffer_set_gen8_vertex_buffer_state(struct ilo_state_vertex_buffer *vb,
+                                           const struct ilo_dev *dev,
+                                           const struct ilo_state_vertex_buffer_info *info)
+{
+   const uint32_t size = vertex_buffer_get_gen6_size(dev, info);
+   uint32_t dw0;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!vertex_buffer_validate_gen6(dev, info))
+      return false;
+
+   dw0 = info->stride << GEN6_VB_DW0_PITCH__SHIFT;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7))
+      dw0 |= GEN7_VB_DW0_ADDR_MODIFIED;
+   if (!info->buf)
+      dw0 |= GEN6_VB_DW0_IS_NULL;
+
+   STATIC_ASSERT(ARRAY_SIZE(vb->vb) >= 3);
+   vb->vb[0] = dw0;
+   vb->vb[1] = info->offset;
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+      vb->vb[2] = size;
+   } else {
+      /* address of the last valid byte */
+      vb->vb[2] = (size) ? info->offset + size - 1 : 0;
+   }
+
+   vb->need_bo = (info->buf != NULL);
+
+   return true;
+}
+
 bool
 ilo_state_vf_init(struct ilo_state_vf *vf,
                   const struct ilo_dev *dev,
@@ -663,3 +735,20 @@ ilo_state_vf_get_delta(const struct ilo_state_vf *vf,
          delta->dirty |= ILO_STATE_VF_3DSTATE_INDEX_BUFFER;
    }
 }
+
+/**
+ * No need to initialize first.
+ */
+bool
+ilo_state_vertex_buffer_set_info(struct ilo_state_vertex_buffer *vb,
+                                 const struct ilo_dev *dev,
+                                 const struct ilo_state_vertex_buffer_info *info)
+{
+   bool ret = true;
+
+   ret &= vertex_buffer_set_gen8_vertex_buffer_state(vb, dev, info);
+
+   assert(ret);
+
+   return ret;
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_vf.h b/src/gallium/drivers/ilo/core/ilo_state_vf.h
index c51da10..488f92f 100644
--- a/src/gallium/drivers/ilo/core/ilo_state_vf.h
+++ b/src/gallium/drivers/ilo/core/ilo_state_vf.h
@@ -65,7 +65,6 @@ struct ilo_state_vf_element_info {
    uint8_t format_size;
    uint8_t component_count;
    bool is_integer;
-   bool is_double;
 
    /* must be the same for those share the same buffer before Gen8 */
    bool instancing_enable;
@@ -127,6 +126,29 @@ struct ilo_state_vf_delta {
    uint32_t dirty;
 };
 
+struct ilo_buffer;
+
+struct ilo_state_vertex_buffer_info {
+   const struct ilo_buffer *buf;
+   uint32_t offset;
+   uint32_t size;
+
+   uint16_t stride;
+
+   /* doubles must be at 64-bit aligned addresses */
+   bool cv_has_double;
+   uint8_t cv_double_vertex_offset_mod_8;
+};
+
+struct ilo_state_vertex_buffer {
+   uint32_t vb[3];
+
+   bool need_bo;
+
+   /* managed by users */
+   struct intel_bo *bo;
+};
+
 static inline size_t
 ilo_state_vf_data_size(const struct ilo_dev *dev, uint8_t element_count)
 {
@@ -172,4 +194,9 @@ ilo_state_vf_get_delta(const struct ilo_state_vf *vf,
                        const struct ilo_state_vf *old,
                        struct ilo_state_vf_delta *delta);
 
+bool
+ilo_state_vertex_buffer_set_info(struct ilo_state_vertex_buffer *vb,
+                                 const struct ilo_dev *dev,
+                                 const struct ilo_state_vertex_buffer_info *info);
+
 #endif /* ILO_STATE_VF_H */
diff --git a/src/gallium/drivers/ilo/ilo_render_gen6.c b/src/gallium/drivers/ilo/ilo_render_gen6.c
index f997274..8415b13 100644
--- a/src/gallium/drivers/ilo/ilo_render_gen6.c
+++ b/src/gallium/drivers/ilo/ilo_render_gen6.c
@@ -430,8 +430,8 @@ gen6_draw_vf(struct ilo_render *r,
    /* 3DSTATE_VERTEX_BUFFERS */
    if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS) ||
        DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed) {
-      gen6_3DSTATE_VERTEX_BUFFERS(r->builder, &vec->ve->vf, &vec->vb,
-            vec->ve->vb_mapping, vec->ve->vb_count);
+      gen6_3DSTATE_VERTEX_BUFFERS(r->builder, &vec->ve->vf,
+            vec->vb.vb, vec->ve->vb_count);
    }
 
    /* 3DSTATE_VERTEX_ELEMENTS */
diff --git a/src/gallium/drivers/ilo/ilo_render_gen8.c b/src/gallium/drivers/ilo/ilo_render_gen8.c
index 3b8589c..4c1c08b 100644
--- a/src/gallium/drivers/ilo/ilo_render_gen8.c
+++ b/src/gallium/drivers/ilo/ilo_render_gen8.c
@@ -211,8 +211,8 @@ gen8_draw_vf(struct ilo_render *r,
    /* 3DSTATE_VERTEX_BUFFERS */
    if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS) ||
        DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed) {
-      gen6_3DSTATE_VERTEX_BUFFERS(r->builder, &vec->ve->vf, &vec->vb,
-            vec->ve->vb_mapping, vec->ve->vb_count);
+      gen6_3DSTATE_VERTEX_BUFFERS(r->builder, &vec->ve->vf,
+            vec->vb.vb, vec->ve->vb_count);
    }
 
    /* 3DSTATE_VERTEX_ELEMENTS */
diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c
index d6144e4..e24f8fa 100644
--- a/src/gallium/drivers/ilo/ilo_state.c
+++ b/src/gallium/drivers/ilo/ilo_state.c
@@ -478,6 +478,39 @@ finalize_vertex_elements(struct ilo_context *ilo)
 }
 
 static void
+finalize_vertex_buffers(struct ilo_context *ilo)
+{
+   const struct ilo_dev *dev = ilo->dev;
+   struct ilo_state_vector *vec = &ilo->state_vector;
+   struct ilo_state_vertex_buffer_info info;
+   unsigned i;
+
+   if (!(vec->dirty & (ILO_DIRTY_VE | ILO_DIRTY_VB)))
+      return;
+
+   memset(&info, 0, sizeof(info));
+
+   for (i = 0; i < vec->ve->vb_count; i++) {
+      const unsigned pipe_idx = vec->ve->vb_mapping[i];
+      const struct pipe_vertex_buffer *cso = &vec->vb.states[pipe_idx];
+
+      if (cso->buffer) {
+         info.buf = ilo_buffer(cso->buffer);
+         info.offset = cso->buffer_offset;
+         info.size = info.buf->bo_size;
+
+         info.stride = cso->stride;
+
+         vec->vb.vb[i].bo = info.buf->bo;
+      } else {
+         memset(&info, 0, sizeof(info));
+      }
+
+      ilo_state_vertex_buffer_set_info(&vec->vb.vb[i], dev, &info);
+   }
+}
+
+static void
 finalize_urb(struct ilo_context *ilo)
 {
    const uint16_t attr_size = sizeof(uint32_t) * 4;
@@ -728,6 +761,7 @@ ilo_finalize_3d_states(struct ilo_context *ilo,
    finalize_constant_buffers(ilo);
    finalize_index_buffer(ilo);
    finalize_vertex_elements(ilo);
+   finalize_vertex_buffers(ilo);
 
    finalize_urb(ilo);
    finalize_rasterizer(ilo);
@@ -1366,8 +1400,6 @@ ilo_create_vertex_elements_state(struct pipe_context *pipe,
       attr->format_size = util_format_get_blocksize(elem->src_format);
       attr->component_count = util_format_get_nr_components(elem->src_format);
       attr->is_integer = util_format_is_pure_integer(elem->src_format);
-      attr->is_double = (util_format_is_float(elem->src_format) &&
-         attr->format_size == attr->component_count * 8);
 
       attr->instancing_enable = (elem->instance_divisor != 0);
       attr->instancing_step_rate = elem->instance_divisor;
diff --git a/src/gallium/drivers/ilo/ilo_state.h b/src/gallium/drivers/ilo/ilo_state.h
index 66c671a..2b3147f 100644
--- a/src/gallium/drivers/ilo/ilo_state.h
+++ b/src/gallium/drivers/ilo/ilo_state.h
@@ -157,6 +157,7 @@ struct ilo_ve_state {
 
 struct ilo_vb_state {
    struct pipe_vertex_buffer states[PIPE_MAX_ATTRIBS];
+   struct ilo_state_vertex_buffer vb[PIPE_MAX_ATTRIBS];
    uint32_t enabled_mask;
 };
 




More information about the mesa-commit mailing list