v3dv: implement vkMapMemory
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
parent
d1d97ea746
commit
cff9f08d31
|
@ -1053,6 +1053,79 @@ device_free(struct v3dv_device *device, struct v3dv_device_memory *mem)
|
||||||
fprintf(stderr, "close object %d: %s\n", mem->handle, strerror(errno));
|
fprintf(stderr, "close object %d: %s\n", mem->handle, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VkResult
|
||||||
|
device_map_unsynchronized(struct v3dv_device *device,
|
||||||
|
struct v3dv_device_memory *mem,
|
||||||
|
uint32_t size)
|
||||||
|
{
|
||||||
|
assert(mem != NULL && size < mem->size);
|
||||||
|
|
||||||
|
/* From the spec:
|
||||||
|
*
|
||||||
|
* "After a successful call to vkMapMemory the memory object memory is
|
||||||
|
* considered to be currently host mapped. It is an application error to
|
||||||
|
* call vkMapMemory on a memory object that is already host mapped."
|
||||||
|
*/
|
||||||
|
assert(mem->map = NULL);
|
||||||
|
|
||||||
|
struct drm_v3d_mmap_bo map;
|
||||||
|
memset(&map, 0, sizeof(map));
|
||||||
|
map.handle = mem->handle;
|
||||||
|
int ret = v3dv_ioctl(device->fd, DRM_IOCTL_V3D_MMAP_BO, &map);
|
||||||
|
if (ret != 0) {
|
||||||
|
fprintf(stderr, "map ioctl failure\n");
|
||||||
|
return VK_ERROR_MEMORY_MAP_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
mem->map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||||
|
device->fd, map.offset);
|
||||||
|
if (mem->map == MAP_FAILED) {
|
||||||
|
fprintf(stderr, "mmap of bo %d (offset 0x%016llx, size %d) failed\n",
|
||||||
|
mem->handle, (long long)map.offset, (uint32_t)mem->size);
|
||||||
|
return VK_ERROR_MEMORY_MAP_FAILED;
|
||||||
|
}
|
||||||
|
VG(VALGRIND_MALLOCLIKE_BLOCK(mem->map, mem->size, 0, false));
|
||||||
|
|
||||||
|
mem->map_size = size;
|
||||||
|
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
device_memory_wait(struct v3dv_device *device,
|
||||||
|
struct v3dv_device_memory *mem,
|
||||||
|
uint64_t timeout_ns)
|
||||||
|
{
|
||||||
|
struct drm_v3d_wait_bo wait = {
|
||||||
|
.handle = mem->handle,
|
||||||
|
.timeout_ns = timeout_ns,
|
||||||
|
};
|
||||||
|
int ret = v3dv_ioctl(device->fd, DRM_IOCTL_V3D_WAIT_BO, &wait);
|
||||||
|
if (ret == -1)
|
||||||
|
return -errno;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VkResult
|
||||||
|
device_map(struct v3dv_device *device,
|
||||||
|
struct v3dv_device_memory *mem,
|
||||||
|
uint32_t size)
|
||||||
|
{
|
||||||
|
VkResult result = device_map_unsynchronized(device, mem, size);
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
const uint64_t infinite = 0xffffffffffffffffull;
|
||||||
|
bool ok = device_memory_wait(device, mem, infinite);
|
||||||
|
if (!ok) {
|
||||||
|
fprintf(stderr, "memory wait for map failed\n");
|
||||||
|
return VK_ERROR_MEMORY_MAP_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
v3dv_AllocateMemory(VkDevice _device,
|
v3dv_AllocateMemory(VkDevice _device,
|
||||||
const VkMemoryAllocateInfo *pAllocateInfo,
|
const VkMemoryAllocateInfo *pAllocateInfo,
|
||||||
|
@ -1117,9 +1190,23 @@ v3dv_MapMemory(VkDevice _device,
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: stub */
|
assert(offset < mem->size);
|
||||||
|
|
||||||
return vk_error(device->instance, VK_ERROR_MEMORY_MAP_FAILED);
|
/* We always map from the beginning of the region, so if our offset
|
||||||
|
* is not 0 and we are not mapping the entire region, we need to
|
||||||
|
* add the offset to the map size.
|
||||||
|
*/
|
||||||
|
if (size == VK_WHOLE_SIZE)
|
||||||
|
size = mem->size;
|
||||||
|
else if (offset > 0)
|
||||||
|
size += offset;
|
||||||
|
|
||||||
|
VkResult result = device_map(device, mem, size);
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
return vk_error(device->instance, result);
|
||||||
|
|
||||||
|
*ppData = ((uint8_t *) mem->map) + offset;
|
||||||
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in New Issue