diff --git a/src/freedreno/vulkan/tu_acceleration_structure.cc b/src/freedreno/vulkan/tu_acceleration_structure.cc
index 061aee59b48549a8682229b96e6178f1ddbc1767..e417a4a785669b205ccea8649e22b04c1b8f5863 100644
--- a/src/freedreno/vulkan/tu_acceleration_structure.cc
+++ b/src/freedreno/vulkan/tu_acceleration_structure.cc
@@ -713,10 +713,11 @@ dump_as(struct vk_acceleration_structure *as)
    struct tu_accel_struct_header *hdr =
       (struct tu_accel_struct_header *)((char *)buf->bo->map + as->offset);
    
-   fprintf(stderr, "dumping AS at %" PRIx64 "\n", buf->iova + as->offset);
+   fprintf(stderr, "dumping AS at %" PRIx64 "\n",
+           vk_buffer_address(&buf->vk, as->offset));
    u_hexdump(stderr, (uint8_t *)hdr, sizeof(*hdr), false);
 
-   char *base = ((char *)buf->bo->map + (hdr->bvh_ptr - buf->iova));
+   char *base = ((char *)buf->bo->map + (hdr->bvh_ptr - buf->vk.device_address));
    struct tu_node *node = (struct tu_node *)base;
 
    fprintf(stderr, "dumping nodes at %" PRIx64 "\n", hdr->bvh_ptr);
@@ -746,7 +747,7 @@ as_finished(struct tu_device *dev, struct vk_acceleration_structure *as)
 
    struct tu_accel_struct_header *hdr =
       (struct tu_accel_struct_header *)((char *)buf->bo->map + as->offset);
-   return hdr->self_ptr == buf->iova + as->offset;
+   return hdr->self_ptr == vk_buffer_address(&buf->vk, as->offset);
 }
 
 VKAPI_ATTR void VKAPI_CALL
diff --git a/src/freedreno/vulkan/tu_buffer.cc b/src/freedreno/vulkan/tu_buffer.cc
index 1b87562adc33b4bb0ada00f235e274cb85396f88..8abf3bcbf4835a5b307532068c6f5c5250e111a2 100644
--- a/src/freedreno/vulkan/tu_buffer.cc
+++ b/src/freedreno/vulkan/tu_buffer.cc
@@ -57,9 +57,9 @@ tu_DestroyBuffer(VkDevice _device,
    tu_perfetto_log_destroy_buffer(device, buffer);
 #endif
 
-   if (buffer->iova)
+   if (buffer->vk.device_address)
       vk_address_binding_report(&instance->vk, &buffer->vk.base,
-                                buffer->iova, buffer->bo_size,
+                                buffer->vk.device_address, buffer->bo_size,
                                 VK_DEVICE_ADDRESS_BINDING_TYPE_UNBIND_EXT);
 
 
@@ -148,7 +148,7 @@ tu_BindBufferMemory2(VkDevice device,
 
       if (mem) {
          buffer->bo = mem->bo;
-         buffer->iova = mem->bo->iova + pBindInfos[i].memoryOffset;
+         buffer->vk.device_address = mem->bo->iova + pBindInfos[i].memoryOffset;
          if (buffer->vk.usage &
              (VK_BUFFER_USAGE_2_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT |
               VK_BUFFER_USAGE_2_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT))
@@ -170,15 +170,6 @@ tu_BindBufferMemory2(VkDevice device,
    return VK_SUCCESS;
 }
 
-VkDeviceAddress
-tu_GetBufferDeviceAddress(VkDevice _device,
-                          const VkBufferDeviceAddressInfo* pInfo)
-{
-   VK_FROM_HANDLE(tu_buffer, buffer, pInfo->buffer);
-
-   return buffer->iova;
-}
-
 uint64_t tu_GetBufferOpaqueCaptureAddress(
    VkDevice _device,
    const VkBufferDeviceAddressInfo* pInfo)
diff --git a/src/freedreno/vulkan/tu_buffer.h b/src/freedreno/vulkan/tu_buffer.h
index 2cc5d31ef6bdea2f56d418091bbffb55ae966f7f..662c38feae2bd4a9baa5baa10f01d22071a5723e 100644
--- a/src/freedreno/vulkan/tu_buffer.h
+++ b/src/freedreno/vulkan/tu_buffer.h
@@ -19,7 +19,6 @@ struct tu_buffer
    struct vk_buffer vk;
 
    struct tu_bo *bo;
-   uint64_t iova;
    uint64_t bo_size;
 };
 
diff --git a/src/freedreno/vulkan/tu_buffer_view.cc b/src/freedreno/vulkan/tu_buffer_view.cc
index 70de3f01cc4b91da7dd86c693113495dd9fda6cb..9c79b9cbbbd718e877be6125adf76f54c9bbf1ac 100644
--- a/src/freedreno/vulkan/tu_buffer_view.cc
+++ b/src/freedreno/vulkan/tu_buffer_view.cc
@@ -30,7 +30,7 @@ tu_CreateBufferView(VkDevice _device,
 
    fdl6_buffer_view_init(
       view->descriptor, vk_format_to_pipe_format(view->vk.format),
-      swiz, buffer->iova + view->vk.offset, view->vk.range);
+      swiz, vk_buffer_address(&buffer->vk, view->vk.offset), view->vk.range);
 
    *pView = tu_buffer_view_to_handle(view);
 
diff --git a/src/freedreno/vulkan/tu_clear_blit.cc b/src/freedreno/vulkan/tu_clear_blit.cc
index 2801ec4e8bd9967239d198c70d58e9dbc2634730..db79a72c885898214108508d4eec0faefa095bbd 100644
--- a/src/freedreno/vulkan/tu_clear_blit.cc
+++ b/src/freedreno/vulkan/tu_clear_blit.cc
@@ -2461,7 +2461,7 @@ tu_copy_buffer_to_image(struct tu_cmd_buffer *cmd,
    for (uint32_t i = 0; i < layers; i++) {
       ops->dst(cs, &dst, i, src_format);
 
-      uint64_t src_va = src_buffer->iova + info->bufferOffset + layer_size * i;
+      uint64_t src_va = vk_buffer_address(&src_buffer->vk, info->bufferOffset) + layer_size * i;
       bool unaligned = (src_va & 63) || (pitch & 63);
       if (!has_unaligned && unaligned) {
          for (uint32_t y = 0; y < extent.height; y++) {
@@ -2647,7 +2647,7 @@ tu_copy_image_to_buffer(struct tu_cmd_buffer *cmd,
    uint32_t layer_size = pitch * dst_height;
 
    handle_buffer_unaligned_store<CHIP>(cmd,
-                                       dst_buffer->iova + info->bufferOffset,
+                                       vk_buffer_address(&dst_buffer->vk, info->bufferOffset),
                                        layer_size * layers, unaligned_store);
 
    ops->setup(cmd, cs, src_format, dst_format, VK_IMAGE_ASPECT_COLOR_BIT, blit_param, false, false,
@@ -2660,7 +2660,7 @@ tu_copy_image_to_buffer(struct tu_cmd_buffer *cmd,
    for (uint32_t i = 0; i < layers; i++) {
       ops->src(cmd, cs, &src, i, VK_FILTER_NEAREST, dst_format);
 
-      uint64_t dst_va = dst_buffer->iova + info->bufferOffset + layer_size * i;
+      uint64_t dst_va = vk_buffer_address(&dst_buffer->vk, info->bufferOffset) + layer_size * i;
       if ((dst_va & 63) || (pitch & 63)) {
          for (uint32_t y = 0; y < extent.height; y++) {
             uint32_t x = (dst_va & 63) / util_format_get_blocksize(dst_format);
@@ -3287,9 +3287,9 @@ tu_CmdCopyBuffer2(VkCommandBuffer commandBuffer,
    for (unsigned i = 0; i < pCopyBufferInfo->regionCount; ++i) {
       const VkBufferCopy2 *region = &pCopyBufferInfo->pRegions[i];
       copy_buffer<CHIP>(cmd,
-                  dst_buffer->iova + region->dstOffset,
-                  src_buffer->iova + region->srcOffset,
-                  region->size, 1, &unaligned_store);
+                        vk_buffer_address(&dst_buffer->vk, region->dstOffset),
+                        vk_buffer_address(&src_buffer->vk, region->srcOffset),
+                        region->size, 1, &unaligned_store);
    }
 
    after_buffer_unaligned_buffer_store<CHIP>(cmd, unaligned_store);
@@ -3316,7 +3316,8 @@ tu_CmdUpdateBuffer(VkCommandBuffer commandBuffer,
 
    bool unaligned_store = false;
    memcpy(tmp.map, pData, dataSize);
-   copy_buffer<CHIP>(cmd, buffer->iova + dstOffset, tmp.iova, dataSize, 4, &unaligned_store);
+   copy_buffer<CHIP>(cmd, vk_buffer_address(&buffer->vk, dstOffset),
+                     tmp.iova, dataSize, 4, &unaligned_store);
 
    after_buffer_unaligned_buffer_store<CHIP>(cmd, unaligned_store);
 }
@@ -3387,7 +3388,7 @@ tu_CmdFillBuffer(VkCommandBuffer commandBuffer,
 
    fillSize = vk_buffer_range(&buffer->vk, dstOffset, fillSize);
 
-   VkDeviceAddress dst_va = buffer->iova + dstOffset;
+   VkDeviceAddress dst_va = vk_buffer_address(&buffer->vk, dstOffset);
 
    tu_cmd_fill_buffer<CHIP>(commandBuffer, dst_va, fillSize, data);
 }
diff --git a/src/freedreno/vulkan/tu_cmd_buffer.cc b/src/freedreno/vulkan/tu_cmd_buffer.cc
index 33d1f1fdc62f0e4c2a1cfc40b44836aa34fe78f1..b54d32133a9a26bed69b87964a703b1f0d818af8 100644
--- a/src/freedreno/vulkan/tu_cmd_buffer.cc
+++ b/src/freedreno/vulkan/tu_cmd_buffer.cc
@@ -3037,7 +3037,7 @@ tu_CmdBindVertexBuffers2(VkCommandBuffer commandBuffer,
          cmd->state.vb[firstBinding + i].size = 0;
       } else {
          struct tu_buffer *buf = tu_buffer_from_handle(pBuffers[i]);
-         cmd->state.vb[firstBinding + i].base = buf->iova + pOffsets[i];
+         cmd->state.vb[firstBinding + i].base = vk_buffer_address(&buf->vk, pOffsets[i]);
          cmd->state.vb[firstBinding + i].size =
             vk_buffer_range(&buf->vk, pOffsets[i], pSizes ? pSizes[i] : VK_WHOLE_SIZE);
       }
@@ -3089,7 +3089,7 @@ tu_CmdBindIndexBuffer2KHR(VkCommandBuffer commandBuffer,
       if (cmd->state.index_size != index_size)
          tu_cs_emit_regs(&cmd->draw_cs, A6XX_PC_RESTART_INDEX(restart_index));
 
-      cmd->state.index_va = buf->iova + offset;
+      cmd->state.index_va = vk_buffer_address(&buf->vk, offset);
       cmd->state.max_index_count = size >> index_shift;
       cmd->state.index_size = index_size;
    } else {
@@ -3600,7 +3600,7 @@ tu_CmdBindTransformFeedbackBuffersEXT(VkCommandBuffer commandBuffer,
 
    for (uint32_t i = 0; i < bindingCount; i++) {
       VK_FROM_HANDLE(tu_buffer, buf, pBuffers[i]);
-      uint64_t iova = buf->iova + pOffsets[i];
+      uint64_t iova = vk_buffer_address(&buf->vk, pOffsets[i]);
       uint32_t size = buf->bo->size - (iova - buf->bo->iova);
       uint32_t idx = i + firstBinding;
 
@@ -3655,7 +3655,7 @@ tu_CmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer,
       tu_cs_emit(cs, CP_MEM_TO_REG_0_REG(REG_A6XX_VPC_SO_BUFFER_OFFSET(idx)) |
                      CP_MEM_TO_REG_0_UNK31 |
                      CP_MEM_TO_REG_0_CNT(1));
-      tu_cs_emit_qw(cs, buf->iova + counter_buffer_offset);
+      tu_cs_emit_qw(cs, vk_buffer_address(&buf->vk, counter_buffer_offset));
 
       if (offset) {
          tu_cs_emit_pkt7(cs, CP_REG_RMW, 3);
@@ -3724,7 +3724,7 @@ tu_CmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer,
       tu_cs_emit_pkt7(cs, CP_REG_TO_MEM, 3);
       tu_cs_emit(cs, CP_REG_TO_MEM_0_REG(REG_A6XX_CP_SCRATCH_REG(0)) |
                      CP_REG_TO_MEM_0_CNT(1));
-      tu_cs_emit_qw(cs, buf->iova + counter_buffer_offset);
+      tu_cs_emit_qw(cs, vk_buffer_address(&buf->vk, counter_buffer_offset));
    }
 
    tu_cond_exec_end(cs);
@@ -6638,7 +6638,7 @@ tu_CmdDrawIndirect(VkCommandBuffer commandBuffer,
    tu_cs_emit(cs, A6XX_CP_DRAW_INDIRECT_MULTI_1_OPCODE(INDIRECT_OP_NORMAL) |
                   A6XX_CP_DRAW_INDIRECT_MULTI_1_DST_OFF(vs_params_offset(cmd)));
    tu_cs_emit(cs, drawCount);
-   tu_cs_emit_qw(cs, buf->iova + offset);
+   tu_cs_emit_qw(cs, vk_buffer_address(&buf->vk, offset));
    tu_cs_emit(cs, stride);
 }
 TU_GENX(tu_CmdDrawIndirect);
@@ -6669,7 +6669,7 @@ tu_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer,
    tu_cs_emit(cs, drawCount);
    tu_cs_emit_qw(cs, cmd->state.index_va);
    tu_cs_emit(cs, cmd->state.max_index_count);
-   tu_cs_emit_qw(cs, buf->iova + offset);
+   tu_cs_emit_qw(cs, vk_buffer_address(&buf->vk, offset));
    tu_cs_emit(cs, stride);
 }
 TU_GENX(tu_CmdDrawIndexedIndirect);
@@ -6705,8 +6705,8 @@ tu_CmdDrawIndirectCount(VkCommandBuffer commandBuffer,
    tu_cs_emit(cs, A6XX_CP_DRAW_INDIRECT_MULTI_1_OPCODE(INDIRECT_OP_INDIRECT_COUNT) |
                   A6XX_CP_DRAW_INDIRECT_MULTI_1_DST_OFF(vs_params_offset(cmd)));
    tu_cs_emit(cs, drawCount);
-   tu_cs_emit_qw(cs, buf->iova + offset);
-   tu_cs_emit_qw(cs, count_buf->iova + countBufferOffset);
+   tu_cs_emit_qw(cs, vk_buffer_address(&buf->vk, offset));
+   tu_cs_emit_qw(cs, vk_buffer_address(&count_buf->vk, countBufferOffset));
    tu_cs_emit(cs, stride);
 }
 TU_GENX(tu_CmdDrawIndirectCount);
@@ -6739,8 +6739,8 @@ tu_CmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer,
    tu_cs_emit(cs, drawCount);
    tu_cs_emit_qw(cs, cmd->state.index_va);
    tu_cs_emit(cs, cmd->state.max_index_count);
-   tu_cs_emit_qw(cs, buf->iova + offset);
-   tu_cs_emit_qw(cs, count_buf->iova + countBufferOffset);
+   tu_cs_emit_qw(cs, vk_buffer_address(&buf->vk, offset));
+   tu_cs_emit_qw(cs, vk_buffer_address(&count_buf->vk, countBufferOffset));
    tu_cs_emit(cs, stride);
 }
 TU_GENX(tu_CmdDrawIndexedIndirectCount);
@@ -6781,7 +6781,7 @@ tu_CmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer,
       vertexStride = vertexStride >> 2;
    }
    tu_cs_emit(cs, instanceCount);
-   tu_cs_emit_qw(cs, buf->iova + counterBufferOffset);
+   tu_cs_emit_qw(cs, vk_buffer_address(&buf->vk, counterBufferOffset));
    tu_cs_emit(cs, counterOffset);
    tu_cs_emit(cs, vertexStride);
 }
@@ -7336,7 +7336,7 @@ tu_CmdDispatchIndirect(VkCommandBuffer commandBuffer,
    VK_FROM_HANDLE(tu_buffer, buffer, _buffer);
    struct tu_dispatch_info info = {};
 
-   info.indirect = buffer->iova + offset;
+   info.indirect = vk_buffer_address(&buffer->vk, offset);
 
    tu_dispatch<CHIP>(cmd_buffer, &info);
 }
@@ -7663,7 +7663,7 @@ tu_CmdBeginConditionalRenderingEXT(VkCommandBuffer commandBuffer,
       tu_emit_cache_flush<CHIP>(cmd);
 
    VK_FROM_HANDLE(tu_buffer, buf, pConditionalRenderingBegin->buffer);
-   uint64_t iova = buf->iova + pConditionalRenderingBegin->offset;
+   uint64_t iova = vk_buffer_address(&buf->vk, pConditionalRenderingBegin->offset);
 
    /* qcom doesn't support 32-bit reference values, only 64-bit, but Vulkan
     * mandates 32-bit comparisons. Our workaround is to copy the the reference
@@ -7711,7 +7711,7 @@ tu_CmdWriteBufferMarker2AMD(VkCommandBuffer commandBuffer,
    VK_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer);
    VK_FROM_HANDLE(tu_buffer, buffer, dstBuffer);
 
-   uint64_t va = buffer->iova + dstOffset;
+   uint64_t va = vk_buffer_address(&buffer->vk, dstOffset);
 
    struct tu_cs *cs = cmd->state.pass ? &cmd->draw_cs : &cmd->cs;
    struct tu_cache_state *cache =
diff --git a/src/freedreno/vulkan/tu_descriptor_set.cc b/src/freedreno/vulkan/tu_descriptor_set.cc
index 8f7f266056398d1dfd9eeb791ae013d69b3b716f..01cddafc7a72ec91340564823a59aa1ed778537e 100644
--- a/src/freedreno/vulkan/tu_descriptor_set.cc
+++ b/src/freedreno/vulkan/tu_descriptor_set.cc
@@ -1007,7 +1007,7 @@ buffer_info_to_address(const VkDescriptorBufferInfo *buffer_info)
    VK_FROM_HANDLE(tu_buffer, buffer, buffer_info->buffer);
 
    uint32_t range = buffer ? vk_buffer_range(&buffer->vk, buffer_info->offset, buffer_info->range) : 0;
-   uint64_t va = buffer ? buffer->iova + buffer_info->offset : 0;
+   uint64_t va = buffer ? vk_buffer_address(&buffer->vk, buffer_info->offset) : 0;
 
    return (VkDescriptorAddressInfoEXT) {
       .address = va,
diff --git a/src/freedreno/vulkan/tu_query_pool.cc b/src/freedreno/vulkan/tu_query_pool.cc
index 963f1159e37398527f8eb3383211ae6abdfbdd00..264fc9ae3bbd0ff7a006bff584798edb1b018358 100644
--- a/src/freedreno/vulkan/tu_query_pool.cc
+++ b/src/freedreno/vulkan/tu_query_pool.cc
@@ -790,7 +790,7 @@ emit_copy_query_pool_results(struct tu_cmd_buffer *cmdbuf,
    for (uint32_t i = 0; i < queryCount; i++) {
       uint32_t query = firstQuery + i;
       uint64_t available_iova = query_available_iova(pool, query);
-      uint64_t buffer_iova = buffer->iova + dstOffset + i * stride;
+      uint64_t buffer_iova = vk_buffer_address(&buffer->vk, dstOffset) + i * stride;
       uint32_t result_count = get_result_count(pool);
       uint32_t statistics = pool->vk.pipeline_statistics;
 
diff --git a/src/freedreno/vulkan/tu_rmv.cc b/src/freedreno/vulkan/tu_rmv.cc
index d9fb381b9ba95928829dcfffb93fd4f7a344eacf..672221f663bf0e758645732087393b72bf8769e4 100644
--- a/src/freedreno/vulkan/tu_rmv.cc
+++ b/src/freedreno/vulkan/tu_rmv.cc
@@ -279,7 +279,7 @@ tu_rmv_log_buffer_bind(struct tu_device *device, struct tu_buffer *buffer)
 
    tu_rmv_emit_resource_bind_locked(device,
                                     tu_rmv_get_resource_id_locked(device, buffer),
-                                    buffer->bo ? buffer->iova : 0,
+                                    buffer->bo ? buffer->vk.device_address : 0,
                                     buffer->vk.size);
 
    simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);