crocus/gen8: add support for vertex instancing and index buffers.

This ports over the VF instancing code from iris

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11507>
This commit is contained in:
Dave Airlie 2021-06-22 04:48:37 +10:00 committed by Marge Bot
parent abc990df9b
commit 515f9f5e40
1 changed files with 74 additions and 1 deletions

View File

@ -3385,7 +3385,13 @@ static uint8_t get_wa_flags(enum isl_format format)
*/
struct crocus_vertex_element_state {
uint32_t vertex_elements[1 + 33 * GENX(VERTEX_ELEMENT_STATE_length)];
#if GFX_VER == 8
uint32_t vf_instancing[33 * GENX(3DSTATE_VF_INSTANCING_length)];
#endif
uint32_t edgeflag_ve[GENX(VERTEX_ELEMENT_STATE_length)];
#if GFX_VER == 8
uint32_t edgeflag_vfi[GENX(3DSTATE_VF_INSTANCING_length)];
#endif
uint32_t step_rate[16];
uint8_t wa_flags[33];
unsigned count;
@ -3420,6 +3426,9 @@ crocus_create_vertex_elements(struct pipe_context *ctx,
}
uint32_t *ve_pack_dest = &cso->vertex_elements[1];
#if GFX_VER == 8
uint32_t *vfi_pack_dest = cso->vf_instancing;
#endif
if (count == 0) {
crocus_pack_state(GENX(VERTEX_ELEMENT_STATE), ve_pack_dest, ve) {
@ -3430,6 +3439,10 @@ crocus_create_vertex_elements(struct pipe_context *ctx,
ve.Component2Control = VFCOMP_STORE_0;
ve.Component3Control = VFCOMP_STORE_1_FP;
}
#if GFX_VER == 8
crocus_pack_command(GENX(3DSTATE_VF_INSTANCING), vfi_pack_dest, vi) {
}
#endif
}
for (int i = 0; i < count; i++) {
@ -3492,7 +3505,17 @@ crocus_create_vertex_elements(struct pipe_context *ctx,
#endif
}
#if GFX_VER == 8
crocus_pack_command(GENX(3DSTATE_VF_INSTANCING), vfi_pack_dest, vi) {
vi.VertexElementIndex = i;
vi.InstancingEnable = state[i].instance_divisor > 0;
vi.InstanceDataStepRate = state[i].instance_divisor;
}
#endif
ve_pack_dest += GENX(VERTEX_ELEMENT_STATE_length);
#if GFX_VER == 8
vfi_pack_dest += GENX(3DSTATE_VF_INSTANCING_length);
#endif
}
/* An alternative version of the last VE and VFI is stored so it
@ -3515,6 +3538,15 @@ crocus_create_vertex_elements(struct pipe_context *ctx,
ve.Component2Control = VFCOMP_STORE_0;
ve.Component3Control = VFCOMP_STORE_0;
}
#if GFX_VER == 8
crocus_pack_command(GENX(3DSTATE_VF_INSTANCING), cso->edgeflag_vfi, vi) {
/* The vi.VertexElementIndex of the EdgeFlag Vertex Element is filled
* at draw time, as it should change if SGVs are emitted.
*/
vi.InstancingEnable = state[edgeflag_index].instance_divisor > 0;
vi.InstanceDataStepRate = state[edgeflag_index].instance_divisor;
}
#endif
}
return cso;
@ -5348,18 +5380,23 @@ emit_vertex_buffer_state(struct crocus_batch *batch,
const unsigned vb_dwords = GENX(VERTEX_BUFFER_STATE_length);
_crocus_pack_state(batch, GENX(VERTEX_BUFFER_STATE), *map, vb) {
vb.BufferStartingAddress = ro_bo(bo, start_offset);
#if GFX_VER >= 8
vb.BufferSize = end_offset - start_offset;
#endif
vb.VertexBufferIndex = buffer_id;
vb.BufferPitch = stride;
#if GFX_VER == 7
#if GFX_VER >= 7
vb.AddressModifyEnable = true;
#endif
#if GFX_VER >= 6
vb.MOCS = crocus_mocs(bo, &batch->screen->isl_dev);
#endif
#if GFX_VER < 8
vb.BufferAccessType = step_rate ? INSTANCEDATA : VERTEXDATA;
vb.InstanceDataStepRate = step_rate;
#if GFX_VER >= 5
vb.EndAddress = ro_bo(bo, end_offset - 1);
#endif
#endif
}
*map += vb_dwords;
@ -6985,8 +7022,13 @@ crocus_upload_dirty_render_state(struct crocus_context *ice,
ve.SourceElementFormat = ISL_FORMAT_R32G32_UINT;
ve.Component0Control = base_ctrl;
ve.Component1Control = base_ctrl;
#if GFX_VER < 8
ve.Component2Control = ice->state.vs_uses_vertexid ? VFCOMP_STORE_VID : VFCOMP_STORE_0;
ve.Component3Control = ice->state.vs_uses_instanceid ? VFCOMP_STORE_IID : VFCOMP_STORE_0;
#else
ve.Component2Control = VFCOMP_STORE_0;
ve.Component3Control = VFCOMP_STORE_0;
#endif
#if GFX_VER < 5
ve.DestinationElementOffset = cso->count * 4;
#endif
@ -7018,6 +7060,32 @@ crocus_upload_dirty_render_state(struct crocus_context *ice,
crocus_batch_emit(batch, &dynamic_ves, sizeof(uint32_t) *
(1 + dyn_count * GENX(VERTEX_ELEMENT_STATE_length)));
}
#if GFX_VER == 8
if (!ice->state.vs_needs_edge_flag) {
crocus_batch_emit(batch, cso->vf_instancing, sizeof(uint32_t) *
entries * GENX(3DSTATE_VF_INSTANCING_length));
} else {
assert(cso->count > 0);
const unsigned edgeflag_index = cso->count - 1;
uint32_t dynamic_vfi[33 * GENX(3DSTATE_VF_INSTANCING_length)];
memcpy(&dynamic_vfi[0], cso->vf_instancing, edgeflag_index *
GENX(3DSTATE_VF_INSTANCING_length) * sizeof(uint32_t));
uint32_t *vfi_pack_dest = &dynamic_vfi[0] +
edgeflag_index * GENX(3DSTATE_VF_INSTANCING_length);
crocus_pack_command(GENX(3DSTATE_VF_INSTANCING), vfi_pack_dest, vi) {
vi.VertexElementIndex = edgeflag_index +
ice->state.vs_needs_sgvs_element +
ice->state.vs_uses_derived_draw_params;
}
for (int i = 0; i < GENX(3DSTATE_VF_INSTANCING_length); i++)
vfi_pack_dest[i] |= cso->edgeflag_vfi[i];
crocus_batch_emit(batch, &dynamic_vfi[0], sizeof(uint32_t) *
entries * GENX(3DSTATE_VF_INSTANCING_length));
}
#endif
}
#if GFX_VERx10 >= 75
@ -7102,7 +7170,12 @@ crocus_upload_render_state(struct crocus_context *ice,
#endif
ib.IndexFormat = draw->index_size >> 1;
ib.BufferStartingAddress = ro_bo(bo, offset);
#if GFX_VER >= 8
ib.MOCS = crocus_mocs(bo, &batch->screen->isl_dev);
ib.BufferSize = bo->size - offset;
#else
ib.BufferEndingAddress = ro_bo(bo, offset + size - 1);
#endif
}
ice->state.index_buffer.size = size;
ice->state.index_buffer.offset = offset;