[Mesa-dev] [PATCH 1/4] anv: Canonicalize known offsets

Chris Wilson chris at chris-wilson.co.uk
Thu May 11 13:13:10 UTC 2017


When we add the reloc, we write the value of the relocation target using
non-canonical form. If we later patch up the address prior to command
submission, we will rewrite it using canonical form. We should always
write the address in canonical form in case we skip the relocation (as
the target did not move since creation of the relocation).

v2: Rebuild reloc_size lost in collateral damage.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Jason Ekstrand <jason.ekstrand at intel.com>
Cc: Grazvydas Ignotas <notasas at gmail.com>
---
 src/intel/vulkan/anv_batch_chain.c | 34 ++++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c
index 9def174b42..45952da012 100644
--- a/src/intel/vulkan/anv_batch_chain.c
+++ b/src/intel/vulkan/anv_batch_chain.c
@@ -214,6 +214,26 @@ anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords)
    return p;
 }
 
+static inline uint64_t sign_extend(uint64_t value, int index)
+{
+   int shift = 63 - index;
+   return (int64_t)(value << shift) >> shift;
+}
+
+static uint64_t gen8_canonical_address(uint64_t address)
+{
+   /* From the Broadwell PRM Vol. 2a, MI_LOAD_REGISTER_MEM::MemoryAddress:
+    *
+    *    "This field specifies the address of the memory location where the
+    *    register value specified in the DWord above will read from. The
+    *    address specifies the DWord location of the data. Range =
+    *    GraphicsVirtualAddress[63:2] for a DWord register GraphicsAddress
+    *    [63:48] are ignored by the HW and assumed to be in correct
+    *    canonical form [63:48] == [47]."
+    */
+   return sign_extend(address, 47);
+}
+
 uint64_t
 anv_batch_emit_reloc(struct anv_batch *batch,
                      void *location, struct anv_bo *bo, uint32_t delta)
@@ -225,7 +245,7 @@ anv_batch_emit_reloc(struct anv_batch *batch,
       return 0;
    }
 
-   return bo->offset + delta;
+   return gen8_canonical_address(bo->offset + delta);
 }
 
 void
@@ -1076,18 +1096,8 @@ write_reloc(const struct anv_device *device, void *p, uint64_t v, bool flush)
 {
    unsigned reloc_size = 0;
    if (device->info.gen >= 8) {
-      /* From the Broadwell PRM Vol. 2a, MI_LOAD_REGISTER_MEM::MemoryAddress:
-       *
-       *    "This field specifies the address of the memory location where the
-       *    register value specified in the DWord above will read from. The
-       *    address specifies the DWord location of the data. Range =
-       *    GraphicsVirtualAddress[63:2] for a DWord register GraphicsAddress
-       *    [63:48] are ignored by the HW and assumed to be in correct
-       *    canonical form [63:48] == [47]."
-       */
-      const int shift = 63 - 47;
       reloc_size = sizeof(uint64_t);
-      *(uint64_t *)p = (((int64_t)v) << shift) >> shift;
+      *(uint64_t *)p = gen8_canonical_address(v);
    } else {
       reloc_size = sizeof(uint32_t);
       *(uint32_t *)p = v;
-- 
2.11.0



More information about the mesa-dev mailing list