[Mesa-dev] [PATCH 01/12] anv: Canonicalize known offsets

Chris Wilson chris at chris-wilson.co.uk
Sun May 14 23:38:45 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..e79d6a2a3b 100644
--- a/src/intel/vulkan/anv_batch_chain.c
+++ b/src/intel/vulkan/anv_batch_chain.c
@@ -140,6 +140,26 @@ anv_reloc_list_grow(struct anv_reloc_list *list,
    return VK_SUCCESS;
 }
 
+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);
+}
+
 VkResult
 anv_reloc_list_add(struct anv_reloc_list *list,
                    const VkAllocationCallbacks *alloc,
@@ -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