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;
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
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;
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;
}
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);
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;
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;
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,
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);
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) {
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;
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
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;
+ }
}
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),
};
/**
* 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;
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;
uint32_t last_user_ve[2][2];
bool edge_flag_supported;
+
+ uint32_t cut[2];
};
struct ilo_state_vf_delta {
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,
#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)
#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
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);
} 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);
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;
*/
uint32_t deferred_pipe_control_dw1;
- bool primitive_restart;
int reduced_prim;
int so_max_vertices;
int reduced_prim;
bool prim_changed;
- bool primitive_restart_changed;
struct ilo_state_urb_delta urb_delta;
struct ilo_state_vf_delta vf_delta;
{
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 */
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) {
#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)
{
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) {
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 &&
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);