diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 6e86a6da06c..520101b9764 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -662,7 +662,7 @@ llvmpipe_resource_from_handle(struct pipe_screen *_screen, if (whandle->type != WINSYS_HANDLE_TYPE_UNBACKED) { void *data; #ifdef HAVE_LINUX_UDMABUF_H - struct llvmpipe_memory_fd_alloc *alloc; + struct llvmpipe_memory_allocation *alloc; uint64_t size; /* Not all winsys implement displaytarget_create_mapped so we need to check * that is available (not null). @@ -671,7 +671,7 @@ llvmpipe_resource_from_handle(struct pipe_screen *_screen, _screen->import_memory_fd(_screen, whandle->handle, (struct pipe_memory_allocation**)&alloc, &size, true)) { - data = alloc->data; + data = alloc->cpu_addr; lpr->dt = winsys->displaytarget_create_mapped(winsys, template->bind, template->format, template->width0, template->height0, whandle->stride, data); @@ -740,7 +740,7 @@ llvmpipe_resource_get_handle(struct pipe_screen *_screen, whandle->modifier = DRM_FORMAT_MOD_LINEAR; if (!lpr->dt && whandle->type == WINSYS_HANDLE_TYPE_FD) { if (!lpr->dmabuf_alloc) { - lpr->dmabuf_alloc = (struct llvmpipe_memory_fd_alloc*)_screen->allocate_memory_fd(_screen, lpr->size_required, (int*)&whandle->handle, true); + lpr->dmabuf_alloc = (struct llvmpipe_memory_allocation*)_screen->allocate_memory_fd(_screen, lpr->size_required, (int*)&whandle->handle, true); if (!lpr->dmabuf_alloc) return false; @@ -748,17 +748,17 @@ llvmpipe_resource_get_handle(struct pipe_screen *_screen, bool is_tex = llvmpipe_resource_is_texture(pt); if (is_tex) { if (lpr->tex_data) - memcpy(lpr->dmabuf_alloc->data, lpr->tex_data, lpr->size_required); + memcpy(lpr->dmabuf_alloc->cpu_addr, lpr->tex_data, lpr->size_required); } else { if (lpr->data) - memcpy(lpr->dmabuf_alloc->data, lpr->data, lpr->size_required); + memcpy(lpr->dmabuf_alloc->cpu_addr, lpr->data, lpr->size_required); } if (!lpr->imported_memory) align_free(is_tex ? lpr->tex_data : lpr->data); if (is_tex) - lpr->tex_data = lpr->dmabuf_alloc->data; + lpr->tex_data = lpr->dmabuf_alloc->cpu_addr; else - lpr->data = lpr->dmabuf_alloc->data; + lpr->data = lpr->dmabuf_alloc->cpu_addr; /* reuse lavapipe codepath to handle destruction */ lpr->backable = true; } @@ -1103,10 +1103,12 @@ llvmpipe_memory_barrier(struct pipe_context *pipe, static struct pipe_memory_allocation * llvmpipe_allocate_memory(struct pipe_screen *screen, uint64_t size) { + struct llvmpipe_memory_allocation *mem = CALLOC_STRUCT(llvmpipe_memory_allocation); uint64_t alignment; if (!os_get_page_size(&alignment)) alignment = 256; - return os_malloc_aligned(size, alignment); + mem->cpu_addr = os_malloc_aligned(size, alignment); + return (struct pipe_memory_allocation *)mem; } @@ -1121,7 +1123,7 @@ llvmpipe_free_memory(struct pipe_screen *screen, #ifdef HAVE_LINUX_UDMABUF_H static void* llvmpipe_resource_alloc_udmabuf(struct llvmpipe_screen *screen, - struct llvmpipe_memory_fd_alloc *alloc, + struct llvmpipe_memory_allocation *alloc, size_t size) { int mem_fd = -1; @@ -1188,7 +1190,7 @@ llvmpipe_allocate_memory_fd(struct pipe_screen *pscreen, int *fd, bool dmabuf) { - struct llvmpipe_memory_fd_alloc *alloc = CALLOC_STRUCT(llvmpipe_memory_fd_alloc); + struct llvmpipe_memory_allocation *alloc = CALLOC_STRUCT(llvmpipe_memory_allocation); if (!alloc) goto fail; @@ -1198,9 +1200,9 @@ llvmpipe_allocate_memory_fd(struct pipe_screen *pscreen, if (dmabuf) { struct llvmpipe_screen *screen = llvmpipe_screen(pscreen); alloc->type = LLVMPIPE_MEMORY_FD_TYPE_DMA_BUF; - alloc->data = llvmpipe_resource_alloc_udmabuf(screen, alloc, size); + alloc->cpu_addr = llvmpipe_resource_alloc_udmabuf(screen, alloc, size); - if (alloc->data) + if (alloc->cpu_addr) *fd = os_dupfd_cloexec(alloc->dmabuf_fd); } else #endif @@ -1209,11 +1211,11 @@ llvmpipe_allocate_memory_fd(struct pipe_screen *pscreen, uint64_t alignment; if (!os_get_page_size(&alignment)) alignment = 256; - alloc->data = os_malloc_aligned_fd(size, alignment, fd, + alloc->cpu_addr = os_malloc_aligned_fd(size, alignment, fd, "llvmpipe memory fd", driver_id); } - if(alloc && !alloc->data) { + if(alloc && !alloc->cpu_addr) { free(alloc); alloc = NULL; } @@ -1230,22 +1232,22 @@ llvmpipe_import_memory_fd(struct pipe_screen *screen, uint64_t *size, bool dmabuf) { - struct llvmpipe_memory_fd_alloc *alloc = CALLOC_STRUCT(llvmpipe_memory_fd_alloc); + struct llvmpipe_memory_allocation *alloc = CALLOC_STRUCT(llvmpipe_memory_allocation); alloc->mem_fd = -1; alloc->dmabuf_fd = -1; #ifdef HAVE_LINUX_UDMABUF_H if (dmabuf) { off_t mmap_size = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); - void *data = mmap(0, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (data == MAP_FAILED) { + void *cpu_addr = mmap(0, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (cpu_addr == MAP_FAILED) { free(alloc); *ptr = NULL; return false; } alloc->type = LLVMPIPE_MEMORY_FD_TYPE_DMA_BUF; - alloc->data = data; + alloc->cpu_addr = cpu_addr; alloc->size = mmap_size; alloc->dmabuf_fd = os_dupfd_cloexec(fd); *ptr = (struct pipe_memory_allocation*)alloc; @@ -1255,7 +1257,7 @@ llvmpipe_import_memory_fd(struct pipe_screen *screen, } else #endif { - bool ret = os_import_memory_fd(fd, (void**)&alloc->data, size, driver_id); + bool ret = os_import_memory_fd(fd, (void**)&alloc->cpu_addr, size, driver_id); if (!ret) { free(alloc); @@ -1274,13 +1276,13 @@ static void llvmpipe_free_memory_fd(struct pipe_screen *screen, struct pipe_memory_allocation *pmem) { - struct llvmpipe_memory_fd_alloc *alloc = (struct llvmpipe_memory_fd_alloc*)pmem; + struct llvmpipe_memory_allocation *alloc = (struct llvmpipe_memory_allocation*)pmem; if (alloc->type == LLVMPIPE_MEMORY_FD_TYPE_OPAQUE) { - os_free_fd(alloc->data); + os_free_fd(alloc->cpu_addr); } #ifdef HAVE_LINUX_UDMABUF_H else { - munmap(alloc->data, alloc->size); + munmap(alloc->cpu_addr, alloc->size); if (alloc->dmabuf_fd >= 0) close(alloc->dmabuf_fd); if (alloc->mem_fd >= 0) @@ -1293,6 +1295,20 @@ llvmpipe_free_memory_fd(struct pipe_screen *screen, #endif +static void * +llvmpipe_map_memory(struct pipe_screen *screen, + struct pipe_memory_allocation *pmem) +{ + struct llvmpipe_memory_allocation *mem = (struct llvmpipe_memory_allocation *)pmem; + return mem->cpu_addr; +} + +static void +llvmpipe_unmap_memory(struct pipe_screen *screen, + struct pipe_memory_allocation *pmem) +{ +} + static bool llvmpipe_resource_bind_backing(struct pipe_screen *pscreen, struct pipe_resource *pt, @@ -1303,14 +1319,17 @@ llvmpipe_resource_bind_backing(struct pipe_screen *pscreen, struct llvmpipe_resource *lpr = llvmpipe_resource(pt); struct sw_winsys *winsys = screen->winsys; + void *addr; if (!lpr->backable) return false; + addr = llvmpipe_map_memory(pscreen, pmem); + if (llvmpipe_resource_is_texture(&lpr->base)) { if (lpr->size_required > LP_MAX_TEXTURE_SIZE) return false; - lpr->tex_data = (char *)pmem + offset; + lpr->tex_data = (char *)addr + offset; if (lpr->dmabuf) { if (lpr->dt) @@ -1331,27 +1350,13 @@ llvmpipe_resource_bind_backing(struct pipe_screen *pscreen, } } } else - lpr->data = (char *)pmem + offset; + lpr->data = (char *)addr + offset; lpr->backing_offset = offset; return true; } -static void * -llvmpipe_map_memory(struct pipe_screen *screen, - struct pipe_memory_allocation *pmem) -{ - return pmem; -} - - -static void -llvmpipe_unmap_memory(struct pipe_screen *screen, - struct pipe_memory_allocation *pmem) -{ -} - #if MESA_DEBUG void diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h index 45e3ee96160..ebce156f33d 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.h +++ b/src/gallium/drivers/llvmpipe/lp_texture.h @@ -58,14 +58,6 @@ struct llvmpipe_screen; struct sw_displaytarget; -struct llvmpipe_memory_fd_alloc { - void *data; - enum llvmpipe_memory_fd_type type; - int mem_fd; - int dmabuf_fd; - size_t size; -}; - /** * llvmpipe subclass of pipe_resource. A texture, drawing surface, * vertex buffer, const buffer, etc. @@ -116,7 +108,7 @@ struct llvmpipe_resource uint64_t size_required; uint64_t backing_offset; #ifdef HAVE_LIBDRM - struct llvmpipe_memory_fd_alloc *dmabuf_alloc; + struct llvmpipe_memory_allocation *dmabuf_alloc; #endif bool backable; bool imported_memory; @@ -132,6 +124,14 @@ struct llvmpipe_transfer struct pipe_transfer base; }; +struct llvmpipe_memory_allocation +{ + void *cpu_addr; + uint64_t size; + enum llvmpipe_memory_fd_type type; + int mem_fd; + int dmabuf_fd; +}; struct llvmpipe_memory_object { diff --git a/src/gallium/frontends/lavapipe/lvp_descriptor_set.c b/src/gallium/frontends/lavapipe/lvp_descriptor_set.c index 1ec157d3bf1..1f41069bc42 100644 --- a/src/gallium/frontends/lavapipe/lvp_descriptor_set.c +++ b/src/gallium/frontends/lavapipe/lvp_descriptor_set.c @@ -28,6 +28,7 @@ #include "vk_util.h" #include "util/u_math.h" #include "util/u_inlines.h" +#include "lp_texture.h" static bool binding_has_immutable_samplers(const VkDescriptorSetLayoutBinding *binding) @@ -250,7 +251,12 @@ get_buffer_resource(struct pipe_context *ctx, const VkDescriptorAddressInfoEXT * uint64_t size; struct pipe_resource *pres = pscreen->resource_create_unbacked(pscreen, &templ, &size); assert(size == bda->range); - pscreen->resource_bind_backing(pscreen, pres, (void *)(uintptr_t)bda->address, 0); + + struct llvmpipe_memory_allocation alloc = { + .cpu_addr = (void *)(uintptr_t)bda->address, + }; + + pscreen->resource_bind_backing(pscreen, pres, (void *)&alloc, 0); return pres; } diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c index cf92276b054..13fabb97df0 100644 --- a/src/gallium/frontends/lavapipe/lvp_device.c +++ b/src/gallium/frontends/lavapipe/lvp_device.c @@ -1767,7 +1767,7 @@ set_mem_priority(struct lvp_device_memory *mem, int priority) if (priority > 0) advice |= MADV_WILLNEED; if (advice) - madvise(mem->pmem, mem->size, advice); + madvise(mem->map, mem->size, advice); } #endif } @@ -1844,22 +1844,25 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory( mem->memory_type = LVP_DEVICE_MEMORY_TYPE_DEFAULT; mem->backed_fd = -1; mem->size = pAllocateInfo->allocationSize; - if (host_ptr_info) { - mem->pmem = host_ptr_info->pHostPointer; + mem->mem_alloc = (struct llvmpipe_memory_allocation) { + .cpu_addr = host_ptr_info->pHostPointer, + }; + mem->pmem = (void *)&mem->mem_alloc; + mem->map = host_ptr_info->pHostPointer; mem->memory_type = LVP_DEVICE_MEMORY_TYPE_USER_PTR; } #ifdef PIPE_MEMORY_FD else if(import_info && import_info->handleType) { bool dmabuf = import_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; uint64_t size; - if(!device->pscreen->import_memory_fd(device->pscreen, import_info->fd, (struct pipe_memory_allocation**)&mem->alloc, &size, dmabuf)) { + if(!device->pscreen->import_memory_fd(device->pscreen, import_info->fd, &mem->pmem, &size, dmabuf)) { close(import_info->fd); error = VK_ERROR_INVALID_EXTERNAL_HANDLE; goto fail; } if(size < pAllocateInfo->allocationSize) { - device->pscreen->free_memory_fd(device->pscreen, (struct pipe_memory_allocation*)mem->alloc); + device->pscreen->free_memory_fd(device->pscreen, mem->pmem); close(import_info->fd); goto fail; } @@ -1871,17 +1874,17 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory( } mem->size = size; - mem->pmem = mem->alloc->data; + mem->map = device->pscreen->map_memory(device->pscreen, mem->pmem); mem->memory_type = dmabuf ? LVP_DEVICE_MEMORY_TYPE_DMA_BUF : LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD; } else if (export_info && export_info->handleTypes) { bool dmabuf = export_info->handleTypes == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; - mem->alloc = (struct llvmpipe_memory_fd_alloc*)device->pscreen->allocate_memory_fd(device->pscreen, pAllocateInfo->allocationSize, &mem->backed_fd, dmabuf); - if (!mem->alloc || mem->backed_fd < 0) { + mem->pmem = device->pscreen->allocate_memory_fd(device->pscreen, pAllocateInfo->allocationSize, &mem->backed_fd, dmabuf); + if (!mem->pmem || mem->backed_fd < 0) { goto fail; } - mem->pmem = mem->alloc->data; + mem->map = device->pscreen->map_memory(device->pscreen, mem->pmem); mem->memory_type = dmabuf ? LVP_DEVICE_MEMORY_TYPE_DMA_BUF : LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD; } #endif @@ -1890,9 +1893,11 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory( if (!mem->pmem) { goto fail; } - if (device->poison_mem) + mem->map = device->pscreen->map_memory(device->pscreen, mem->pmem); + if (device->poison_mem) { /* this is a value that will definitely break things */ - memset(mem->pmem, UINT8_MAX / 2 + 1, pAllocateInfo->allocationSize); + memset(mem->map, UINT8_MAX / 2 + 1, pAllocateInfo->allocationSize); + } set_mem_priority(mem, priority); } @@ -1918,6 +1923,9 @@ VKAPI_ATTR void VKAPI_CALL lvp_FreeMemory( if (mem == NULL) return; + if (mem->memory_type != LVP_DEVICE_MEMORY_TYPE_USER_PTR) + device->pscreen->unmap_memory(device->pscreen, mem->pmem); + switch(mem->memory_type) { case LVP_DEVICE_MEMORY_TYPE_DEFAULT: device->pscreen->free_memory(device->pscreen, mem->pmem); @@ -1925,7 +1933,7 @@ VKAPI_ATTR void VKAPI_CALL lvp_FreeMemory( #ifdef PIPE_MEMORY_FD case LVP_DEVICE_MEMORY_TYPE_DMA_BUF: case LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD: - device->pscreen->free_memory_fd(device->pscreen, (struct pipe_memory_allocation*)mem->alloc); + device->pscreen->free_memory_fd(device->pscreen, mem->pmem); if(mem->backed_fd >= 0) close(mem->backed_fd); break; @@ -1944,17 +1952,14 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_MapMemory2KHR( const VkMemoryMapInfoKHR* pMemoryMapInfo, void** ppData) { - LVP_FROM_HANDLE(lvp_device, device, _device); LVP_FROM_HANDLE(lvp_device_memory, mem, pMemoryMapInfo->memory); - void *map; + if (mem == NULL) { *ppData = NULL; return VK_SUCCESS; } - map = device->pscreen->map_memory(device->pscreen, mem->pmem); - - *ppData = (char *)map + pMemoryMapInfo->offset; + *ppData = (char *)mem->map + pMemoryMapInfo->offset; return VK_SUCCESS; } @@ -1962,13 +1967,6 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_UnmapMemory2KHR( VkDevice _device, const VkMemoryUnmapInfoKHR* pMemoryUnmapInfo) { - LVP_FROM_HANDLE(lvp_device, device, _device); - LVP_FROM_HANDLE(lvp_device_memory, mem, pMemoryUnmapInfo->memory); - - if (mem == NULL) - return VK_SUCCESS; - - device->pscreen->unmap_memory(device->pscreen, mem->pmem); return VK_SUCCESS; } @@ -2147,7 +2145,8 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_BindBufferMemory2(VkDevice _device, LVP_FROM_HANDLE(lvp_buffer, buffer, pBindInfos[i].buffer); VkBindMemoryStatusKHR *status = (void*)vk_find_struct_const(&pBindInfos[i], BIND_MEMORY_STATUS_KHR); - buffer->pmem = mem->pmem; + buffer->mem = mem; + buffer->map = (char*)mem->map + pBindInfos[i].memoryOffset; buffer->offset = pBindInfos[i].memoryOffset; device->pscreen->resource_bind_backing(device->pscreen, buffer->bo, diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index d8107d091c0..c91c524153c 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -227,7 +227,12 @@ get_buffer_resource(struct pipe_context *ctx, void *mem) uint64_t size; struct pipe_resource *pres = pscreen->resource_create_unbacked(pscreen, &templ, &size); - pscreen->resource_bind_backing(pscreen, pres, mem, 0); + + struct llvmpipe_memory_allocation alloc = { + .cpu_addr = mem, + }; + + pscreen->resource_bind_backing(pscreen, pres, (void *)&alloc, 0); return pres; } diff --git a/src/gallium/frontends/lavapipe/lvp_image.c b/src/gallium/frontends/lavapipe/lvp_image.c index 102dc08dff8..c023b9efa1f 100644 --- a/src/gallium/frontends/lavapipe/lvp_image.c +++ b/src/gallium/frontends/lavapipe/lvp_image.c @@ -560,10 +560,9 @@ VKAPI_ATTR void VKAPI_CALL lvp_DestroyBuffer( if (!_buffer) return; - char *ptr = (char*)buffer->pmem + buffer->offset; - if (ptr) { + if (buffer->map) { simple_mtx_lock(&device->bda_lock); - struct hash_entry *he = _mesa_hash_table_search(&device->bda, ptr); + struct hash_entry *he = _mesa_hash_table_search(&device->bda, buffer->map); if (he) _mesa_hash_table_remove(&device->bda, he); simple_mtx_unlock(&device->bda_lock); @@ -578,12 +577,11 @@ VKAPI_ATTR VkDeviceAddress VKAPI_CALL lvp_GetBufferDeviceAddress( { LVP_FROM_HANDLE(lvp_device, device, _device); LVP_FROM_HANDLE(lvp_buffer, buffer, pInfo->buffer); - char *ptr = (char*)buffer->pmem + buffer->offset; simple_mtx_lock(&device->bda_lock); - _mesa_hash_table_insert(&device->bda, ptr, buffer); + _mesa_hash_table_insert(&device->bda, buffer->map, buffer); simple_mtx_unlock(&device->bda_lock); - return (VkDeviceAddress)(uintptr_t)ptr; + return (VkDeviceAddress)(uintptr_t)buffer->map; } VKAPI_ATTR uint64_t VKAPI_CALL lvp_GetBufferOpaqueCaptureAddress( diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h index 85704c96491..4dadd308c9a 100644 --- a/src/gallium/frontends/lavapipe/lvp_private.h +++ b/src/gallium/frontends/lavapipe/lvp_private.h @@ -230,15 +230,13 @@ enum lvp_device_memory_type { struct lvp_device_memory { struct vk_object_base base; struct pipe_memory_allocation *pmem; + struct llvmpipe_memory_allocation mem_alloc; uint32_t type_index; VkDeviceSize map_size; VkDeviceSize size; void * map; enum lvp_device_memory_type memory_type; int backed_fd; -#ifdef PIPE_MEMORY_FD - struct llvmpipe_memory_fd_alloc *alloc; -#endif }; struct lvp_pipe_sync { @@ -579,10 +577,11 @@ struct lvp_event { struct lvp_buffer { struct vk_buffer vk; - struct pipe_memory_allocation *pmem; + struct lvp_device_memory *mem; struct pipe_resource *bo; uint64_t total_size; uint64_t offset; + void *map; }; struct lvp_buffer_view {