Mesa (master): ilo: add ilo_state_sol_buffer

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


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

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Mon Jun 15 15:17:45 2015 +0800

ilo: add ilo_state_sol_buffer

It serves the same purpose as ilo_state_vertex_buffer does.

---

 src/gallium/drivers/ilo/core/ilo_builder_3d_top.h |  105 ++++++-----
 src/gallium/drivers/ilo/core/ilo_state_sol.c      |  210 +++++++++++++++++----
 src/gallium/drivers/ilo/core/ilo_state_sol.h      |   42 ++++-
 src/gallium/drivers/ilo/ilo_render_gen7.c         |   22 ++-
 src/gallium/drivers/ilo/ilo_state.c               |   33 +++-
 src/gallium/drivers/ilo/ilo_state.h               |    8 +
 6 files changed, 317 insertions(+), 103 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 6a45d70..398586b 100644
--- a/src/gallium/drivers/ilo/core/ilo_builder_3d_top.h
+++ b/src/gallium/drivers/ilo/core/ilo_builder_3d_top.h
@@ -756,11 +756,13 @@ gen7_3DSTATE_STREAMOUT(struct ilo_builder *builder,
 
    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_STREAMOUT) | (cmd_len - 2);
    /* see sol_set_gen7_3DSTATE_STREAMOUT() */
-   dw[1] = sol->so[0];
-   dw[2] = sol->so[1];
+   dw[1] = sol->streamout[0];
+   dw[2] = sol->streamout[1];
    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
-      dw[3] = sol->so[2];
-      dw[4] = sol->so[3];
+      dw[3] = sol->strides[1] << GEN8_SO_DW3_BUFFER1_PITCH__SHIFT |
+              sol->strides[0] << GEN8_SO_DW3_BUFFER0_PITCH__SHIFT;
+      dw[4] = sol->strides[3] << GEN8_SO_DW4_BUFFER3_PITCH__SHIFT |
+              sol->strides[2] << GEN8_SO_DW4_BUFFER2_PITCH__SHIFT;
    }
 }
 
@@ -797,8 +799,8 @@ gen7_3DSTATE_SO_DECL_LIST(struct ilo_builder *builder,
 
    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_DECL_LIST) | (cmd_len - 2);
    /* see sol_set_gen7_3DSTATE_SO_DECL_LIST() */
-   dw[1] = sol->so[4];
-   dw[2] = sol->so[5];
+   dw[1] = sol->so_decl[0];
+   dw[2] = sol->so_decl[1];
    memcpy(&dw[3], sol->decl, sizeof(sol->decl[0]) * sol->decl_count);
 
    if (sol->decl_count < cmd_decl_count) {
@@ -808,74 +810,77 @@ gen7_3DSTATE_SO_DECL_LIST(struct ilo_builder *builder,
 }
 
 static inline void
-gen7_3DSTATE_SO_BUFFER(struct ilo_builder *builder, int index, int stride,
-                       const struct pipe_stream_output_target *so_target)
+gen7_3DSTATE_SO_BUFFER(struct ilo_builder *builder,
+                       const struct ilo_state_sol *sol,
+                       const struct ilo_state_sol_buffer *sb,
+                       uint8_t buffer)
 {
-   const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 4;
-   struct ilo_buffer *buf;
-   int start, end;
+   const uint8_t cmd_len = 4;
    uint32_t *dw;
    unsigned pos;
 
-   ILO_DEV_ASSERT(builder->dev, 7, 8);
-
-   buf = ilo_buffer(so_target->buffer);
-
-   /* DWord-aligned */
-   assert(stride % 4 == 0);
-   assert(so_target->buffer_offset % 4 == 0);
+   ILO_DEV_ASSERT(builder->dev, 7, 7.5);
 
-   stride &= ~3;
-   start = so_target->buffer_offset & ~3;
-   end = (start + so_target->buffer_size) & ~3;
+   assert(buffer < ILO_STATE_SOL_MAX_BUFFER_COUNT);
 
    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
-   dw[1] = index << GEN7_SO_BUF_DW1_INDEX__SHIFT |
-           stride;
-
-   if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
-      dw[1] |= builder->mocs << GEN8_SO_BUF_DW1_MOCS__SHIFT;
-
-      dw[4] = end - start;
-      dw[5] = 0;
-      dw[6] = 0;
-      dw[7] = 0;
-
-      ilo_builder_batch_reloc64(builder, pos + 2,
-            buf->bo, start, INTEL_RELOC_WRITE);
+   /* see sol_buffer_set_gen7_3dstate_so_buffer() */
+   dw[1] = buffer << GEN7_SO_BUF_DW1_INDEX__SHIFT |
+           builder->mocs << GEN7_SO_BUF_DW1_MOCS__SHIFT |
+           sol->strides[buffer] << GEN7_SO_BUF_DW1_PITCH__SHIFT;
+
+   if (sb->need_bo) {
+      ilo_builder_batch_reloc(builder, pos + 2, sb->bo,
+            sb->so_buf[0], INTEL_RELOC_WRITE);
+      ilo_builder_batch_reloc(builder, pos + 3, sb->bo,
+            sb->so_buf[1], INTEL_RELOC_WRITE);
    } else {
-      dw[1] |= builder->mocs << GEN7_SO_BUF_DW1_MOCS__SHIFT;
-
-      ilo_builder_batch_reloc(builder, pos + 2,
-            buf->bo, start, INTEL_RELOC_WRITE);
-      ilo_builder_batch_reloc(builder, pos + 3,
-            buf->bo, end, INTEL_RELOC_WRITE);
+      dw[2] = 0;
+      dw[3] = 0;
    }
 }
 
 static inline void
-gen7_disable_3DSTATE_SO_BUFFER(struct ilo_builder *builder, int index)
+gen8_3DSTATE_SO_BUFFER(struct ilo_builder *builder,
+                       const struct ilo_state_sol *sol,
+                       const struct ilo_state_sol_buffer *sb,
+                       uint8_t buffer)
 {
-   const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 4;
+   const uint8_t cmd_len = 8;
    uint32_t *dw;
+   unsigned pos;
 
-   ILO_DEV_ASSERT(builder->dev, 7, 8);
+   ILO_DEV_ASSERT(builder->dev, 8, 8);
 
-   ilo_builder_batch_pointer(builder, cmd_len, &dw);
+   pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
-   dw[1] = index << GEN7_SO_BUF_DW1_INDEX__SHIFT;
-   dw[2] = 0;
-   dw[3] = 0;
+   /* see sol_buffer_set_gen8_3dstate_so_buffer() */
+   dw[1] = sb->so_buf[0] |
+           buffer << GEN7_SO_BUF_DW1_INDEX__SHIFT |
+           builder->mocs << GEN8_SO_BUF_DW1_MOCS__SHIFT;
+
+   if (sb->need_bo) {
+      ilo_builder_batch_reloc64(builder, pos + 2, sb->bo,
+            sb->so_buf[1], INTEL_RELOC_WRITE);
+   } else {
+      dw[2] = 0;
+      dw[3] = 0;
+   }
 
-   if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
-      dw[4] = 0;
+   dw[4] = sb->so_buf[2];
+
+   if (sb->need_write_offset_bo) {
+      ilo_builder_batch_reloc64(builder, pos + 5, sb->write_offset_bo,
+            sizeof(uint32_t) * buffer, INTEL_RELOC_WRITE);
+   } else {
       dw[5] = 0;
       dw[6] = 0;
-      dw[7] = 0;
    }
+
+   dw[7] = sb->so_buf[3];
 }
 
 static inline void
diff --git a/src/gallium/drivers/ilo/core/ilo_state_sol.c b/src/gallium/drivers/ilo/core/ilo_state_sol.c
index dbc4b89..38c0b71 100644
--- a/src/gallium/drivers/ilo/core/ilo_state_sol.c
+++ b/src/gallium/drivers/ilo/core/ilo_state_sol.c
@@ -26,6 +26,7 @@
  */
 
 #include "ilo_debug.h"
+#include "ilo_buffer.h"
 #include "ilo_state_sol.h"
 
 static bool
@@ -134,7 +135,7 @@ sol_validate_gen7(const struct ilo_dev *dev,
 }
 
 static bool
-sol_set_gen7_3DSTATE_STREAMOUT(struct ilo_state_sol *so,
+sol_set_gen7_3DSTATE_STREAMOUT(struct ilo_state_sol *sol,
                                const struct ilo_dev *dev,
                                const struct ilo_state_sol_info *info)
 {
@@ -176,12 +177,10 @@ sol_set_gen7_3DSTATE_STREAMOUT(struct ilo_state_sol *so,
       dw1 |= GEN7_SO_DW1_STATISTICS;
 
    if (ilo_dev_gen(dev) < ILO_GEN(8)) {
-      const uint8_t buffer_enables =
-         ((bool) info->buffer_strides[3]) << 3 |
-         ((bool) info->buffer_strides[2]) << 2 |
-         ((bool) info->buffer_strides[1]) << 1 |
-         ((bool) info->buffer_strides[0]);
-
+      const uint8_t buffer_enables = ((bool) info->buffer_strides[3]) << 3 |
+                                     ((bool) info->buffer_strides[2]) << 2 |
+                                     ((bool) info->buffer_strides[1]) << 1 |
+                                     ((bool) info->buffer_strides[0]);
       dw1 |= buffer_enables << GEN7_SO_DW1_BUFFER_ENABLES__SHIFT;
    }
 
@@ -194,27 +193,17 @@ sol_set_gen7_3DSTATE_STREAMOUT(struct ilo_state_sol *so,
          vue_read[0].offset << GEN7_SO_DW2_STREAM0_READ_OFFSET__SHIFT |
          vue_read[0].len << GEN7_SO_DW2_STREAM0_READ_LEN__SHIFT;
 
-   STATIC_ASSERT(ARRAY_SIZE(so->so) >= 4);
-   so->so[0] = dw1;
-   so->so[1] = dw2;
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
-      uint32_t dw3, dw4;
-
-      dw3 = info->buffer_strides[1] << GEN8_SO_DW3_BUFFER1_PITCH__SHIFT |
-            info->buffer_strides[0] << GEN8_SO_DW3_BUFFER0_PITCH__SHIFT;
-      dw4 = info->buffer_strides[3] << GEN8_SO_DW4_BUFFER3_PITCH__SHIFT |
-            info->buffer_strides[2] << GEN8_SO_DW4_BUFFER2_PITCH__SHIFT;
+   STATIC_ASSERT(ARRAY_SIZE(sol->streamout) >= 2);
+   sol->streamout[0] = dw1;
+   sol->streamout[1] = dw2;
 
-      so->so[2] = dw3;
-      so->so[3] = dw4;
-   }
+   memcpy(sol->strides, info->buffer_strides, sizeof(sol->strides));
 
    return true;
 }
 
 static bool
-sol_set_gen7_3DSTATE_SO_DECL_LIST(struct ilo_state_sol *so,
+sol_set_gen7_3DSTATE_SO_DECL_LIST(struct ilo_state_sol *sol,
                                   const struct ilo_dev *dev,
                                   const struct ilo_state_sol_info *info,
                                   uint8_t max_decl_count)
@@ -264,25 +253,146 @@ sol_set_gen7_3DSTATE_SO_DECL_LIST(struct ilo_state_sol *so,
          decl_counts[1] << GEN7_SO_DECL_DW2_STREAM1_ENTRY_COUNT__SHIFT |
          decl_counts[0] << GEN7_SO_DECL_DW2_STREAM0_ENTRY_COUNT__SHIFT;
 
-   STATIC_ASSERT(ARRAY_SIZE(so->so) >= 6);
-   so->so[4] = dw1;
-   so->so[5] = dw2;
+   STATIC_ASSERT(ARRAY_SIZE(sol->so_decl) >= 2);
+   sol->so_decl[0] = dw1;
+   sol->so_decl[1] = dw2;
 
-   STATIC_ASSERT(ARRAY_SIZE(so->decl[0]) == 2);
-   memcpy(so->decl, decl_list, sizeof(so->decl[0]) * max_decl_count);
-   so->decl_count = max_decl_count;
+   STATIC_ASSERT(ARRAY_SIZE(sol->decl[0]) == 2);
+   memcpy(sol->decl, decl_list, sizeof(sol->decl[0]) * max_decl_count);
+   sol->decl_count = max_decl_count;
+
+   return true;
+}
+
+static bool
+sol_buffer_validate_gen7(const struct ilo_dev *dev,
+                         const struct ilo_state_sol_buffer_info *info)
+{
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   if (info->buf)
+      assert(info->offset < info->buf->bo_size && info->size);
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 208:
+    *
+    *     "(Surface Base Address) This field specifies the starting DWord
+    *      address..."
+    */
+   assert(info->offset % 4 == 0);
+
+   /* Gen8+ only */
+   if (info->write_offset_load || info->write_offset_save)
+      assert(ilo_dev_gen(dev) >= ILO_GEN(8));
+
+   /*
+    * From the Broadwell PRM, volume 2b, page 206:
+    *
+    *     "This field (Stream Offset) specifies the Offset in stream output
+    *      buffer to start at, or whether to append to the end of an existing
+    *      buffer. The Offset must be DWORD aligned."
+    */
+   if (info->write_offset_imm_enable) {
+      assert(info->write_offset_load);
+      assert(info->write_offset_imm % 4 == 0);
+   }
+
+   return true;
+}
+
+static uint32_t
+sol_buffer_get_gen6_size(const struct ilo_dev *dev,
+                         const struct ilo_state_sol_buffer_info *info)
+{
+   uint32_t size;
+
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (!info->buf)
+      return 0;
+
+   size = (info->offset + info->size <= info->buf->bo_size) ? info->size :
+      info->buf->bo_size - info->offset;
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 208:
+    *
+    *     "(Surface End Address) This field specifies the ending DWord
+    *      address..."
+    */
+   size &= ~3;
+
+   return size;
+}
+
+static bool
+sol_buffer_set_gen7_3dstate_so_buffer(struct ilo_state_sol_buffer *sb,
+                                      const struct ilo_dev *dev,
+                                      const struct ilo_state_sol_buffer_info *info)
+{
+   const uint32_t size = sol_buffer_get_gen6_size(dev, info);
+
+   ILO_DEV_ASSERT(dev, 7, 7.5);
+
+   if (!sol_buffer_validate_gen7(dev, info))
+      return false;
+
+   STATIC_ASSERT(ARRAY_SIZE(sb->so_buf) >= 2);
+   sb->so_buf[0] = info->offset;
+   sb->so_buf[1] = (size) ? info->offset + size : 0;
+
+   return true;
+}
+
+static bool
+sol_buffer_set_gen8_3dstate_so_buffer(struct ilo_state_sol_buffer *sb,
+                                      const struct ilo_dev *dev,
+                                      const struct ilo_state_sol_buffer_info *info)
+{
+   const uint32_t size = sol_buffer_get_gen6_size(dev, info);
+   uint32_t dw1;
+
+   ILO_DEV_ASSERT(dev, 8, 8);
+
+   if (!sol_buffer_validate_gen7(dev, info))
+      return false;
+
+   dw1 = 0;
+
+   if (info->buf)
+      dw1 |= GEN8_SO_BUF_DW1_ENABLE;
+   if (info->write_offset_load)
+      dw1 |= GEN8_SO_BUF_DW1_OFFSET_WRITE_ENABLE;
+   if (info->write_offset_save)
+      dw1 |= GEN8_SO_BUF_DW1_OFFSET_ENABLE;
+
+   STATIC_ASSERT(ARRAY_SIZE(sb->so_buf) >= 4);
+   sb->so_buf[0] = dw1;
+   sb->so_buf[1] = info->offset;
+
+   /*
+    * From the Broadwell PRM, volume 2b, page 205:
+    *
+    *     "This field (Surface Size) specifies the size of buffer in number
+    *      DWords minus 1 of the buffer in Graphics Memory."
+    */
+   sb->so_buf[2] = (size) ? size / 4 - 1 : 0;
+
+   /* load from imm or sb->write_offset_bo */
+   sb->so_buf[3] = (info->write_offset_imm_enable) ?
+      info->write_offset_imm : ~0u;
 
    return true;
 }
 
 bool
-ilo_state_sol_init(struct ilo_state_sol *so,
+ilo_state_sol_init(struct ilo_state_sol *sol,
                    const struct ilo_dev *dev,
                    const struct ilo_state_sol_info *info)
 {
    bool ret = true;
 
-   assert(ilo_is_zeroed(so, sizeof(*so)));
+   assert(ilo_is_zeroed(sol, sizeof(*sol)));
    assert(ilo_is_zeroed(info->data, info->data_size));
 
    if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
@@ -295,10 +405,10 @@ ilo_state_sol_init(struct ilo_state_sol *so,
       }
 
       assert(ilo_state_sol_data_size(dev, max_decl_count) <= info->data_size);
-      so->decl = (uint32_t (*)[2]) info->data;
+      sol->decl = (uint32_t (*)[2]) info->data;
 
-      ret &= sol_set_gen7_3DSTATE_STREAMOUT(so, dev, info);
-      ret &= sol_set_gen7_3DSTATE_SO_DECL_LIST(so, dev, info, max_decl_count);
+      ret &= sol_set_gen7_3DSTATE_STREAMOUT(sol, dev, info);
+      ret &= sol_set_gen7_3DSTATE_SO_DECL_LIST(sol, dev, info, max_decl_count);
    }
 
    assert(ret);
@@ -318,3 +428,37 @@ ilo_state_sol_init_disabled(struct ilo_state_sol *sol,
 
    return ilo_state_sol_init(sol, dev, &info);
 }
+
+bool
+ilo_state_sol_buffer_init(struct ilo_state_sol_buffer *sb,
+                          const struct ilo_dev *dev,
+                          const struct ilo_state_sol_buffer_info *info)
+{
+   bool ret = true;
+
+   assert(ilo_is_zeroed(sb, sizeof(*sb)));
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(8))
+      ret &= sol_buffer_set_gen8_3dstate_so_buffer(sb, dev, info);
+   else
+      ret &= sol_buffer_set_gen7_3dstate_so_buffer(sb, dev, info);
+
+   sb->need_bo = (info->size > 0);
+   sb->need_write_offset_bo = (info->write_offset_save ||
+         (info->write_offset_load && !info->write_offset_imm_enable));
+
+   assert(ret);
+
+   return ret;
+}
+
+bool
+ilo_state_sol_buffer_init_disabled(struct ilo_state_sol_buffer *sb,
+                                   const struct ilo_dev *dev)
+{
+   struct ilo_state_sol_buffer_info info;
+
+   memset(&info, 0, sizeof(info));
+
+   return ilo_state_sol_buffer_init(sb, dev, &info);
+}
diff --git a/src/gallium/drivers/ilo/core/ilo_state_sol.h b/src/gallium/drivers/ilo/core/ilo_state_sol.h
index c5c693e..2513fcb 100644
--- a/src/gallium/drivers/ilo/core/ilo_state_sol.h
+++ b/src/gallium/drivers/ilo/core/ilo_state_sol.h
@@ -99,12 +99,43 @@ struct ilo_state_sol_info {
 };
 
 struct ilo_state_sol {
-   uint32_t so[6];
+   uint32_t streamout[2];
+   uint16_t strides[4];
 
+   uint32_t so_decl[2];
    uint32_t (*decl)[2];
    uint8_t decl_count;
 };
 
+struct ilo_buffer;
+
+struct ilo_state_sol_buffer_info {
+   const struct ilo_buffer *buf;
+   uint32_t offset;
+   uint32_t size;
+
+   /*
+    * Gen8+ only.  When enabled, require a write offset bo of at least
+    * (sizeof(uint32_t) * ILO_STATE_SOL_MAX_BUFFER_COUNT) bytes
+    */
+   bool write_offset_load;
+   bool write_offset_save;
+
+   bool write_offset_imm_enable;
+   uint32_t write_offset_imm;
+};
+
+struct ilo_state_sol_buffer {
+   uint32_t so_buf[4];
+
+   bool need_bo;
+   bool need_write_offset_bo;
+
+   /* managed by users */
+   struct intel_bo *bo;
+   struct intel_bo *write_offset_bo;
+};
+
 static inline size_t
 ilo_state_sol_data_size(const struct ilo_dev *dev, uint8_t max_decl_count)
 {
@@ -123,4 +154,13 @@ ilo_state_sol_init_disabled(struct ilo_state_sol *sol,
                             const struct ilo_dev *dev,
                             bool render_disable);
 
+bool
+ilo_state_sol_buffer_init(struct ilo_state_sol_buffer *sb,
+                          const struct ilo_dev *dev,
+                          const struct ilo_state_sol_buffer_info *info);
+
+bool
+ilo_state_sol_buffer_init_disabled(struct ilo_state_sol_buffer *sb,
+                                   const struct ilo_dev *dev);
+
 #endif /* ILO_STATE_SOL_H */
diff --git a/src/gallium/drivers/ilo/ilo_render_gen7.c b/src/gallium/drivers/ilo/ilo_render_gen7.c
index e4d2bf0..7d0e4c4 100644
--- a/src/gallium/drivers/ilo/ilo_render_gen7.c
+++ b/src/gallium/drivers/ilo/ilo_render_gen7.c
@@ -431,19 +431,21 @@ gen7_draw_sol(struct ilo_render *r,
    /* 3DSTATE_SO_BUFFER */
    if ((DIRTY(SO) || dirty_sh || r->batch_bo_changed) &&
        vec->so.enabled) {
-      const struct pipe_stream_output_info *so_info;
       int i;
 
-      so_info = ilo_shader_get_kernel_so_info(shader);
-
-      for (i = 0; i < vec->so.count; i++) {
-         const int stride = so_info->stride[i] * 4; /* in bytes */
-
-         gen7_3DSTATE_SO_BUFFER(r->builder, i, stride, vec->so.states[i]);
+      for (i = 0; i < ILO_STATE_SOL_MAX_BUFFER_COUNT; i++) {
+         const struct pipe_stream_output_target *target =
+            (i < vec->so.count && vec->so.states[i]) ?
+            vec->so.states[i] : NULL;
+         const struct ilo_state_sol_buffer *sb = (target) ?
+            &((const struct ilo_stream_output_target *) target)->sb :
+            &vec->so.dummy_sb;
+
+         if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
+            gen8_3DSTATE_SO_BUFFER(r->builder, sol, sb, i);
+         else
+            gen7_3DSTATE_SO_BUFFER(r->builder, sol, sb, i);
       }
-
-      for (; i < 4; i++)
-         gen7_disable_3DSTATE_SO_BUFFER(r->builder, i);
    }
 
    /* 3DSTATE_SO_DECL_LIST */
diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c
index 966a6e0..62e3180 100644
--- a/src/gallium/drivers/ilo/ilo_state.c
+++ b/src/gallium/drivers/ilo/ilo_state.c
@@ -1899,19 +1899,28 @@ ilo_create_stream_output_target(struct pipe_context *pipe,
                                 unsigned buffer_offset,
                                 unsigned buffer_size)
 {
-   struct pipe_stream_output_target *target;
+   const struct ilo_dev *dev = ilo_context(pipe)->dev;
+   struct ilo_stream_output_target *target;
+   struct ilo_state_sol_buffer_info info;
 
-   target = MALLOC_STRUCT(pipe_stream_output_target);
+   target = CALLOC_STRUCT(ilo_stream_output_target);
    assert(target);
 
-   pipe_reference_init(&target->reference, 1);
-   target->buffer = NULL;
-   pipe_resource_reference(&target->buffer, res);
-   target->context = pipe;
-   target->buffer_offset = buffer_offset;
-   target->buffer_size = buffer_size;
+   pipe_reference_init(&target->base.reference, 1);
+   pipe_resource_reference(&target->base.buffer, res);
+   target->base.context = pipe;
+   target->base.buffer_offset = buffer_offset;
+   target->base.buffer_size = buffer_size;
+
+   memset(&info, 0, sizeof(info));
+   info.buf = ilo_buffer(res);
+   info.offset = buffer_offset;
+   info.size = buffer_size;
+
+   ilo_state_sol_buffer_init(&target->sb, dev, &info);
+   target->sb.bo = info.buf->bo;
 
-   return target;
+   return &target->base;
 }
 
 static void
@@ -2338,6 +2347,8 @@ ilo_state_vector_init(const struct ilo_dev *dev,
    ilo_state_ds_init_disabled(&vec->disabled_ds, dev);
    ilo_state_gs_init_disabled(&vec->disabled_gs, dev);
 
+   ilo_state_sol_buffer_init_disabled(&vec->so.dummy_sb, dev);
+
    ilo_state_surface_init_for_null(&vec->fb.null_rt, dev);
    ilo_state_zs_init_for_null(&vec->fb.null_zs, dev);
 
@@ -2439,6 +2450,10 @@ ilo_state_vector_resource_renamed(struct ilo_state_vector *vec,
 
       for (i = 0; i < vec->so.count; i++) {
          if (vec->so.states[i]->buffer == res) {
+            struct ilo_stream_output_target *target =
+               (struct ilo_stream_output_target *) vec->so.states[i];
+
+            target->sb.bo = ilo_buffer(res)->bo;
             states |= ILO_DIRTY_SO;
             break;
          }
diff --git a/src/gallium/drivers/ilo/ilo_state.h b/src/gallium/drivers/ilo/ilo_state.h
index d990269..e4746d0 100644
--- a/src/gallium/drivers/ilo/ilo_state.h
+++ b/src/gallium/drivers/ilo/ilo_state.h
@@ -217,11 +217,19 @@ struct ilo_view_state {
    unsigned count;
 };
 
+struct ilo_stream_output_target {
+   struct pipe_stream_output_target base;
+
+   struct ilo_state_sol_buffer sb;
+};
+
 struct ilo_so_state {
    struct pipe_stream_output_target *states[ILO_MAX_SO_BUFFERS];
    unsigned count;
    unsigned append_bitmask;
 
+   struct ilo_state_sol_buffer dummy_sb;
+
    bool enabled;
 };
 




More information about the mesa-commit mailing list