summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/ilo/core/ilo_builder_3d_top.h56
-rw-r--r--src/gallium/drivers/ilo/core/ilo_state_vf.c113
-rw-r--r--src/gallium/drivers/ilo/core/ilo_state_vf.h29
-rw-r--r--src/gallium/drivers/ilo/ilo_render_gen6.c4
-rw-r--r--src/gallium/drivers/ilo/ilo_render_gen8.c4
-rw-r--r--src/gallium/drivers/ilo/ilo_state.c36
-rw-r--r--src/gallium/drivers/ilo/ilo_state.h1
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 782746591d9..bb20c7fd87a 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 4126560aee9..92e0380e5c3 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 c51da10270f..488f92f9b40 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 f997274397a..8415b136002 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 3b8589ce8f1..4c1c08bbd25 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 d6144e4035f..e24f8fa316f 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 66c671a01e5..2b3147fc355 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;
};