#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
}
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);
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
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;
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;
*
* "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;
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
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;
uint32_t payload[5];
};
-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,
#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,
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;
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);
/**
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;
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);
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);
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;
}
/* 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
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);
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);
}
/* 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
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;
}
}
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)
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;
}
#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"
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;