/**
* Returns the greatest common divisor of a and b that is a power of two.
*/
-static inline uint64_t
+static uint64_t
gcd_pow2_u64(uint64_t a, uint64_t b)
{
assert(a > 0 || b > 0);
}
void
-genX(cmd_buffer_gpu_memcpy)(struct anv_cmd_buffer *cmd_buffer,
- struct anv_bo *dst, uint32_t dst_offset,
- struct anv_bo *src, uint32_t src_offset,
- uint32_t size)
+genX(cmd_buffer_so_memcpy)(struct anv_cmd_buffer *cmd_buffer,
+ struct anv_address dst, struct anv_address src,
+ uint32_t size)
{
if (size == 0)
return;
- assert(dst_offset + size <= dst->size);
- assert(src_offset + size <= src->size);
-
/* The maximum copy block size is 4 32-bit components at a time. */
- unsigned bs = 16;
- bs = gcd_pow2_u64(bs, src_offset);
- bs = gcd_pow2_u64(bs, dst_offset);
- bs = gcd_pow2_u64(bs, size);
+ assert(size % 4 == 0);
+ unsigned bs = gcd_pow2_u64(16, size);
enum isl_format format;
switch (bs) {
genX(cmd_buffer_config_l3)(cmd_buffer, cfg);
}
+ genX(cmd_buffer_set_binding_for_gen8_vb_flush)(cmd_buffer, 32, src, size);
genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);
genX(flush_pipeline_select_3d)(cmd_buffer);
&(struct GENX(VERTEX_BUFFER_STATE)) {
.VertexBufferIndex = 32, /* Reserved for this */
.AddressModifyEnable = true,
- .BufferStartingAddress = { src, src_offset },
+ .BufferStartingAddress = src,
.BufferPitch = bs,
+ .MOCS = anv_mocs_for_bo(cmd_buffer->device, src.bo),
#if (GEN_GEN >= 8)
- .MemoryObjectControlState = GENX(MOCS),
.BufferSize = size,
#else
- .VertexBufferMemoryObjectControlState = GENX(MOCS),
- .EndAddress = { src, src_offset + size - 1 },
+ .EndAddress = anv_address_add(src, size - 1),
#endif
});
.Component3Control = (bs >= 16) ? VFCOMP_STORE_SRC : VFCOMP_STORE_0,
});
+#if GEN_GEN >= 8
+ anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VF_INSTANCING), vfi) {
+ vfi.InstancingEnable = false;
+ vfi.VertexElementIndex = 0;
+ }
+#endif
+
#if GEN_GEN >= 8
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VF_SGVS), sgvs);
#endif
* allocate space for the VS. Even though one isn't run, we need VUEs to
* store the data that VF is going to pass to SOL.
*/
+ const unsigned entry_size[4] = { DIV_ROUND_UP(32, 64), 1, 1, 1 };
+
genX(emit_urb_setup)(cmd_buffer->device, &cmd_buffer->batch,
- VK_SHADER_STAGE_VERTEX_BIT, DIV_ROUND_UP(32, 64), 0,
- cmd_buffer->state.current_l3_config);
+ cmd_buffer->state.current_l3_config,
+ VK_SHADER_STAGE_VERTEX_BIT, entry_size, NULL);
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_SO_BUFFER), sob) {
+#if GEN_GEN < 12
sob.SOBufferIndex = 0;
- sob.SOBufferObjectControlState = GENX(MOCS);
- sob.SurfaceBaseAddress = (struct anv_address) { dst, dst_offset };
+#else
+ sob._3DCommandOpcode = 0;
+ sob._3DCommandSubOpcode = SO_BUFFER_INDEX_0_CMD;
+#endif
+ sob.MOCS = anv_mocs_for_bo(cmd_buffer->device, dst.bo),
+ sob.SurfaceBaseAddress = dst;
#if GEN_GEN >= 8
sob.SOBufferEnable = true;
- sob.SurfaceSize = size - 1;
+ sob.SurfaceSize = size / 4 - 1;
#else
sob.SurfacePitch = bs;
- sob.SurfaceEndAddress = sob.SurfaceBaseAddress;
- sob.SurfaceEndAddress.offset += size;
+ sob.SurfaceEndAddress = anv_address_add(dst, size);
#endif
#if GEN_GEN >= 8
}
#endif
+ anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VF_STATISTICS), vf) {
+ vf.StatisticsEnable = false;
+ }
+
+#if GEN_GEN >= 12
+ /* Disable Primitive Replication. */
+ anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_PRIMITIVE_REPLICATION), pr);
+#endif
+
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) {
prim.VertexAccessType = SEQUENTIAL;
prim.PrimitiveTopologyType = _3DPRIM_POINTLIST;
prim.BaseVertexLocation = 0;
}
- cmd_buffer->state.dirty |= ANV_CMD_DIRTY_PIPELINE;
+ genX(cmd_buffer_update_dirty_vbs_for_gen8_vb_flush)(cmd_buffer, SEQUENTIAL,
+ 1ull << 32);
+
+ cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_PIPELINE;
}