From da4878cb807f46e6053731a177c3c75497aaf4fb Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 19 Jun 2015 15:06:50 +0800 Subject: [PATCH] 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. --- .../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 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 @@ -477,6 +477,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) { @@ -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; }; -- 2.30.2