[Mesa-dev] [PATCH 06/12] anv: Compute the target address for relocations just once

Chris Wilson chris at chris-wilson.co.uk
Sun May 14 23:38:50 UTC 2017


Compute the target address address whilst adding the relocation so that
we guarantee the value matches the relocation entry we pass to the
kernel. Pass it back from the relocation function for it to be written
into the command stream.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 src/intel/vulkan/anv_batch_chain.c | 29 ++++++++++++++++++++---------
 src/intel/vulkan/anv_private.h     |  2 +-
 src/intel/vulkan/genX_blorp_exec.c |  3 ++-
 src/intel/vulkan/genX_cmd_buffer.c |  6 ++++--
 4 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c
index 5d86472492..8edc2b521e 100644
--- a/src/intel/vulkan/anv_batch_chain.c
+++ b/src/intel/vulkan/anv_batch_chain.c
@@ -205,14 +205,23 @@ static uint64_t gen8_canonical_address(uint64_t address)
    return sign_extend(address, 47);
 }
 
+
+#define READ_ONCE(x) (*(volatile __typeof__(x) *)&(x))
+
 VkResult
 anv_reloc_list_add(struct anv_reloc_list *list,
                    const VkAllocationCallbacks *alloc,
-                   uint32_t offset, struct anv_bo *target_bo, uint32_t delta)
+                   uint32_t offset, struct anv_bo *target_bo, uint32_t delta,
+                   uint64_t *address)
 {
+   uint64_t presumed_offset = READ_ONCE(target_bo->offset);
    VkResult result;
    int index;
 
+   /* The address written into the batch must always match presumed_offset. */
+   if (address)
+      *address = gen8_canonical_address(presumed_offset + delta);
+
    /* The array of unique bo should be reasonably small */
    for (index = 0; index < list->num_bos; index++)
       if (list->bos[index] == target_bo)
@@ -243,7 +252,7 @@ anv_reloc_list_add(struct anv_reloc_list *list,
    entry->target_handle = target_bo->gem_handle;
    entry->delta = delta;
    entry->offset = offset;
-   entry->presumed_offset = target_bo->offset;
+   entry->presumed_offset = presumed_offset;
    entry->read_domains = domain;
    entry->write_domain = domain;
    VG(VALGRIND_CHECK_MEM_IS_DEFINED(entry, sizeof(*entry)));
@@ -310,14 +319,15 @@ uint64_t
 anv_batch_emit_reloc(struct anv_batch *batch,
                      void *location, struct anv_bo *bo, uint32_t delta)
 {
+   uint64_t address;
+
    VkResult result = anv_reloc_list_add(batch->relocs, batch->alloc,
-                                        location - batch->start, bo, delta);
-   if (result != VK_SUCCESS) {
+                                        location - batch->start, bo, delta,
+                                        &address);
+   if (result != VK_SUCCESS)
       anv_batch_set_error(batch, result);
-      return 0;
-   }
 
-   return gen8_canonical_address(bo->offset + delta);
+   return address;
 }
 
 void
@@ -523,9 +533,10 @@ anv_batch_bo_list_clone(const struct list_head *list,
              prev_bbo->relocs.reloc_bos[prev_bbo->relocs.num_relocs - 1] == &bbo->bo)
             prev_bbo->relocs.num_relocs--;
 
-         int reloc_size = cmd_buffer->device->info.gen < 8 ? 4 : 8;
+         const int reloc_size = cmd_buffer->device->info.gen < 8 ? 4 : 8;
          anv_reloc_list_add(&prev_bbo->relocs, &cmd_buffer->pool->alloc,
-                            prev_bbo->length - reloc_size, &new_bbo->bo, 0);
+                            prev_bbo->length - reloc_size, &new_bbo->bo, 0,
+                            NULL);
       }
 
       prev_bbo = new_bbo;
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index f1792e9692..7c9b9f3b2a 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -850,7 +850,7 @@ void anv_reloc_list_finish(struct anv_reloc_list *list,
 VkResult anv_reloc_list_add(struct anv_reloc_list *list,
                             const VkAllocationCallbacks *alloc,
                             uint32_t offset, struct anv_bo *target_bo,
-                            uint32_t delta);
+                            uint32_t delta, uint64_t *address);
 
 struct anv_batch_bo {
    /* Link in the anv_cmd_buffer.owned_batch_bos list */
diff --git a/src/intel/vulkan/genX_blorp_exec.c b/src/intel/vulkan/genX_blorp_exec.c
index 71ed70741e..ff243b1fa2 100644
--- a/src/intel/vulkan/genX_blorp_exec.c
+++ b/src/intel/vulkan/genX_blorp_exec.c
@@ -59,7 +59,8 @@ blorp_surface_reloc(struct blorp_batch *batch, uint32_t ss_offset,
    struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
    VkResult result =
       anv_reloc_list_add(&cmd_buffer->surface_relocs, &cmd_buffer->pool->alloc,
-                         ss_offset, address.buffer, address.offset + delta);
+                         ss_offset, address.buffer, address.offset + delta,
+                         NULL);
    if (result != VK_SUCCESS)
       anv_batch_set_error(&cmd_buffer->batch, result);
 }
diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c
index ef9b7d0554..ef65ffe629 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -173,7 +173,8 @@ add_surface_state_reloc(struct anv_cmd_buffer *cmd_buffer,
 
    VkResult result =
       anv_reloc_list_add(&cmd_buffer->surface_relocs, &cmd_buffer->pool->alloc,
-                         state.offset + isl_dev->ss.addr_offset, bo, offset);
+                         state.offset + isl_dev->ss.addr_offset, bo, offset,
+                         NULL);
    if (result != VK_SUCCESS)
       anv_batch_set_error(&cmd_buffer->batch, result);
 }
@@ -203,7 +204,8 @@ add_image_view_relocs(struct anv_cmd_buffer *cmd_buffer,
          anv_reloc_list_add(&cmd_buffer->surface_relocs,
                             &cmd_buffer->pool->alloc,
                             state.offset + isl_dev->ss.aux_addr_offset,
-                            iview->bo, aux_offset);
+                            iview->bo, aux_offset,
+                            NULL);
       if (result != VK_SUCCESS)
          anv_batch_set_error(&cmd_buffer->batch, result);
    }
-- 
2.11.0



More information about the mesa-dev mailing list