mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 04:58:05 +02:00
hk: Add virtio implicit sync support
Since we can't know what BOs are written easily, just sync against all external BOs. This should go away once we have proper fence passing support so we can do implicit sync passing in muvm-x11bridge. Signed-off-by: Asahi Lina <lina@asahilina.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32081>
This commit is contained in:
parent
1a621a6967
commit
da1601a4ec
4 changed files with 109 additions and 4 deletions
|
|
@ -452,6 +452,10 @@ hk_CreateDevice(VkPhysicalDevice physicalDevice,
|
|||
agx_scratch_init(&dev->dev, &dev->scratch.fs);
|
||||
agx_scratch_init(&dev->dev, &dev->scratch.cs);
|
||||
|
||||
u_rwlock_init(&dev->external_bos.lock);
|
||||
util_dynarray_init(&dev->external_bos.counts, NULL);
|
||||
util_dynarray_init(&dev->external_bos.list, NULL);
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
fail_mem_cache:
|
||||
|
|
@ -491,6 +495,10 @@ hk_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator)
|
|||
if (!dev)
|
||||
return;
|
||||
|
||||
util_dynarray_fini(&dev->external_bos.counts);
|
||||
util_dynarray_fini(&dev->external_bos.list);
|
||||
u_rwlock_destroy(&dev->external_bos.lock);
|
||||
|
||||
hk_device_finish_meta(dev);
|
||||
hk_destroy_internal_shaders(dev, &dev->kernels, false);
|
||||
hk_destroy_internal_shaders(dev, &dev->prolog_epilog, true);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "asahi/lib/agx_device.h"
|
||||
#include "util/rwlock.h"
|
||||
#include "util/simple_mtx.h"
|
||||
#include "util/u_dynarray.h"
|
||||
#include "agx_bg_eot.h"
|
||||
#include "agx_pack.h"
|
||||
#include "agx_scratch.h"
|
||||
|
|
@ -107,6 +109,12 @@ struct hk_device {
|
|||
} scratch;
|
||||
|
||||
uint32_t perftest;
|
||||
|
||||
struct {
|
||||
struct u_rwlock lock;
|
||||
struct util_dynarray list;
|
||||
struct util_dynarray counts;
|
||||
} external_bos;
|
||||
};
|
||||
|
||||
VK_DEFINE_HANDLE_CASTS(hk_device, vk.base, VkDevice, VK_OBJECT_TYPE_DEVICE)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,79 @@ hk_memory_type_flags(const VkMemoryType *type,
|
|||
return flags;
|
||||
}
|
||||
|
||||
static void
|
||||
hk_add_ext_bo_locked(struct hk_device *dev, struct agx_bo *bo)
|
||||
{
|
||||
uint32_t id = bo->vbo_res_id;
|
||||
|
||||
unsigned count = util_dynarray_num_elements(&dev->external_bos.list,
|
||||
struct asahi_ccmd_submit_res);
|
||||
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
struct asahi_ccmd_submit_res *p = util_dynarray_element(
|
||||
&dev->external_bos.list, struct asahi_ccmd_submit_res, i);
|
||||
|
||||
if (p->res_id == id) {
|
||||
++*util_dynarray_element(&dev->external_bos.counts, unsigned, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
struct asahi_ccmd_submit_res res = {
|
||||
.res_id = id,
|
||||
.flags = ASAHI_EXTRES_READ | ASAHI_EXTRES_WRITE,
|
||||
};
|
||||
util_dynarray_append(&dev->external_bos.list, struct asahi_ccmd_submit_res,
|
||||
res);
|
||||
util_dynarray_append(&dev->external_bos.counts, unsigned, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
hk_add_ext_bo(struct hk_device *dev, struct agx_bo *bo)
|
||||
{
|
||||
if (dev->dev.is_virtio) {
|
||||
u_rwlock_wrlock(&dev->external_bos.lock);
|
||||
hk_add_ext_bo_locked(dev, bo);
|
||||
u_rwlock_wrunlock(&dev->external_bos.lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hk_remove_ext_bo_locked(struct hk_device *dev, struct agx_bo *bo)
|
||||
{
|
||||
uint32_t id = bo->vbo_res_id;
|
||||
unsigned count = util_dynarray_num_elements(&dev->external_bos.list,
|
||||
struct asahi_ccmd_submit_res);
|
||||
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
struct asahi_ccmd_submit_res *p = util_dynarray_element(
|
||||
&dev->external_bos.list, struct asahi_ccmd_submit_res, i);
|
||||
|
||||
if (p->res_id == id) {
|
||||
unsigned *ctr =
|
||||
util_dynarray_element(&dev->external_bos.counts, unsigned, i);
|
||||
if (!--*ctr) {
|
||||
*ctr = util_dynarray_pop(&dev->external_bos.counts, unsigned);
|
||||
*p = util_dynarray_pop(&dev->external_bos.list,
|
||||
struct asahi_ccmd_submit_res);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
unreachable("BO not found");
|
||||
}
|
||||
|
||||
static void
|
||||
hk_remove_ext_bo(struct hk_device *dev, struct agx_bo *bo)
|
||||
{
|
||||
if (dev->dev.is_virtio) {
|
||||
u_rwlock_wrlock(&dev->external_bos.lock);
|
||||
hk_remove_ext_bo_locked(dev, bo);
|
||||
u_rwlock_wrunlock(&dev->external_bos.lock);
|
||||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
hk_GetMemoryFdPropertiesKHR(VkDevice device,
|
||||
VkExternalMemoryHandleTypeFlagBits handleType,
|
||||
|
|
@ -146,6 +219,9 @@ hk_AllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
|
|||
}
|
||||
}
|
||||
|
||||
if (mem->bo->flags & (AGX_BO_SHAREABLE | AGX_BO_SHARED))
|
||||
hk_add_ext_bo(dev, mem->bo);
|
||||
|
||||
if (fd_info && fd_info->handleType) {
|
||||
/* From the Vulkan spec:
|
||||
*
|
||||
|
|
@ -190,6 +266,9 @@ hk_FreeMemory(VkDevice device, VkDeviceMemory _mem,
|
|||
struct hk_memory_heap *heap = &pdev->mem_heaps[type->heapIndex];
|
||||
p_atomic_add(&heap->used, -((int64_t)mem->bo->size));
|
||||
|
||||
if (mem->bo->flags & (AGX_BO_SHAREABLE | AGX_BO_SHARED))
|
||||
hk_remove_ext_bo(dev, mem->bo);
|
||||
|
||||
agx_bo_unreference(&dev->dev, mem->bo);
|
||||
|
||||
vk_device_memory_destroy(&dev->vk, pAllocator, &mem->vk);
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ max_commands_per_submit(struct hk_device *dev)
|
|||
}
|
||||
|
||||
static VkResult
|
||||
queue_submit_single(struct agx_device *dev, struct drm_asahi_submit *submit)
|
||||
queue_submit_single(struct hk_device *dev, struct drm_asahi_submit *submit)
|
||||
{
|
||||
/* Currently we don't use the result buffer or implicit sync */
|
||||
struct agx_submit_virt virt = {
|
||||
|
|
@ -280,7 +280,17 @@ queue_submit_single(struct agx_device *dev, struct drm_asahi_submit *submit)
|
|||
.extres_count = 0,
|
||||
};
|
||||
|
||||
int ret = dev->ops.submit(dev, submit, &virt);
|
||||
if (dev->dev.is_virtio) {
|
||||
u_rwlock_rdlock(&dev->external_bos.lock);
|
||||
virt.extres_count = util_dynarray_num_elements(
|
||||
&dev->external_bos.list, struct asahi_ccmd_submit_res);
|
||||
virt.extres = util_dynarray_begin(&dev->external_bos.list);
|
||||
}
|
||||
|
||||
int ret = dev->dev.ops.submit(&dev->dev, submit, &virt);
|
||||
|
||||
if (dev->dev.is_virtio)
|
||||
u_rwlock_rdunlock(&dev->external_bos.lock);
|
||||
|
||||
/* XXX: don't trap */
|
||||
if (ret) {
|
||||
|
|
@ -348,7 +358,7 @@ queue_submit_looped(struct hk_device *dev, struct drm_asahi_submit *submit)
|
|||
.out_sync_count = last ? submit->out_sync_count : 0,
|
||||
};
|
||||
|
||||
VkResult result = queue_submit_single(&dev->dev, &submit_ioctl);
|
||||
VkResult result = queue_submit_single(dev, &submit_ioctl);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
|
|
@ -520,7 +530,7 @@ queue_submit(struct hk_device *dev, struct hk_queue *queue,
|
|||
};
|
||||
|
||||
if (command_count <= max_commands_per_submit(dev))
|
||||
return queue_submit_single(&dev->dev, &submit_ioctl);
|
||||
return queue_submit_single(dev, &submit_ioctl);
|
||||
else
|
||||
return queue_submit_looped(dev, &submit_ioctl);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue