}
/**
- * See vf_invalidate_for_vb_48b_transitions in iris_state.c.
- * XXX: actually add this
+ * See iris_upload_render_state's IRIS_DIRTY_VERTEX_BUFFERS handling for
+ * a comment about why these VF invalidations are needed.
*/
static void
-blorp_vf_invalidate_for_vb_48b_transitions(struct blorp_batch *batch,
+blorp_vf_invalidate_for_vb_48b_transitions(struct blorp_batch *blorp_batch,
const struct blorp_address *addrs,
unsigned num_vbs)
{
-#if 0
struct iris_context *ice = blorp_batch->blorp->driver_ctx;
struct iris_batch *batch = blorp_batch->driver_batch;
bool need_invalidate = false;
if (need_invalidate) {
iris_emit_pipe_control_flush(batch, PIPE_CONTROL_VF_CACHE_INVALIDATE);
}
-#endif
}
static struct blorp_address
const unsigned vb_dwords = GENX(VERTEX_BUFFER_STATE_length);
if (cso->num_buffers > 0) {
- iris_batch_emit(batch, cso->vertex_buffers, sizeof(uint32_t) *
- (1 + vb_dwords * cso->num_buffers));
+ /* The VF cache designers cut corners, and made the cache key's
+ * <VertexBufferIndex, Memory Address> tuple only consider the bottom
+ * 32 bits of the address. If you have two vertex buffers which get
+ * placed exactly 4 GiB apart and use them in back-to-back draw calls,
+ * you can get collisions (even within a single batch).
+ *
+ * So, we need to do a VF cache invalidate if the buffer for a VB
+ * slot slot changes [48:32] address bits from the previous time.
+ */
+ bool need_invalidate = false;
for (unsigned i = 0; i < cso->num_buffers; i++) {
+ uint16_t high_bits = 0;
+
struct iris_resource *res = (void *) cso->resources[i];
- if (res)
+ if (res) {
iris_use_pinned_bo(batch, res->bo, false);
+
+ high_bits = res->bo->gtt_offset >> 32ull;
+ if (high_bits != ice->state.last_vbo_high_bits[i]) {
+ need_invalidate = true;
+ ice->state.last_vbo_high_bits[i] = high_bits;
+ }
+ }
}
+
+ if (need_invalidate) {
+ iris_emit_pipe_control_flush(batch,
+ PIPE_CONTROL_VF_CACHE_INVALIDATE);
+ }
+
+ iris_batch_emit(batch, cso->vertex_buffers, sizeof(uint32_t) *
+ (1 + vb_dwords * cso->num_buffers));
}
}
ib.BufferSize = bo->size;
ib.BufferStartingAddress = ro_bo(bo, offset);
}
+
+ /* The VF cache key only uses 32-bits, see vertex buffer comment above */
+ uint16_t high_bits = bo->gtt_offset >> 32ull;
+ if (high_bits != ice->state.last_index_bo_high_bits) {
+ iris_emit_pipe_control_flush(batch, PIPE_CONTROL_VF_CACHE_INVALIDATE);
+ ice->state.last_index_bo_high_bits = high_bits;
+ }
}
#define _3DPRIM_END_OFFSET 0x2420