diff options
author | Chia-I Wu <[email protected]> | 2015-06-18 14:26:29 +0800 |
---|---|---|
committer | Chia-I Wu <[email protected]> | 2015-06-20 11:14:14 +0800 |
commit | 4555211028394673f8ad68f3de9c12e9a1f93160 (patch) | |
tree | c9d885b73ee4253b91a4fe7e22171e76b63fc90e /src/gallium/drivers/ilo/core | |
parent | e8d297b7a108fcf1cb688fe1db89e83b8f85e091 (diff) |
ilo: add 3DSTATE_VF_INSTANCING to ilo_state_vf
3DSTATE_VF_INSTANCING specifies instancing enable and step rate. They are
specified along with 3DSTATE_VERTEX_BUFFERS instead prior to Gen8. Both
commands are added.
Diffstat (limited to 'src/gallium/drivers/ilo/core')
-rw-r--r-- | src/gallium/drivers/ilo/core/ilo_builder_3d_top.h | 50 | ||||
-rw-r--r-- | src/gallium/drivers/ilo/core/ilo_state_vf.c | 117 | ||||
-rw-r--r-- | src/gallium/drivers/ilo/core/ilo_state_vf.h | 26 |
3 files changed, 144 insertions, 49 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 e4ee9cf3af4..782746591d9 100644 --- a/src/gallium/drivers/ilo/core/ilo_builder_3d_top.h +++ b/src/gallium/drivers/ilo/core/ilo_builder_3d_top.h @@ -264,7 +264,8 @@ gen8_3DSTATE_VF_TOPOLOGY(struct ilo_builder *builder, static inline void gen8_3DSTATE_VF_INSTANCING(struct ilo_builder *builder, - int vb_index, uint32_t step_rate) + const struct ilo_state_vf *vf, + uint32_t attr) { const uint8_t cmd_len = 3; uint32_t *dw; @@ -274,10 +275,15 @@ gen8_3DSTATE_VF_INSTANCING(struct ilo_builder *builder, ilo_builder_batch_pointer(builder, cmd_len, &dw); dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_INSTANCING) | (cmd_len - 2); - dw[1] = vb_index; - if (step_rate) - dw[1] |= GEN8_INSTANCING_DW1_ENABLE; - dw[2] = step_rate; + dw[1] = attr << GEN8_INSTANCING_DW1_VE_INDEX__SHIFT; + dw[2] = 0; + /* see vf_set_gen8_3DSTATE_VF_INSTANCING() */ + if (attr >= vf->internal_ve_count) { + attr -= vf->internal_ve_count; + + dw[1] |= vf->user_instancing[attr][0]; + dw[2] |= vf->user_instancing[attr][1]; + } } static inline void @@ -298,9 +304,9 @@ 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 unsigned *instance_divisors, unsigned vb_count) { uint8_t cmd_len; @@ -327,9 +333,9 @@ gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder, pos++; for (hw_idx = 0; hw_idx < vb_count; hw_idx++) { - const unsigned instance_divisor = instance_divisors[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]; dw[0] = hw_idx << GEN6_VB_DW0_INDEX__SHIFT; @@ -341,19 +347,19 @@ gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder, if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) dw[0] |= GEN7_VB_DW0_ADDR_MODIFIED; - if (instance_divisor) - dw[0] |= GEN6_VB_DW0_ACCESS_INSTANCEDATA; - else - dw[0] |= GEN6_VB_DW0_ACCESS_VERTEXDATA; + dw[1] = 0; + dw[2] = 0; + dw[3] = 0; - /* use null vb if there is no buffer or the stride is out of range */ - if (!cso->buffer || cso->stride > 2048) { - dw[0] |= GEN6_VB_DW0_IS_NULL; - dw[1] = 0; - dw[2] = 0; - dw[3] = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? - 0 : instance_divisor; + /* 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; } @@ -371,8 +377,6 @@ gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder, const uint32_t start_offset = cso->buffer_offset; const uint32_t end_offset = buf->bo_size - 1; - dw[3] = instance_divisor; - ilo_builder_batch_reloc(builder, pos + 1, buf->bo, start_offset, 0); ilo_builder_batch_reloc(builder, pos + 2, buf->bo, end_offset, 0); } @@ -431,12 +435,16 @@ gen6_3DSTATE_VERTEX_ELEMENTS(struct ilo_builder *builder, dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) | (cmd_len - 2); dw++; - /* see vf_set_gen6_3DSTATE_VERTEX_ELEMENTS() */ + /* + * see vf_params_set_gen6_internal_ve() and + * vf_set_gen6_3DSTATE_VERTEX_ELEMENTS() + */ if (vf->internal_ve_count) { memcpy(dw, vf->internal_ve, sizeof(vf->internal_ve[0]) * vf->internal_ve_count); dw += 2 * vf->internal_ve_count; } + memcpy(dw, vf->user_ve, sizeof(vf->user_ve[0]) * vf->user_ve_count); } diff --git a/src/gallium/drivers/ilo/core/ilo_state_vf.c b/src/gallium/drivers/ilo/core/ilo_state_vf.c index 571af3d5aea..4126560aee9 100644 --- a/src/gallium/drivers/ilo/core/ilo_state_vf.c +++ b/src/gallium/drivers/ilo/core/ilo_state_vf.c @@ -221,6 +221,66 @@ vf_set_gen6_3DSTATE_VERTEX_ELEMENTS(struct ilo_state_vf *vf, return true; } +static bool +vf_set_gen6_vertex_buffer_state(struct ilo_state_vf *vf, + const struct ilo_dev *dev, + const struct ilo_state_vf_info *info) +{ + uint8_t i; + + ILO_DEV_ASSERT(dev, 6, 7.5); + + memset(vf->vb_to_first_elem, -1, sizeof(vf->vb_to_first_elem)); + + for (i = 0; i < info->element_count; i++) { + const struct ilo_state_vf_element_info *elem = &info->elements[i]; + + STATIC_ASSERT(ARRAY_SIZE(vf->user_instancing[i]) >= 2); + /* instancing enable only */ + vf->user_instancing[i][0] = (elem->instancing_enable) ? + GEN6_VB_DW0_ACCESS_INSTANCEDATA : + GEN6_VB_DW0_ACCESS_VERTEXDATA; + vf->user_instancing[i][1] = elem->instancing_step_rate; + + /* + * Instancing is per VB, not per VE, before Gen8. Set up a VB-to-VE + * mapping as well. + */ + if (vf->vb_to_first_elem[elem->buffer] < 0) { + vf->vb_to_first_elem[elem->buffer] = i; + } else { + const struct ilo_state_vf_element_info *first = + &info->elements[vf->vb_to_first_elem[elem->buffer]]; + + assert(elem->instancing_enable == first->instancing_enable && + elem->instancing_step_rate == first->instancing_step_rate); + } + } + + return true; +} + +static bool +vf_set_gen8_3DSTATE_VF_INSTANCING(struct ilo_state_vf *vf, + const struct ilo_dev *dev, + const struct ilo_state_vf_info *info) +{ + uint8_t i; + + ILO_DEV_ASSERT(dev, 8, 8); + + for (i = 0; i < info->element_count; i++) { + const struct ilo_state_vf_element_info *elem = &info->elements[i]; + + STATIC_ASSERT(ARRAY_SIZE(vf->user_instancing[i]) >= 2); + vf->user_instancing[i][0] = (elem->instancing_enable) ? + GEN8_INSTANCING_DW1_ENABLE : 0; + vf->user_instancing[i][1] = elem->instancing_step_rate; + } + + return true; +} + static uint32_t get_gen6_component_zeros(const struct ilo_dev *dev) { @@ -254,7 +314,9 @@ vf_params_set_gen6_internal_ve(struct ilo_state_vf *vf, { const bool prepend_ids = (params->prepend_vertexid || params->prepend_instanceid); - uint8_t internal_ve_count = 0; + uint8_t internal_ve_count = 0, i; + uint32_t dw1[2]; + ILO_DEV_ASSERT(dev, 6, 8); @@ -279,29 +341,23 @@ vf_params_set_gen6_internal_ve(struct ilo_state_vf *vf, * * - [DevILK+] Element[0] must be valid." */ - if (params->prepend_zeros || (!user_ve_count && !prepend_ids)) { - STATIC_ASSERT(ARRAY_SIZE(vf->internal_ve[internal_ve_count]) >= 2); - vf->internal_ve[internal_ve_count][0] = GEN6_VE_DW0_VALID; - vf->internal_ve[internal_ve_count][1] = get_gen6_component_zeros(dev); - internal_ve_count++; - } + if (params->prepend_zeros || (!user_ve_count && !prepend_ids)) + dw1[internal_ve_count++] = get_gen6_component_zeros(dev); if (prepend_ids) { - uint32_t dw1; - if (ilo_dev_gen(dev) >= ILO_GEN(8)) { /* placeholder for 3DSTATE_VF_SGVS */ - dw1 = get_gen6_component_zeros(dev); + dw1[internal_ve_count++] = get_gen6_component_zeros(dev); } else { - dw1 = get_gen6_component_ids(dev, - params->prepend_vertexid, - params->prepend_instanceid); + dw1[internal_ve_count++] = get_gen6_component_ids(dev, + params->prepend_vertexid, params->prepend_instanceid); } + } - STATIC_ASSERT(ARRAY_SIZE(vf->internal_ve[internal_ve_count]) >= 2); - vf->internal_ve[internal_ve_count][0] = GEN6_VE_DW0_VALID; - vf->internal_ve[internal_ve_count][1] = dw1; - internal_ve_count++; + for (i = 0; i < internal_ve_count; i++) { + STATIC_ASSERT(ARRAY_SIZE(vf->internal_ve[i]) >= 2); + vf->internal_ve[i][0] = GEN6_VE_DW0_VALID; + vf->internal_ve[i][1] = dw1[i]; } vf->internal_ve_count = internal_ve_count; @@ -440,9 +496,16 @@ ilo_state_vf_init(struct ilo_state_vf *vf, assert(ilo_state_vf_data_size(dev, info->element_count) <= info->data_size); vf->user_ve = (uint32_t (*)[2]) info->data; + vf->user_instancing = + (uint32_t (*)[2]) (vf->user_ve + info->element_count); ret &= vf_set_gen6_3DSTATE_VERTEX_ELEMENTS(vf, dev, info); + if (ilo_dev_gen(dev) >= ILO_GEN(8)) + ret &= vf_set_gen8_3DSTATE_VF_INSTANCING(vf, dev, info); + else + ret &= vf_set_gen6_vertex_buffer_state(vf, dev, info); + ret &= ilo_state_vf_set_params(vf, dev, &info->params); assert(ret); @@ -545,8 +608,12 @@ ilo_state_vf_full_delta(const struct ilo_state_vf *vf, { delta->dirty = ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS; - if (ilo_dev_gen(dev) >= ILO_GEN(8)) - delta->dirty |= ILO_STATE_VF_3DSTATE_VF_SGVS; + if (ilo_dev_gen(dev) >= ILO_GEN(8)) { + delta->dirty |= ILO_STATE_VF_3DSTATE_VF_SGVS | + ILO_STATE_VF_3DSTATE_VF_INSTANCING; + } else { + delta->dirty |= ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS; + } if (ilo_dev_gen(dev) >= ILO_GEN(7.5)) delta->dirty |= ILO_STATE_VF_3DSTATE_VF; @@ -561,7 +628,8 @@ ilo_state_vf_get_delta(const struct ilo_state_vf *vf, struct ilo_state_vf_delta *delta) { /* no shallow copying */ - assert(vf->user_ve != old->user_ve); + assert(vf->user_ve != old->user_ve && + vf->user_instancing != old->user_instancing); delta->dirty = 0; @@ -573,6 +641,15 @@ ilo_state_vf_get_delta(const struct ilo_state_vf *vf, sizeof(vf->user_ve[0]) * vf->user_ve_count)) delta->dirty |= ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS; + if (vf->user_ve_count != old->user_ve_count || + memcmp(vf->user_instancing, old->user_instancing, + sizeof(vf->user_instancing[0]) * vf->user_ve_count)) { + if (ilo_dev_gen(dev) >= ILO_GEN(8)) + delta->dirty |= ILO_STATE_VF_3DSTATE_VF_INSTANCING; + else + delta->dirty |= ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS; + } + if (ilo_dev_gen(dev) >= ILO_GEN(8)) { if (vf->sgvs[0] != old->sgvs[0]) delta->dirty |= ILO_STATE_VF_3DSTATE_VF_SGVS; diff --git a/src/gallium/drivers/ilo/core/ilo_state_vf.h b/src/gallium/drivers/ilo/core/ilo_state_vf.h index 49a0eb3aa14..c51da10270f 100644 --- a/src/gallium/drivers/ilo/core/ilo_state_vf.h +++ b/src/gallium/drivers/ilo/core/ilo_state_vf.h @@ -48,8 +48,10 @@ enum ilo_state_vf_dirty_bits { ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS = (1 << 0), ILO_STATE_VF_3DSTATE_VF_SGVS = (1 << 1), - ILO_STATE_VF_3DSTATE_VF = (1 << 2), - ILO_STATE_VF_3DSTATE_INDEX_BUFFER = (1 << 3), + ILO_STATE_VF_3DSTATE_VF_INSTANCING = (1 << 2), + ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS = (1 << 3), + ILO_STATE_VF_3DSTATE_VF = (1 << 4), + ILO_STATE_VF_3DSTATE_INDEX_BUFFER = (1 << 5), }; /** @@ -64,6 +66,10 @@ struct ilo_state_vf_element_info { 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; + uint32_t instancing_step_rate; }; /** @@ -100,17 +106,20 @@ struct ilo_state_vf_info { }; struct ilo_state_vf { + uint32_t (*user_ve)[2]; + uint32_t (*user_instancing)[2]; + int8_t vb_to_first_elem[ILO_STATE_VF_MAX_BUFFER_COUNT]; + uint8_t user_ve_count; + + bool edge_flag_supported; + uint32_t last_user_ve[2][2]; + /* two VEs are reserved for internal use */ uint32_t internal_ve[2][2]; - uint32_t (*user_ve)[2]; uint8_t internal_ve_count; - uint8_t user_ve_count; uint32_t sgvs[1]; - uint32_t last_user_ve[2][2]; - bool edge_flag_supported; - uint32_t cut[2]; }; @@ -122,7 +131,8 @@ static inline size_t ilo_state_vf_data_size(const struct ilo_dev *dev, uint8_t element_count) { const struct ilo_state_vf *vf = NULL; - return sizeof(vf->user_ve[0]) * element_count; + return (sizeof(vf->user_ve[0]) + + sizeof(vf->user_instancing[0])) * element_count; } bool |