aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/ilo/core
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2015-06-18 14:26:29 +0800
committerChia-I Wu <[email protected]>2015-06-20 11:14:14 +0800
commit4555211028394673f8ad68f3de9c12e9a1f93160 (patch)
treec9d885b73ee4253b91a4fe7e22171e76b63fc90e /src/gallium/drivers/ilo/core
parente8d297b7a108fcf1cb688fe1db89e83b8f85e091 (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.h50
-rw-r--r--src/gallium/drivers/ilo/core/ilo_state_vf.c117
-rw-r--r--src/gallium/drivers/ilo/core/ilo_state_vf.h26
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