From e8d297b7a108fcf1cb688fe1db89e83b8f85e091 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 16 Jun 2015 23:11:06 +0800 Subject: [PATCH] ilo: add 3DSTATE_VF to ilo_state_vf 3DSTATE_VF specifies cut index enable and cut index. Cut index enable is specified in 3DSTATE_INDEX_BUFFER instead prior to Gen7.5. Both commands are added. --- .../drivers/ilo/core/ilo_builder_3d_top.h | 49 ++++---- src/gallium/drivers/ilo/core/ilo_state_vf.c | 109 +++++++++++++++++- src/gallium/drivers/ilo/core/ilo_state_vf.h | 13 ++- .../drivers/ilo/genhw/gen_render_3d.xml.h | 12 +- src/gallium/drivers/ilo/ilo_render.c | 4 - src/gallium/drivers/ilo/ilo_render_gen.h | 2 - src/gallium/drivers/ilo/ilo_render_gen6.c | 24 ++-- src/gallium/drivers/ilo/ilo_render_gen8.c | 11 +- src/gallium/drivers/ilo/ilo_state.c | 32 ++++- 9 files changed, 190 insertions(+), 66 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 bfd94344103..e4ee9cf3af4 100644 --- a/src/gallium/drivers/ilo/core/ilo_builder_3d_top.h +++ b/src/gallium/drivers/ilo/core/ilo_builder_3d_top.h @@ -190,8 +190,7 @@ gen7_3DSTATE_URB_GS(struct ilo_builder *builder, static inline void gen75_3DSTATE_VF(struct ilo_builder *builder, - bool enable_cut_index, - uint32_t cut_index) + const struct ilo_state_vf *vf) { const uint8_t cmd_len = 2; uint32_t *dw; @@ -200,11 +199,10 @@ gen75_3DSTATE_VF(struct ilo_builder *builder, ilo_builder_batch_pointer(builder, cmd_len, &dw); - dw[0] = GEN75_RENDER_CMD(3D, 3DSTATE_VF) | (cmd_len - 2); - if (enable_cut_index) - dw[0] |= GEN75_VF_DW0_CUT_INDEX_ENABLE; - - dw[1] = cut_index; + /* see vf_params_set_gen75_3DSTATE_VF() */ + dw[0] = GEN75_RENDER_CMD(3D, 3DSTATE_VF) | (cmd_len - 2) | + vf->cut[0]; + dw[1] = vf->cut[1]; } static inline void @@ -444,13 +442,13 @@ gen6_3DSTATE_VERTEX_ELEMENTS(struct ilo_builder *builder, static inline void gen6_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder, - const struct ilo_ib_state *ib, - bool enable_cut_index) + const struct ilo_state_vf *vf, + const struct ilo_ib_state *ib) { const uint8_t cmd_len = 3; struct ilo_buffer *buf = ilo_buffer(ib->hw_resource); uint32_t start_offset, end_offset; - int format; + enum gen_index_format format; uint32_t *dw; unsigned pos; @@ -459,23 +457,19 @@ gen6_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder, if (!buf) return; - /* this is moved to the new 3DSTATE_VF */ - if (ilo_dev_gen(builder->dev) >= ILO_GEN(7.5)) - assert(!enable_cut_index); - switch (ib->hw_index_size) { case 4: - format = GEN6_IB_DW0_FORMAT_DWORD; + format = GEN6_INDEX_DWORD; break; case 2: - format = GEN6_IB_DW0_FORMAT_WORD; + format = GEN6_INDEX_WORD; break; case 1: - format = GEN6_IB_DW0_FORMAT_BYTE; + format = GEN6_INDEX_BYTE; break; default: assert(!"unknown index size"); - format = GEN6_IB_DW0_FORMAT_BYTE; + format = GEN6_INDEX_BYTE; break; } @@ -494,9 +488,11 @@ gen6_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder, dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2) | builder->mocs << GEN6_IB_DW0_MOCS__SHIFT | - format; - if (enable_cut_index) - dw[0] |= GEN6_IB_DW0_CUT_INDEX_ENABLE; + format << GEN6_IB_DW0_FORMAT__SHIFT; + + /* see vf_params_set_gen6_3dstate_index_buffer() */ + if (ilo_dev_gen(builder->dev) <= ILO_GEN(7)) + dw[0] |= vf->cut[0]; ilo_builder_batch_reloc(builder, pos + 1, buf->bo, start_offset, 0); ilo_builder_batch_reloc(builder, pos + 2, buf->bo, end_offset, 0); @@ -504,6 +500,7 @@ gen6_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder, static inline void gen8_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder, + const struct ilo_state_vf *vf, const struct ilo_ib_state *ib) { const uint8_t cmd_len = 5; @@ -519,24 +516,24 @@ gen8_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder, switch (ib->hw_index_size) { case 4: - format = GEN8_IB_DW1_FORMAT_DWORD; + format = GEN6_INDEX_DWORD; break; case 2: - format = GEN8_IB_DW1_FORMAT_WORD; + format = GEN6_INDEX_WORD; break; case 1: - format = GEN8_IB_DW1_FORMAT_BYTE; + format = GEN6_INDEX_BYTE; break; default: assert(!"unknown index size"); - format = GEN8_IB_DW1_FORMAT_BYTE; + format = GEN6_INDEX_BYTE; break; } pos = ilo_builder_batch_pointer(builder, cmd_len, &dw); dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2); - dw[1] = format | + dw[1] = format << GEN8_IB_DW1_FORMAT__SHIFT | builder->mocs << GEN8_IB_DW1_MOCS__SHIFT; dw[4] = buf->bo_size; diff --git a/src/gallium/drivers/ilo/core/ilo_state_vf.c b/src/gallium/drivers/ilo/core/ilo_state_vf.c index f9a462db254..571af3d5aea 100644 --- a/src/gallium/drivers/ilo/core/ilo_state_vf.c +++ b/src/gallium/drivers/ilo/core/ilo_state_vf.c @@ -339,6 +339,94 @@ vf_params_set_gen8_3DSTATE_VF_SGVS(struct ilo_state_vf *vf, return true; } +static uint32_t +get_gen6_fixed_cut_index(const struct ilo_dev *dev, + enum gen_index_format format) +{ + const uint32_t fixed = ~0u; + + ILO_DEV_ASSERT(dev, 6, 7); + + switch (format) { + case GEN6_INDEX_BYTE: return (uint8_t) fixed; + case GEN6_INDEX_WORD: return (uint16_t) fixed; + case GEN6_INDEX_DWORD: return (uint32_t) fixed; + default: + assert(!"unknown index format"); + return fixed; + } +} + +static bool +get_gen6_cut_index_supported(const struct ilo_dev *dev, + enum gen_3dprim_type topology) +{ + ILO_DEV_ASSERT(dev, 6, 8); + + /* + * See the Sandy Bridge PRM, volume 2 part 1, page 80 and the Haswell PRM, + * volume 7, page 456. + */ + switch (topology) { + case GEN6_3DPRIM_TRIFAN: + case GEN6_3DPRIM_QUADLIST: + case GEN6_3DPRIM_QUADSTRIP: + case GEN6_3DPRIM_POLYGON: + case GEN6_3DPRIM_LINELOOP: + return (ilo_dev_gen(dev) >= ILO_GEN(7.5)); + case GEN6_3DPRIM_RECTLIST: + case GEN6_3DPRIM_TRIFAN_NOSTIPPLE: + return false; + default: + return true; + } +} + +static bool +vf_params_set_gen6_3dstate_index_buffer(struct ilo_state_vf *vf, + const struct ilo_dev *dev, + const struct ilo_state_vf_params_info *params) +{ + uint32_t dw0 = 0; + + ILO_DEV_ASSERT(dev, 6, 7); + + /* cut index only, as in 3DSTATE_VF */ + if (params->cut_index_enable) { + assert(get_gen6_cut_index_supported(dev, params->cv_topology)); + assert(get_gen6_fixed_cut_index(dev, params->cv_index_format) == + params->cut_index); + + dw0 |= GEN6_IB_DW0_CUT_INDEX_ENABLE; + } + + STATIC_ASSERT(ARRAY_SIZE(vf->cut) >= 1); + vf->cut[0] = dw0; + + return true; +} + +static bool +vf_params_set_gen75_3DSTATE_VF(struct ilo_state_vf *vf, + const struct ilo_dev *dev, + const struct ilo_state_vf_params_info *params) +{ + uint32_t dw0 = 0; + + ILO_DEV_ASSERT(dev, 7.5, 8); + + if (params->cut_index_enable) { + assert(get_gen6_cut_index_supported(dev, params->cv_topology)); + dw0 |= GEN75_VF_DW0_CUT_INDEX_ENABLE; + } + + STATIC_ASSERT(ARRAY_SIZE(vf->cut) >= 2); + vf->cut[0] = dw0; + vf->cut[1] = params->cut_index; + + return true; +} + bool ilo_state_vf_init(struct ilo_state_vf *vf, const struct ilo_dev *dev, @@ -354,6 +442,7 @@ ilo_state_vf_init(struct ilo_state_vf *vf, vf->user_ve = (uint32_t (*)[2]) info->data; ret &= vf_set_gen6_3DSTATE_VERTEX_ELEMENTS(vf, dev, info); + ret &= ilo_state_vf_set_params(vf, dev, &info->params); assert(ret); @@ -429,7 +518,7 @@ ilo_state_vf_set_params(struct ilo_state_vf *vf, if (params->last_element_edge_flag) { assert(vf->edge_flag_supported); if (ilo_dev_gen(dev) == ILO_GEN(6)) - assert(!params->cv_is_quad); + assert(params->cv_topology != GEN6_3DPRIM_QUADLIST); } if (vf->edge_flag_supported) { @@ -439,6 +528,11 @@ ilo_state_vf_set_params(struct ilo_state_vf *vf, sizeof(vf->user_ve[vf->user_ve_count - 1])); } + if (ilo_dev_gen(dev) >= ILO_GEN(7.5)) + ret &= vf_params_set_gen75_3DSTATE_VF(vf, dev, params); + else + ret &= vf_params_set_gen6_3dstate_index_buffer(vf, dev, params); + assert(ret); return ret; @@ -453,6 +547,11 @@ ilo_state_vf_full_delta(const struct ilo_state_vf *vf, if (ilo_dev_gen(dev) >= ILO_GEN(8)) delta->dirty |= ILO_STATE_VF_3DSTATE_VF_SGVS; + + if (ilo_dev_gen(dev) >= ILO_GEN(7.5)) + delta->dirty |= ILO_STATE_VF_3DSTATE_VF; + else + delta->dirty |= ILO_STATE_VF_3DSTATE_INDEX_BUFFER; } void @@ -478,4 +577,12 @@ ilo_state_vf_get_delta(const struct ilo_state_vf *vf, if (vf->sgvs[0] != old->sgvs[0]) delta->dirty |= ILO_STATE_VF_3DSTATE_VF_SGVS; } + + if (ilo_dev_gen(dev) >= ILO_GEN(7.5)) { + if (memcmp(vf->cut, old->cut, sizeof(vf->cut))) + delta->dirty |= ILO_STATE_VF_3DSTATE_VF; + } else { + if (vf->cut[0] != old->cut[0]) + delta->dirty |= ILO_STATE_VF_3DSTATE_INDEX_BUFFER; + } } diff --git a/src/gallium/drivers/ilo/core/ilo_state_vf.h b/src/gallium/drivers/ilo/core/ilo_state_vf.h index 7238e661d35..49a0eb3aa14 100644 --- a/src/gallium/drivers/ilo/core/ilo_state_vf.h +++ b/src/gallium/drivers/ilo/core/ilo_state_vf.h @@ -48,6 +48,8 @@ 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), }; /** @@ -68,7 +70,7 @@ struct ilo_state_vf_element_info { * VF parameters. */ struct ilo_state_vf_params_info { - bool cv_is_quad; + enum gen_3dprim_type cv_topology; /* prepend an attribute of zeros */ bool prepend_zeros; @@ -78,8 +80,15 @@ struct ilo_state_vf_params_info { bool prepend_instanceid; bool last_element_edge_flag; + + enum gen_index_format cv_index_format; + bool cut_index_enable; + uint32_t cut_index; }; +/** + * Vertex fetch. + */ struct ilo_state_vf_info { void *data; size_t data_size; @@ -101,6 +110,8 @@ struct ilo_state_vf { uint32_t last_user_ve[2][2]; bool edge_flag_supported; + + uint32_t cut[2]; }; struct ilo_state_vf_delta { diff --git a/src/gallium/drivers/ilo/genhw/gen_render_3d.xml.h b/src/gallium/drivers/ilo/genhw/gen_render_3d.xml.h index 1abfef987b5..60e3922e286 100644 --- a/src/gallium/drivers/ilo/genhw/gen_render_3d.xml.h +++ b/src/gallium/drivers/ilo/genhw/gen_render_3d.xml.h @@ -105,6 +105,12 @@ enum gen_state_alignment { GEN8_ALIGNMENT_SURFACE_STATE = 0x40, }; +enum gen_index_format { + GEN6_INDEX_BYTE = 0x0, + GEN6_INDEX_WORD = 0x1, + GEN6_INDEX_DWORD = 0x2, +}; + enum gen_vf_component { GEN6_VFCOMP_NOSTORE = 0x0, GEN6_VFCOMP_STORE_SRC = 0x1, @@ -366,9 +372,6 @@ enum gen_msrast_mode { #define GEN6_IB_DW0_CUT_INDEX_ENABLE (0x1 << 10) #define GEN6_IB_DW0_FORMAT__MASK 0x00000300 #define GEN6_IB_DW0_FORMAT__SHIFT 8 -#define GEN6_IB_DW0_FORMAT_BYTE (0x0 << 8) -#define GEN6_IB_DW0_FORMAT_WORD (0x1 << 8) -#define GEN6_IB_DW0_FORMAT_DWORD (0x2 << 8) @@ -376,9 +379,6 @@ enum gen_msrast_mode { #define GEN8_IB_DW1_FORMAT__MASK 0x00000300 #define GEN8_IB_DW1_FORMAT__SHIFT 8 -#define GEN8_IB_DW1_FORMAT_BYTE (0x0 << 8) -#define GEN8_IB_DW1_FORMAT_WORD (0x1 << 8) -#define GEN8_IB_DW1_FORMAT_DWORD (0x2 << 8) #define GEN8_IB_DW1_MOCS__MASK 0x0000007f #define GEN8_IB_DW1_MOCS__SHIFT 0 diff --git a/src/gallium/drivers/ilo/ilo_render.c b/src/gallium/drivers/ilo/ilo_render.c index 910ed8c9608..21f75de11a0 100644 --- a/src/gallium/drivers/ilo/ilo_render.c +++ b/src/gallium/drivers/ilo/ilo_render.c @@ -334,7 +334,6 @@ draw_session_prepare(struct ilo_render *render, render->instruction_bo_changed = true; session->prim_changed = true; - session->primitive_restart_changed = true; ilo_state_urb_full_delta(&vec->urb, render->dev, &session->urb_delta); ilo_state_vf_full_delta(&vec->ve->vf, render->dev, &session->vf_delta); @@ -350,8 +349,6 @@ draw_session_prepare(struct ilo_render *render, } else { session->prim_changed = (render->state.reduced_prim != session->reduced_prim); - session->primitive_restart_changed = - (render->state.primitive_restart != vec->draw->primitive_restart); ilo_state_urb_get_delta(&vec->urb, render->dev, &render->state.urb, &session->urb_delta); @@ -390,7 +387,6 @@ draw_session_end(struct ilo_render *render, render->instruction_bo_changed = false; render->state.reduced_prim = session->reduced_prim; - render->state.primitive_restart = vec->draw->primitive_restart; render->state.urb = vec->urb; render->state.rs = vec->rasterizer->rs; diff --git a/src/gallium/drivers/ilo/ilo_render_gen.h b/src/gallium/drivers/ilo/ilo_render_gen.h index ae14e779e1f..6bbc0a8e3f1 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen.h +++ b/src/gallium/drivers/ilo/ilo_render_gen.h @@ -82,7 +82,6 @@ struct ilo_render { */ uint32_t deferred_pipe_control_dw1; - bool primitive_restart; int reduced_prim; int so_max_vertices; @@ -143,7 +142,6 @@ struct ilo_render_draw_session { int reduced_prim; bool prim_changed; - bool primitive_restart_changed; struct ilo_state_urb_delta urb_delta; struct ilo_state_vf_delta vf_delta; diff --git a/src/gallium/drivers/ilo/ilo_render_gen6.c b/src/gallium/drivers/ilo/ilo_render_gen6.c index 1414f12b439..89c87349b62 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen6.c +++ b/src/gallium/drivers/ilo/ilo_render_gen6.c @@ -413,24 +413,18 @@ gen6_draw_vf(struct ilo_render *r, { if (ilo_dev_gen(r->dev) >= ILO_GEN(7.5)) { /* 3DSTATE_INDEX_BUFFER */ - if (DIRTY(IB) || r->batch_bo_changed) { - gen6_3DSTATE_INDEX_BUFFER(r->builder, - &vec->ib, false); - } + if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_INDEX_BUFFER) || + DIRTY(IB) || r->batch_bo_changed) + gen6_3DSTATE_INDEX_BUFFER(r->builder, &vec->ve->vf, &vec->ib); /* 3DSTATE_VF */ - if (session->primitive_restart_changed) { - gen75_3DSTATE_VF(r->builder, vec->draw->primitive_restart, - vec->draw->restart_index); - } - } - else { + if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VF) + gen75_3DSTATE_VF(r->builder, &vec->ve->vf); + } else { /* 3DSTATE_INDEX_BUFFER */ - if (DIRTY(IB) || session->primitive_restart_changed || - r->batch_bo_changed) { - gen6_3DSTATE_INDEX_BUFFER(r->builder, - &vec->ib, vec->draw->primitive_restart); - } + if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_INDEX_BUFFER) || + DIRTY(IB) || r->batch_bo_changed) + gen6_3DSTATE_INDEX_BUFFER(r->builder, &vec->ve->vf, &vec->ib); } /* 3DSTATE_VERTEX_BUFFERS */ diff --git a/src/gallium/drivers/ilo/ilo_render_gen8.c b/src/gallium/drivers/ilo/ilo_render_gen8.c index 495dbc3a283..7e0d2060698 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen8.c +++ b/src/gallium/drivers/ilo/ilo_render_gen8.c @@ -202,14 +202,13 @@ gen8_draw_vf(struct ilo_render *r, int i; /* 3DSTATE_INDEX_BUFFER */ - if (DIRTY(IB) || r->batch_bo_changed) - gen8_3DSTATE_INDEX_BUFFER(r->builder, &vec->ib); + if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_INDEX_BUFFER) || + DIRTY(IB) || r->batch_bo_changed) + gen8_3DSTATE_INDEX_BUFFER(r->builder, &vec->ve->vf, &vec->ib); /* 3DSTATE_VF */ - if (session->primitive_restart_changed) { - gen75_3DSTATE_VF(r->builder, vec->draw->primitive_restart, - vec->draw->restart_index); - } + if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VF) + gen75_3DSTATE_VF(r->builder, &vec->ve->vf); /* 3DSTATE_VERTEX_BUFFERS */ if (DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed) { diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c index 0b16f3b81b9..a01e9da69ec 100644 --- a/src/gallium/drivers/ilo/ilo_state.c +++ b/src/gallium/drivers/ilo/ilo_state.c @@ -39,6 +39,19 @@ #include "ilo_shader.h" #include "ilo_state.h" +static enum gen_index_format +ilo_translate_index_size(unsigned index_size) +{ + switch (index_size) { + case 1: return GEN6_INDEX_BYTE; + case 2: return GEN6_INDEX_WORD; + case 4: return GEN6_INDEX_DWORD; + default: + assert(!"unknown index size"); + return GEN6_INDEX_BYTE; + } +} + static enum gen_mip_filter ilo_translate_mip_filter(unsigned filter) { @@ -375,6 +388,7 @@ finalize_index_buffer(struct ilo_context *ilo) if (!(vec->dirty & ILO_DIRTY_IB) && !need_upload) return; + /* make sure vec->ib.hw_resource changes when reallocated */ pipe_resource_reference(¤t_hw_res, vec->ib.hw_resource); if (need_upload) { @@ -429,8 +443,8 @@ finalize_vertex_elements(struct ilo_context *ilo) const struct ilo_dev *dev = ilo->dev; struct ilo_state_vector *vec = &ilo->state_vector; struct ilo_ve_state *ve = vec->ve; - const bool is_quad = (vec->draw->mode == PIPE_PRIM_QUADS || - vec->draw->mode == PIPE_PRIM_QUAD_STRIP); + const enum gen_3dprim_type topology = + gen6_3d_translate_pipe_prim(vec->draw->mode); const bool last_element_edge_flag = (vec->vs && ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_INPUT_EDGEFLAG)); const bool prepend_vertexid = (vec->vs && @@ -438,16 +452,24 @@ finalize_vertex_elements(struct ilo_context *ilo) const bool prepend_instanceid = (vec->vs && ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_INPUT_INSTANCEID)); + const enum gen_index_format index_format = (vec->draw->indexed) ? + ilo_translate_index_size(vec->ib.state.index_size) : GEN6_INDEX_DWORD; /* check for non-orthogonal states */ - if (ve->vf_params.cv_is_quad != is_quad || + if (ve->vf_params.cv_topology != topology || ve->vf_params.prepend_vertexid != prepend_vertexid || ve->vf_params.prepend_instanceid != prepend_instanceid || - ve->vf_params.last_element_edge_flag != last_element_edge_flag) { - ve->vf_params.cv_is_quad = is_quad; + ve->vf_params.last_element_edge_flag != last_element_edge_flag || + ve->vf_params.cv_index_format != index_format || + ve->vf_params.cut_index_enable != vec->draw->primitive_restart || + ve->vf_params.cut_index != vec->draw->restart_index) { + ve->vf_params.cv_topology = topology; ve->vf_params.prepend_vertexid = prepend_vertexid; ve->vf_params.prepend_instanceid = prepend_instanceid; ve->vf_params.last_element_edge_flag = last_element_edge_flag; + ve->vf_params.cv_index_format = index_format; + ve->vf_params.cut_index_enable = vec->draw->primitive_restart; + ve->vf_params.cut_index = vec->draw->restart_index; ilo_state_vf_set_params(&ve->vf, dev, &ve->vf_params); -- 2.30.2