From 5a52627c4f9215649b0f244af96512b9aafceaa1 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 2 Jun 2015 14:57:48 +0800 Subject: [PATCH] ilo: embed ilo_state_vf in ilo_ve_state --- src/gallium/drivers/ilo/core/ilo_builder_3d_top.h | 78 ++++------- src/gallium/drivers/ilo/core/ilo_state_3d.h | 36 ----- src/gallium/drivers/ilo/core/ilo_state_3d_top.c | 159 ---------------------- src/gallium/drivers/ilo/ilo_blitter.h | 3 +- src/gallium/drivers/ilo/ilo_blitter_rectlist.c | 27 ++-- src/gallium/drivers/ilo/ilo_render.c | 6 + src/gallium/drivers/ilo/ilo_render_gen.h | 1 + src/gallium/drivers/ilo/ilo_render_gen6.c | 12 +- src/gallium/drivers/ilo/ilo_render_gen7.c | 2 +- src/gallium/drivers/ilo/ilo_render_gen8.c | 18 +-- src/gallium/drivers/ilo/ilo_state.c | 122 ++++++++++------- src/gallium/drivers/ilo/ilo_state.h | 12 ++ 12 files changed, 146 insertions(+), 330 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 2a475cb..a47c297 100644 --- a/src/gallium/drivers/ilo/core/ilo_builder_3d_top.h +++ b/src/gallium/drivers/ilo/core/ilo_builder_3d_top.h @@ -39,6 +39,7 @@ #include "ilo_state_sampler.h" #include "ilo_state_sol.h" #include "ilo_state_urb.h" +#include "ilo_state_vf.h" #include "ilo_builder.h" static inline void @@ -249,10 +250,10 @@ gen6_3d_translate_pipe_prim(unsigned prim) } static inline void -gen8_3DSTATE_VF_TOPOLOGY(struct ilo_builder *builder, unsigned pipe_prim) +gen8_3DSTATE_VF_TOPOLOGY(struct ilo_builder *builder, + enum gen_3dprim_type topology) { const uint8_t cmd_len = 2; - const int prim = gen6_3d_translate_pipe_prim(pipe_prim); uint32_t *dw; ILO_DEV_ASSERT(builder->dev, 8, 8); @@ -260,7 +261,7 @@ gen8_3DSTATE_VF_TOPOLOGY(struct ilo_builder *builder, unsigned pipe_prim) ilo_builder_batch_pointer(builder, cmd_len, &dw); dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_TOPOLOGY) | (cmd_len - 2); - dw[1] = prim; + dw[1] = topology << GEN8_TOPOLOGY_DW1_TYPE__SHIFT; } static inline void @@ -283,8 +284,7 @@ gen8_3DSTATE_VF_INSTANCING(struct ilo_builder *builder, static inline void gen8_3DSTATE_VF_SGVS(struct ilo_builder *builder, - bool vid_enable, int vid_ve, int vid_comp, - bool iid_enable, int iid_ve, int iid_comp) + const struct ilo_state_vf *vf) { const uint8_t cmd_len = 2; uint32_t *dw; @@ -294,25 +294,16 @@ gen8_3DSTATE_VF_SGVS(struct ilo_builder *builder, ilo_builder_batch_pointer(builder, cmd_len, &dw); dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_SGVS) | (cmd_len - 2); - dw[1] = 0; - - if (iid_enable) { - dw[1] |= GEN8_SGVS_DW1_IID_ENABLE | - vid_comp << GEN8_SGVS_DW1_IID_VE_COMP__SHIFT | - vid_ve << GEN8_SGVS_DW1_IID_VE_INDEX__SHIFT; - } - - if (vid_enable) { - dw[1] |= GEN8_SGVS_DW1_VID_ENABLE | - vid_comp << GEN8_SGVS_DW1_VID_VE_COMP__SHIFT | - vid_ve << GEN8_SGVS_DW1_VID_VE_INDEX__SHIFT; - } + /* see vf_params_set_gen8_3DSTATE_VF_SGVS() */ + dw[1] = vf->sgvs[0]; } static inline void gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder, - const struct ilo_ve_state *ve, - const struct ilo_vb_state *vb) + const struct ilo_vb_state *vb, + const unsigned *vb_mapping, + const unsigned *instance_divisors, + unsigned vb_count) { uint8_t cmd_len; uint32_t *dw; @@ -325,21 +316,21 @@ gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder, * * "From 1 to 33 VBs can be specified..." */ - assert(ve->vb_count <= 33); + assert(vb_count <= 33); - if (!ve->vb_count) + if (!vb_count) return; - cmd_len = 1 + 4 * ve->vb_count; + cmd_len = 1 + 4 * vb_count; pos = ilo_builder_batch_pointer(builder, cmd_len, &dw); dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_BUFFERS) | (cmd_len - 2); dw++; pos++; - for (hw_idx = 0; hw_idx < ve->vb_count; hw_idx++) { - const unsigned instance_divisor = ve->instance_divisors[hw_idx]; - const unsigned pipe_idx = ve->vb_mapping[hw_idx]; + 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]; dw[0] = hw_idx << GEN6_VB_DW0_INDEX__SHIFT; @@ -428,46 +419,27 @@ gen6_user_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder, static inline void gen6_3DSTATE_VERTEX_ELEMENTS(struct ilo_builder *builder, - const struct ilo_ve_state *ve) + const struct ilo_state_vf *vf) { uint8_t cmd_len; uint32_t *dw; - unsigned i; ILO_DEV_ASSERT(builder->dev, 6, 8); - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 92: - * - * "At least one VERTEX_ELEMENT_STATE structure must be included." - * - * From the Sandy Bridge PRM, volume 2 part 1, page 93: - * - * "Up to 34 (DevSNB+) vertex elements are supported." - */ - assert(ve->count + ve->prepend_nosrc_cso >= 1); - assert(ve->count + ve->prepend_nosrc_cso <= 34); - - STATIC_ASSERT(Elements(ve->cso[0].payload) == 2); + cmd_len = 1 + 2 * (vf->internal_ve_count + vf->user_ve_count); - cmd_len = 1 + 2 * (ve->count + ve->prepend_nosrc_cso); ilo_builder_batch_pointer(builder, cmd_len, &dw); dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) | (cmd_len - 2); dw++; - if (ve->prepend_nosrc_cso) { - memcpy(dw, ve->nosrc_cso.payload, sizeof(ve->nosrc_cso.payload)); - dw += 2; + /* see 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; } - - for (i = 0; i < ve->count - ve->last_cso_edgeflag; i++) { - memcpy(dw, ve->cso[i].payload, sizeof(ve->cso[i].payload)); - dw += 2; - } - - if (ve->last_cso_edgeflag) - memcpy(dw, ve->edgeflag_cso.payload, sizeof(ve->edgeflag_cso.payload)); + memcpy(dw, vf->user_ve, sizeof(vf->user_ve[0]) * vf->user_ve_count); } static inline void diff --git a/src/gallium/drivers/ilo/core/ilo_state_3d.h b/src/gallium/drivers/ilo/core/ilo_state_3d.h index 45929b2..16db93c 100644 --- a/src/gallium/drivers/ilo/core/ilo_state_3d.h +++ b/src/gallium/drivers/ilo/core/ilo_state_3d.h @@ -72,27 +72,6 @@ struct ilo_ib_state { int64_t draw_start_offset; }; -struct ilo_ve_cso { - /* VERTEX_ELEMENT_STATE */ - uint32_t payload[2]; -}; - -struct ilo_ve_state { - struct ilo_ve_cso cso[PIPE_MAX_ATTRIBS]; - unsigned count; - - unsigned instance_divisors[PIPE_MAX_ATTRIBS]; - unsigned vb_mapping[PIPE_MAX_ATTRIBS]; - unsigned vb_count; - - /* these are not valid until the state is finalized */ - struct ilo_ve_cso edgeflag_cso; - bool last_cso_edgeflag; - - struct ilo_ve_cso nosrc_cso; - bool prepend_nosrc_cso; -}; - struct ilo_so_state { struct pipe_stream_output_target *states[ILO_MAX_SO_BUFFERS]; unsigned count; @@ -139,21 +118,6 @@ struct ilo_shader_cso { }; void -ilo_gpe_init_ve(const struct ilo_dev *dev, - unsigned num_states, - const struct pipe_vertex_element *states, - struct ilo_ve_state *ve); - -void -ilo_gpe_set_ve_edgeflag(const struct ilo_dev *dev, - struct ilo_ve_cso *cso); - -void -ilo_gpe_init_ve_nosrc(const struct ilo_dev *dev, - int comp0, int comp1, int comp2, int comp3, - struct ilo_ve_cso *cso); - -void ilo_gpe_init_vs_cso(const struct ilo_dev *dev, const struct ilo_shader_state *vs, struct ilo_shader_cso *cso); diff --git a/src/gallium/drivers/ilo/core/ilo_state_3d_top.c b/src/gallium/drivers/ilo/core/ilo_state_3d_top.c index ca58f73..feac579 100644 --- a/src/gallium/drivers/ilo/core/ilo_state_3d_top.c +++ b/src/gallium/drivers/ilo/core/ilo_state_3d_top.c @@ -37,165 +37,6 @@ #include "ilo_state_3d.h" #include "../ilo_shader.h" -static void -ve_init_cso(const struct ilo_dev *dev, - const struct pipe_vertex_element *state, - unsigned vb_index, - struct ilo_ve_cso *cso) -{ - int comp[4] = { - GEN6_VFCOMP_STORE_SRC, - GEN6_VFCOMP_STORE_SRC, - GEN6_VFCOMP_STORE_SRC, - GEN6_VFCOMP_STORE_SRC, - }; - int format; - - ILO_DEV_ASSERT(dev, 6, 8); - - switch (util_format_get_nr_components(state->src_format)) { - case 1: comp[1] = GEN6_VFCOMP_STORE_0; - case 2: comp[2] = GEN6_VFCOMP_STORE_0; - case 3: comp[3] = (util_format_is_pure_integer(state->src_format)) ? - GEN6_VFCOMP_STORE_1_INT : - GEN6_VFCOMP_STORE_1_FP; - } - - format = ilo_format_translate_vertex(dev, state->src_format); - - STATIC_ASSERT(Elements(cso->payload) >= 2); - cso->payload[0] = - vb_index << GEN6_VE_DW0_VB_INDEX__SHIFT | - GEN6_VE_DW0_VALID | - format << GEN6_VE_DW0_FORMAT__SHIFT | - state->src_offset << GEN6_VE_DW0_VB_OFFSET__SHIFT; - - cso->payload[1] = - comp[0] << GEN6_VE_DW1_COMP0__SHIFT | - comp[1] << GEN6_VE_DW1_COMP1__SHIFT | - comp[2] << GEN6_VE_DW1_COMP2__SHIFT | - comp[3] << GEN6_VE_DW1_COMP3__SHIFT; -} - -void -ilo_gpe_init_ve(const struct ilo_dev *dev, - unsigned num_states, - const struct pipe_vertex_element *states, - struct ilo_ve_state *ve) -{ - unsigned i; - - ILO_DEV_ASSERT(dev, 6, 8); - - ve->count = num_states; - ve->vb_count = 0; - - for (i = 0; i < num_states; i++) { - const unsigned pipe_idx = states[i].vertex_buffer_index; - const unsigned instance_divisor = states[i].instance_divisor; - unsigned hw_idx; - - /* - * map the pipe vb to the hardware vb, which has a fixed instance - * divisor - */ - for (hw_idx = 0; hw_idx < ve->vb_count; hw_idx++) { - if (ve->vb_mapping[hw_idx] == pipe_idx && - ve->instance_divisors[hw_idx] == instance_divisor) - break; - } - - /* create one if there is no matching hardware vb */ - if (hw_idx >= ve->vb_count) { - hw_idx = ve->vb_count++; - - ve->vb_mapping[hw_idx] = pipe_idx; - ve->instance_divisors[hw_idx] = instance_divisor; - } - - ve_init_cso(dev, &states[i], hw_idx, &ve->cso[i]); - } -} - -void -ilo_gpe_set_ve_edgeflag(const struct ilo_dev *dev, - struct ilo_ve_cso *cso) -{ - int format; - - ILO_DEV_ASSERT(dev, 6, 8); - - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 94: - * - * "- This bit (Edge Flag Enable) must only be ENABLED on the last - * valid VERTEX_ELEMENT structure. - * - * - When set, Component 0 Control must be set to VFCOMP_STORE_SRC, - * and Component 1-3 Control must be set to VFCOMP_NOSTORE. - * - * - The Source Element Format must be set to the UINT format. - * - * - [DevSNB]: Edge Flags are not supported for QUADLIST - * primitives. Software may elect to convert QUADLIST primitives - * to some set of corresponding edge-flag-supported primitive - * types (e.g., POLYGONs) prior to submission to the 3D pipeline." - */ - cso->payload[0] |= GEN6_VE_DW0_EDGE_FLAG_ENABLE; - - /* - * Edge flags have format GEN6_FORMAT_R8_USCALED when defined via - * glEdgeFlagPointer(), and format GEN6_FORMAT_R32_FLOAT when defined - * via glEdgeFlag(), as can be seen in vbo_attrib_tmp.h. - * - * Since all the hardware cares about is whether the flags are zero or not, - * we can treat them as the corresponding _UINT formats. - */ - format = GEN_EXTRACT(cso->payload[0], GEN6_VE_DW0_FORMAT); - cso->payload[0] &= ~GEN6_VE_DW0_FORMAT__MASK; - - switch (format) { - case GEN6_FORMAT_R32_FLOAT: - format = GEN6_FORMAT_R32_UINT; - break; - case GEN6_FORMAT_R8_USCALED: - format = GEN6_FORMAT_R8_UINT; - break; - default: - break; - } - - cso->payload[0] |= GEN_SHIFT32(format, GEN6_VE_DW0_FORMAT); - - cso->payload[1] = - GEN6_VFCOMP_STORE_SRC << GEN6_VE_DW1_COMP0__SHIFT | - GEN6_VFCOMP_NOSTORE << GEN6_VE_DW1_COMP1__SHIFT | - GEN6_VFCOMP_NOSTORE << GEN6_VE_DW1_COMP2__SHIFT | - GEN6_VFCOMP_NOSTORE << GEN6_VE_DW1_COMP3__SHIFT; -} - -void -ilo_gpe_init_ve_nosrc(const struct ilo_dev *dev, - int comp0, int comp1, int comp2, int comp3, - struct ilo_ve_cso *cso) -{ - ILO_DEV_ASSERT(dev, 6, 8); - - STATIC_ASSERT(Elements(cso->payload) >= 2); - - assert(comp0 != GEN6_VFCOMP_STORE_SRC && - comp1 != GEN6_VFCOMP_STORE_SRC && - comp2 != GEN6_VFCOMP_STORE_SRC && - comp3 != GEN6_VFCOMP_STORE_SRC); - - cso->payload[0] = GEN6_VE_DW0_VALID; - cso->payload[1] = - comp0 << GEN6_VE_DW1_COMP0__SHIFT | - comp1 << GEN6_VE_DW1_COMP1__SHIFT | - comp2 << GEN6_VE_DW1_COMP2__SHIFT | - comp3 << GEN6_VE_DW1_COMP3__SHIFT; -} - void ilo_gpe_init_vs_cso(const struct ilo_dev *dev, const struct ilo_shader_state *vs, diff --git a/src/gallium/drivers/ilo/ilo_blitter.h b/src/gallium/drivers/ilo/ilo_blitter.h index c257c60..dd56472 100644 --- a/src/gallium/drivers/ilo/ilo_blitter.h +++ b/src/gallium/drivers/ilo/ilo_blitter.h @@ -58,9 +58,10 @@ struct ilo_blitter { bool initialized; float vertices[3][2]; - struct ilo_ve_state ve; struct pipe_draw_info draw; + uint32_t vf_data[2]; + struct ilo_state_vf vf; struct ilo_state_sol sol; struct ilo_state_viewport vp; diff --git a/src/gallium/drivers/ilo/ilo_blitter_rectlist.c b/src/gallium/drivers/ilo/ilo_blitter_rectlist.c index b106e79..ed9057a 100644 --- a/src/gallium/drivers/ilo/ilo_blitter_rectlist.c +++ b/src/gallium/drivers/ilo/ilo_blitter_rectlist.c @@ -40,30 +40,25 @@ static bool ilo_blitter_set_invariants(struct ilo_blitter *blitter) { - struct pipe_vertex_element velem; + struct ilo_state_vf_element_info elem; if (blitter->initialized) return true; - /* only vertex X and Y */ - memset(&velem, 0, sizeof(velem)); - velem.src_format = PIPE_FORMAT_R32G32_FLOAT; - ilo_gpe_init_ve(blitter->ilo->dev, 1, &velem, &blitter->ve); - - /* generate VUE header */ - ilo_gpe_init_ve_nosrc(blitter->ilo->dev, - GEN6_VFCOMP_STORE_0, /* Reserved */ - GEN6_VFCOMP_STORE_0, /* Render Target Array Index */ - GEN6_VFCOMP_STORE_0, /* Viewport Index */ - GEN6_VFCOMP_STORE_0, /* Point Width */ - &blitter->ve.nosrc_cso); - blitter->ve.prepend_nosrc_cso = true; - /* a rectangle has 3 vertices in a RECTLIST */ util_draw_init_info(&blitter->draw); blitter->draw.mode = ILO_PRIM_RECTANGLES; blitter->draw.count = 3; + memset(&elem, 0, sizeof(elem)); + /* only vertex X and Y */ + elem.format = GEN6_FORMAT_R32G32_FLOAT; + elem.format_size = 8; + elem.component_count = 2; + + ilo_state_vf_init_for_rectlist(&blitter->vf, blitter->ilo->dev, + blitter->vf_data, sizeof(blitter->vf_data), &elem, 1); + ilo_state_sol_init_disabled(&blitter->sol, blitter->ilo->dev, false); /** @@ -79,7 +74,7 @@ ilo_blitter_set_invariants(struct ilo_blitter *blitter) blitter->vp_data, sizeof(blitter->vp_data)); ilo_state_urb_init_for_rectlist(&blitter->urb, blitter->ilo->dev, - blitter->ve.count + blitter->ve.prepend_nosrc_cso); + ilo_state_vf_get_attr_count(&blitter->vf)); blitter->initialized = true; diff --git a/src/gallium/drivers/ilo/ilo_render.c b/src/gallium/drivers/ilo/ilo_render.c index 0fd19e3..c3b5372 100644 --- a/src/gallium/drivers/ilo/ilo_render.c +++ b/src/gallium/drivers/ilo/ilo_render.c @@ -449,6 +449,7 @@ draw_session_prepare(struct ilo_render *render, 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); ilo_state_raster_full_delta(&vec->rasterizer->rs, render->dev, &session->rs_delta); @@ -467,6 +468,11 @@ draw_session_prepare(struct ilo_render *render, ilo_state_urb_get_delta(&vec->urb, render->dev, &render->state.urb, &session->urb_delta); + if (vec->dirty & ILO_DIRTY_VE) { + ilo_state_vf_full_delta(&vec->ve->vf, render->dev, + &session->vf_delta); + } + if (vec->dirty & ILO_DIRTY_RASTERIZER) { ilo_state_raster_get_delta(&vec->rasterizer->rs, render->dev, &render->state.rs, &session->rs_delta); diff --git a/src/gallium/drivers/ilo/ilo_render_gen.h b/src/gallium/drivers/ilo/ilo_render_gen.h index 74c1380..439d432 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen.h +++ b/src/gallium/drivers/ilo/ilo_render_gen.h @@ -150,6 +150,7 @@ struct ilo_render_draw_session { bool primitive_restart_changed; struct ilo_state_urb_delta urb_delta; + struct ilo_state_vf_delta vf_delta; struct ilo_state_raster_delta rs_delta; struct ilo_state_viewport_delta vp_delta; struct ilo_state_cc_delta cc_delta; diff --git a/src/gallium/drivers/ilo/ilo_render_gen6.c b/src/gallium/drivers/ilo/ilo_render_gen6.c index 9d19995..7b4740e 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen6.c +++ b/src/gallium/drivers/ilo/ilo_render_gen6.c @@ -434,12 +434,14 @@ gen6_draw_vf(struct ilo_render *r, } /* 3DSTATE_VERTEX_BUFFERS */ - if (DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed) - gen6_3DSTATE_VERTEX_BUFFERS(r->builder, vec->ve, &vec->vb); + if (DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed) { + gen6_3DSTATE_VERTEX_BUFFERS(r->builder, &vec->vb, vec->ve->vb_mapping, + vec->ve->instance_divisors, vec->ve->vb_count); + } /* 3DSTATE_VERTEX_ELEMENTS */ - if (DIRTY(VE)) - gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, vec->ve); + if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS) + gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &vec->ve->vf); } void @@ -873,7 +875,7 @@ ilo_render_emit_rectlist_commands_gen6(struct ilo_render *r, session->vb_start, session->vb_end, sizeof(blitter->vertices[0])); - gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &blitter->ve); + gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &blitter->vf); gen6_3DSTATE_URB(r->builder, &blitter->urb); diff --git a/src/gallium/drivers/ilo/ilo_render_gen7.c b/src/gallium/drivers/ilo/ilo_render_gen7.c index f5c1a82..8aea76d 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen7.c +++ b/src/gallium/drivers/ilo/ilo_render_gen7.c @@ -762,7 +762,7 @@ ilo_render_emit_rectlist_commands_gen7(struct ilo_render *r, session->vb_start, session->vb_end, sizeof(blitter->vertices[0])); - gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &blitter->ve); + gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &blitter->vf); gen7_rectlist_pcb_alloc(r, blitter); diff --git a/src/gallium/drivers/ilo/ilo_render_gen8.c b/src/gallium/drivers/ilo/ilo_render_gen8.c index e0e1a85..689e698 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen8.c +++ b/src/gallium/drivers/ilo/ilo_render_gen8.c @@ -219,23 +219,25 @@ gen8_draw_vf(struct ilo_render *r, } /* 3DSTATE_VERTEX_BUFFERS */ - if (DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed) - gen6_3DSTATE_VERTEX_BUFFERS(r->builder, vec->ve, &vec->vb); + if (DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed) { + gen6_3DSTATE_VERTEX_BUFFERS(r->builder, &vec->vb, vec->ve->vb_mapping, + vec->ve->instance_divisors, vec->ve->vb_count); + } /* 3DSTATE_VERTEX_ELEMENTS */ - if (DIRTY(VE)) - gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, vec->ve); + if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS) + gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &vec->ve->vf); - gen8_3DSTATE_VF_TOPOLOGY(r->builder, vec->draw->mode); + gen8_3DSTATE_VF_TOPOLOGY(r->builder, + gen6_3d_translate_pipe_prim(vec->draw->mode)); for (i = 0; i < vec->ve->vb_count; i++) { gen8_3DSTATE_VF_INSTANCING(r->builder, i, vec->ve->instance_divisors[i]); } - gen8_3DSTATE_VF_SGVS(r->builder, - false, 0, 0, - false, 0, 0); + if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VF_SGVS) + gen8_3DSTATE_VF_SGVS(r->builder, &vec->ve->vf); } void diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c index 896402c..a164c4c 100644 --- a/src/gallium/drivers/ilo/ilo_state.c +++ b/src/gallium/drivers/ilo/ilo_state.c @@ -423,57 +423,32 @@ finalize_index_buffer(struct ilo_context *ilo) static void 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 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 && + ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_INPUT_VERTEXID)); + const bool prepend_instanceid = (vec->vs && + ilo_shader_get_kernel_param(vec->vs, + ILO_KERNEL_VS_INPUT_INSTANCEID)); - if (!(vec->dirty & (ILO_DIRTY_VE | ILO_DIRTY_VS))) - return; + /* check for non-orthogonal states */ + if (ve->vf_params.cv_is_quad != is_quad || + 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.prepend_vertexid = prepend_vertexid; + ve->vf_params.prepend_instanceid = prepend_instanceid; + ve->vf_params.last_element_edge_flag = last_element_edge_flag; - vec->dirty |= ILO_DIRTY_VE; + ilo_state_vf_set_params(&ve->vf, dev, &ve->vf_params); - vec->ve->last_cso_edgeflag = false; - if (vec->ve->count && vec->vs && - ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_INPUT_EDGEFLAG)) { - vec->ve->edgeflag_cso = vec->ve->cso[vec->ve->count - 1]; - ilo_gpe_set_ve_edgeflag(ilo->dev, &vec->ve->edgeflag_cso); - vec->ve->last_cso_edgeflag = true; - } - - vec->ve->prepend_nosrc_cso = false; - if (vec->vs && - (ilo_shader_get_kernel_param(vec->vs, - ILO_KERNEL_VS_INPUT_INSTANCEID) || - ilo_shader_get_kernel_param(vec->vs, - ILO_KERNEL_VS_INPUT_VERTEXID))) { - ilo_gpe_init_ve_nosrc(ilo->dev, - GEN6_VFCOMP_STORE_VID, - GEN6_VFCOMP_STORE_IID, - GEN6_VFCOMP_NOSTORE, - GEN6_VFCOMP_NOSTORE, - &vec->ve->nosrc_cso); - vec->ve->prepend_nosrc_cso = true; - } else if (!vec->vs) { - /* generate VUE header */ - ilo_gpe_init_ve_nosrc(ilo->dev, - GEN6_VFCOMP_STORE_0, /* Reserved */ - GEN6_VFCOMP_STORE_0, /* Render Target Array Index */ - GEN6_VFCOMP_STORE_0, /* Viewport Index */ - GEN6_VFCOMP_STORE_0, /* Point Width */ - &vec->ve->nosrc_cso); - vec->ve->prepend_nosrc_cso = true; - } else if (!vec->ve->count) { - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 92: - * - * "SW must ensure that at least one vertex element is defined prior - * to issuing a 3DPRIMTIVE command, or operation is UNDEFINED." - */ - ilo_gpe_init_ve_nosrc(ilo->dev, - GEN6_VFCOMP_STORE_0, - GEN6_VFCOMP_STORE_0, - GEN6_VFCOMP_STORE_0, - GEN6_VFCOMP_STORE_1_FP, - &vec->ve->nosrc_cso); - vec->ve->prepend_nosrc_cso = true; + vec->dirty |= ILO_DIRTY_VE; } } @@ -491,8 +466,7 @@ finalize_urb(struct ilo_context *ilo) memset(&info, 0, sizeof(info)); - info.ve_entry_size = attr_size * - (vec->ve->count + vec->ve->prepend_nosrc_cso); + info.ve_entry_size = attr_size * ilo_state_vf_get_attr_count(&vec->ve->vf); if (vec->vs) { info.vs_const_data = (bool) @@ -1319,12 +1293,58 @@ ilo_create_vertex_elements_state(struct pipe_context *pipe, const struct pipe_vertex_element *elements) { const struct ilo_dev *dev = ilo_context(pipe)->dev; + struct ilo_state_vf_element_info vf_elements[PIPE_MAX_ATTRIBS]; + struct ilo_state_vf_info vf_info; struct ilo_ve_state *ve; + unsigned i; - ve = MALLOC_STRUCT(ilo_ve_state); + ve = CALLOC_STRUCT(ilo_ve_state); assert(ve); - ilo_gpe_init_ve(dev, num_elements, elements, ve); + for (i = 0; i < num_elements; i++) { + const struct pipe_vertex_element *elem = &elements[i]; + struct ilo_state_vf_element_info *attr = &vf_elements[i]; + unsigned hw_idx; + + /* + * map the pipe vb to the hardware vb, which has a fixed instance + * divisor + */ + for (hw_idx = 0; hw_idx < ve->vb_count; hw_idx++) { + if (ve->vb_mapping[hw_idx] == elem->vertex_buffer_index && + ve->instance_divisors[hw_idx] == elem->instance_divisor) + break; + } + + /* create one if there is no matching hardware vb */ + if (hw_idx >= ve->vb_count) { + hw_idx = ve->vb_count++; + + ve->vb_mapping[hw_idx] = elem->vertex_buffer_index; + ve->instance_divisors[hw_idx] = elem->instance_divisor; + } + + attr->buffer = hw_idx; + attr->vertex_offset = elem->src_offset; + attr->format = ilo_format_translate_vertex(dev, elem->src_format); + 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); + } + + memset(&vf_info, 0, sizeof(vf_info)); + vf_info.data = ve->vf_data; + vf_info.data_size = sizeof(ve->vf_data); + vf_info.elements = vf_elements; + vf_info.element_count = num_elements; + /* vf_info.params and ve->vf_params are both zeroed */ + + if (!ilo_state_vf_init(&ve->vf, dev, &vf_info)) { + FREE(ve); + return NULL; + } return ve; } diff --git a/src/gallium/drivers/ilo/ilo_state.h b/src/gallium/drivers/ilo/ilo_state.h index 908585a..f504e07 100644 --- a/src/gallium/drivers/ilo/ilo_state.h +++ b/src/gallium/drivers/ilo/ilo_state.h @@ -35,6 +35,7 @@ #include "core/ilo_state_sol.h" #include "core/ilo_state_surface.h" #include "core/ilo_state_urb.h" +#include "core/ilo_state_vf.h" #include "core/ilo_state_viewport.h" #include "core/ilo_state_zs.h" #include "pipe/p_state.h" @@ -129,6 +130,17 @@ enum ilo_dirty_flags { struct ilo_context; +struct ilo_ve_state { + unsigned vb_mapping[PIPE_MAX_ATTRIBS]; + unsigned instance_divisors[PIPE_MAX_ATTRIBS]; + unsigned vb_count; + + /* these are not valid until the state is finalized */ + uint32_t vf_data[PIPE_MAX_ATTRIBS][2]; + struct ilo_state_vf_params_info vf_params; + struct ilo_state_vf vf; +}; + struct ilo_cbuf_cso { struct pipe_resource *resource; struct ilo_state_surface_buffer_info info; -- 2.7.4