diff options
author | Erico Nunes <ernunes@redhat.com> | 2023-12-07 10:13:24 -0500 |
---|---|---|
committer | Erico Nunes <ernunes@redhat.com> | 2023-12-07 10:13:24 -0500 |
commit | f5f610b1a785e829f2b8c2bd29e33a5bc023dfec (patch) | |
tree | c124425f5a8753fe5b64e1f89c62cc139290635d | |
parent | d3362bfa6bccb437d52ee5f03fe74930a0c2cf05 (diff) |
powervr-mesa-next-wayland-workedpowervr-mesa-next-wayland
Signed-off-by: Erico Nunes <ernunes@redhat.com>
-rw-r--r-- | src/gbm/main/gbm.c | 2 | ||||
-rw-r--r-- | src/imagination/vulkan/pvr_device.c | 102 | ||||
-rw-r--r-- | src/imagination/vulkan/pvr_formats.c | 49 | ||||
-rw-r--r-- | src/imagination/vulkan/pvr_image.c | 96 | ||||
-rw-r--r-- | src/imagination/vulkan/pvr_private.h | 1 | ||||
-rw-r--r-- | src/imagination/vulkan/winsys/pvr_winsys.h | 6 |
6 files changed, 248 insertions, 8 deletions
diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c index 599f7aae9b6..c314797e58e 100644 --- a/src/gbm/main/gbm.c +++ b/src/gbm/main/gbm.c @@ -576,10 +576,12 @@ gbm_bo_create_with_modifiers2(struct gbm_device *gbm, * * \sa enum gbm_bo_flags for the list of usage flags */ +#include <assert.h> GBM_EXPORT struct gbm_bo * gbm_bo_import(struct gbm_device *gbm, uint32_t type, void *buffer, uint32_t flags) { + assert(gbm->v0.bo_import != 0); return gbm->v0.bo_import(gbm, type, buffer, flags); } diff --git a/src/imagination/vulkan/pvr_device.c b/src/imagination/vulkan/pvr_device.c index 531e18b2aeb..7a6aaac0f13 100644 --- a/src/imagination/vulkan/pvr_device.c +++ b/src/imagination/vulkan/pvr_device.c @@ -59,6 +59,7 @@ #include "pvr_uscgen.h" #include "pvr_util.h" #include "pvr_winsys.h" +#include "pvr_winsys_helper.h" #include "rogue/rogue.h" #include "util/build_id.h" #include "util/log.h" @@ -76,6 +77,12 @@ #include "vk_sampler.h" #include "vk_util.h" +// maybe unneeded? +//#ifdef VK_USE_PLATFORM_WAYLAND_KHR +//#include <wayland-client.h> +//#include "wayland-drm-client-protocol.h" +//#endif + #define PVR_GLOBAL_FREE_LIST_INITIAL_SIZE (2U * 1024U * 1024U) #define PVR_GLOBAL_FREE_LIST_MAX_SIZE (256U * 1024U * 1024U) #define PVR_GLOBAL_FREE_LIST_GROW_SIZE (1U * 1024U * 1024U) @@ -93,7 +100,8 @@ */ #define PVR_GLOBAL_FREE_LIST_GROW_THRESHOLD 13U -#if defined(VK_USE_PLATFORM_DISPLAY_KHR) +#if defined(VK_USE_PLATFORM_DISPLAY_KHR) || \ + defined(VK_USE_PLATFORM_WAYLAND_KHR) # define PVR_USE_WSI_PLATFORM_DISPLAY true #else # define PVR_USE_WSI_PLATFORM_DISPLAY false @@ -155,6 +163,7 @@ static const struct vk_instance_extension_table pvr_instance_extensions = { .KHR_get_physical_device_properties2 = true, .KHR_get_surface_capabilities2 = PVR_USE_WSI_PLATFORM, .KHR_surface = PVR_USE_WSI_PLATFORM, + .KHR_wayland_surface = VK_USE_PLATFORM_WAYLAND_KHR, .EXT_debug_report = true, .EXT_debug_utils = true, }; @@ -188,6 +197,10 @@ static void pvr_physical_device_get_supported_extensions( .KHR_shader_float16_int8 = false, .KHR_storage_buffer_storage_class = true, .KHR_swapchain = PVR_USE_WSI_PLATFORM, +#ifdef PVR_USE_WSI_PLATFORM // needed? + .KHR_swapchain_mutable_format = true, + .KHR_incremental_present = true, +#endif .KHR_timeline_semaphore = true, .KHR_uniform_buffer_standard_layout = true, .EXT_external_memory_dma_buf = true, @@ -772,7 +785,7 @@ static VkResult pvr_physical_device_init(struct pvr_physical_device *pdevice, goto err_out; } - if (instance->vk.enabled_extensions.KHR_display) { + if (instance->vk.enabled_extensions.KHR_display || instance->vk.enabled_extensions.KHR_wayland_surface) { display_path = vk_strdup(&instance->vk.alloc, drm_display_device->nodes[DRM_NODE_PRIMARY], VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); @@ -2152,6 +2165,71 @@ VkResult pvr_EnumerateInstanceLayerProperties(uint32_t *pPropertyCount, return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT); } +static void +device_free_wsi_dumb(int32_t display_fd, int32_t dumb_handle) +{ + assert(display_fd != -1); + if (dumb_handle < 0) + return; + + struct drm_mode_destroy_dumb destroy_dumb = { + .handle = dumb_handle, + }; + if (pvr_ioctl(display_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb, VK_ERROR_UNKNOWN)) { + fprintf(stderr, "destroy dumb object %d: %s\n", dumb_handle, strerror(errno)); + } +} + +static VkResult +device_alloc_for_wsi(struct pvr_device *device, + const VkAllocationCallbacks *pAllocator, + struct pvr_device_memory *mem, + VkDeviceSize size) +{ + VkResult result; +// struct pvr_physical_device *pdevice = device->pdevice; + + struct pvr_winsys *ws = device->ws; + int display_fd = ws->display_fd; + + assert(display_fd != -1); + + mem->is_for_wsi = true; + + struct drm_mode_create_dumb create_dumb = { + .width = 1024, /* one page */ + .height = align(size, 4096) / 4096, + .bpp = util_format_get_blocksizebits(PIPE_FORMAT_RGBA8888_UNORM), + }; + + int err; + err = pvr_ioctl(display_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb, VK_ERROR_UNKNOWN); + if (err < 0) + goto fail_create; + + int fd; + err = + drmPrimeHandleToFD(display_fd, create_dumb.handle, O_CLOEXEC, &fd); + if (err < 0) + goto fail_export; + + //result = device_import_bo(device, pAllocator, fd, size, &mem->bo); + result = device->ws->ops->buffer_create_from_fd(device->ws, fd, &mem->bo); + close(fd); + if (result != VK_SUCCESS) + goto fail_import; + + mem->bo->dumb_handle = create_dumb.handle; + return VK_SUCCESS; + +fail_import: +fail_export: + device_free_wsi_dumb(display_fd, create_dumb.handle); + +fail_create: + return VK_ERROR_OUT_OF_DEVICE_MEMORY; +} + VkResult pvr_AllocateMemory(VkDevice _device, const VkMemoryAllocateInfo *pAllocateInfo, const VkAllocationCallbacks *pAllocator, @@ -2173,9 +2251,14 @@ VkResult pvr_AllocateMemory(VkDevice _device, if (!mem) return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); + mem->is_for_wsi = false; + + const struct wsi_memory_allocate_info *wsi_info = NULL; + vk_foreach_struct_const (ext, pAllocateInfo->pNext) { switch ((unsigned)ext->sType) { case VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA: + wsi_info = (void *)ext; type = PVR_WINSYS_BO_TYPE_DISPLAY; break; case VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR: @@ -2187,7 +2270,11 @@ VkResult pvr_AllocateMemory(VkDevice _device, } } - if (fd_info && fd_info->handleType) { + const VkDeviceSize alloc_size = align64(pAllocateInfo->allocationSize, 4096); + + if (wsi_info) { + result = device_alloc_for_wsi(device, pAllocator, mem, alloc_size); + } else if (fd_info && fd_info->handleType) { VkDeviceSize aligned_alloc_size = ALIGN_POT(pAllocateInfo->allocationSize, device->ws->page_size); @@ -2324,6 +2411,15 @@ void pvr_FreeMemory(VkDevice _device, device->ws->ops->buffer_destroy(mem->bo); + /* If this memory allocation was for WSI, then we need to use the + * display device to free the allocated dumb BO. + */ + if (mem->is_for_wsi) { + struct pvr_winsys *ws = device->ws; + int display_fd = ws->display_fd; + device_free_wsi_dumb(display_fd, mem->bo->dumb_handle); + } + vk_object_free(&device->vk, pAllocator, mem); } diff --git a/src/imagination/vulkan/pvr_formats.c b/src/imagination/vulkan/pvr_formats.c index 091aefd8e6f..226a0f8c924 100644 --- a/src/imagination/vulkan/pvr_formats.c +++ b/src/imagination/vulkan/pvr_formats.c @@ -44,6 +44,7 @@ #include "vk_format.h" #include "vk_log.h" #include "vk_util.h" +#include "drm-uapi/drm_fourcc.h" #define FORMAT(vk, tex_fmt, pack_mode, accum_format) \ [VK_FORMAT_##vk] = { \ @@ -816,6 +817,54 @@ void pvr_GetPhysicalDeviceFormatProperties2( vk_foreach_struct (ext, pFormatProperties->pNext) { switch (ext->sType) { + case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT: { + struct VkDrmFormatModifierPropertiesListEXT *list = (void *)ext; + VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierPropertiesEXT, out, + list->pDrmFormatModifierProperties, + &list->drmFormatModifierCount); + if (pFormatProperties->formatProperties.linearTilingFeatures) { + vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, + &out, mod_props) { + mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR; + mod_props->drmFormatModifierPlaneCount = 1; + mod_props->drmFormatModifierTilingFeatures = + pFormatProperties->formatProperties.linearTilingFeatures; + } + } + if (pFormatProperties->formatProperties.optimalTilingFeatures) { + vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, + &out, mod_props) { + mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR; // TODO + mod_props->drmFormatModifierPlaneCount = 1; + mod_props->drmFormatModifierTilingFeatures = + pFormatProperties->formatProperties.optimalTilingFeatures; + } + } + break; + } + case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT: { + struct VkDrmFormatModifierPropertiesList2EXT *list = (void *)ext; + VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierProperties2EXT, out, + list->pDrmFormatModifierProperties, + &list->drmFormatModifierCount); + if (linear2) { + vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT, + &out, mod_props) { + mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR; + mod_props->drmFormatModifierPlaneCount = 1; + mod_props->drmFormatModifierTilingFeatures = linear2; + } + } + if (optimal2) { + vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT, + &out, mod_props) { + mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR; // TODO + mod_props->drmFormatModifierPlaneCount = 1; + mod_props->drmFormatModifierTilingFeatures = optimal2; + } + } + break; + } case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3: { VkFormatProperties3 *pFormatProperties3 = (VkFormatProperties3 *)ext; pFormatProperties3->linearTilingFeatures = linear2; diff --git a/src/imagination/vulkan/pvr_image.c b/src/imagination/vulkan/pvr_image.c index 071fe60c2d3..a8edd5f7712 100644 --- a/src/imagination/vulkan/pvr_image.c +++ b/src/imagination/vulkan/pvr_image.c @@ -39,6 +39,7 @@ #include "vk_object.h" #include "vk_util.h" #include "wsi_common.h" +#include "drm-uapi/drm_fourcc.h" static void pvr_image_init_memlayout(struct pvr_image *image) { @@ -53,6 +54,7 @@ static void pvr_image_init_memlayout(struct pvr_image *image) else image->memlayout = PVR_MEMLAYOUT_TWIDDLED; break; + case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT: case VK_IMAGE_TILING_LINEAR: image->memlayout = PVR_MEMLAYOUT_LINEAR; break; @@ -141,12 +143,10 @@ static void pvr_image_setup_mip_levels(struct pvr_image *image) image->size = image->layer_size * image->vk.array_layers; } -VkResult pvr_CreateImage(VkDevice _device, - const VkImageCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator, - VkImage *pImage) +static VkResult +create_image(struct pvr_device *device, const VkImageCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkImage *pImage) { - PVR_FROM_HANDLE(pvr_device, device, _device); struct pvr_image *image; image = @@ -169,6 +169,78 @@ VkResult pvr_CreateImage(VkDevice _device, return VK_SUCCESS; } +static struct pvr_image * +pvr_wsi_get_image_from_swapchain(VkSwapchainKHR swapchain, uint32_t index) +{ + VkImage _image = wsi_common_get_image(swapchain, index); + PVR_FROM_HANDLE(pvr_image, image, _image); + return image; +} + +static VkResult +create_image_from_swapchain(struct pvr_device *device, + const VkImageCreateInfo *pCreateInfo, + const VkImageSwapchainCreateInfoKHR *swapchain_info, + const VkAllocationCallbacks *pAllocator, + VkImage *pImage) +{ + struct pvr_image *swapchain_image = + pvr_wsi_get_image_from_swapchain(swapchain_info->swapchain, 0); + assert(swapchain_image); + + VkImageCreateInfo local_create_info = *pCreateInfo; + local_create_info.pNext = NULL; + + /* Added by wsi code. */ + local_create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + + /* The spec requires TILING_OPTIMAL as input, but the swapchain image may + * privately use a different tiling. See spec anchor + * #swapchain-wsi-image-create-info . + */ + assert(local_create_info.tiling == VK_IMAGE_TILING_OPTIMAL); + local_create_info.tiling = swapchain_image->vk.tiling; + + VkImageDrmFormatModifierListCreateInfoEXT local_modifier_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT, + .drmFormatModifierCount = 1, + .pDrmFormatModifiers = &swapchain_image->vk.drm_format_mod, + }; + + if (swapchain_image->vk.drm_format_mod != DRM_FORMAT_MOD_INVALID) + __vk_append_struct(&local_create_info, &local_modifier_info); + + assert(swapchain_image->vk.image_type == local_create_info.imageType); + assert(swapchain_image->vk.format == local_create_info.format); + assert(swapchain_image->vk.extent.width == local_create_info.extent.width); + assert(swapchain_image->vk.extent.height == local_create_info.extent.height); + assert(swapchain_image->vk.extent.depth == local_create_info.extent.depth); + assert(swapchain_image->vk.array_layers == local_create_info.arrayLayers); + assert(swapchain_image->vk.samples == local_create_info.samples); + assert(swapchain_image->vk.tiling == local_create_info.tiling); + assert((swapchain_image->vk.usage & local_create_info.usage) == + local_create_info.usage); + + return create_image(device, &local_create_info, pAllocator, pImage); +} + + +VkResult pvr_CreateImage(VkDevice _device, + const VkImageCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkImage *pImage) +{ + PVR_FROM_HANDLE(pvr_device, device, _device); + const VkImageSwapchainCreateInfoKHR *swapchain_info = + vk_find_struct_const(pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR); + + if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE) + return create_image_from_swapchain(device, pCreateInfo, swapchain_info, + pAllocator, pImage); + + return create_image(device, pCreateInfo, pAllocator, pImage); +} + void pvr_DestroyImage(VkDevice _device, VkImage _image, const VkAllocationCallbacks *pAllocator) @@ -532,3 +604,17 @@ void pvr_DestroyBufferView(VkDevice _device, vk_buffer_view_destroy(&device->vk, pAllocator, &bview->vk); } + +VkResult +pvr_GetImageDrmFormatModifierPropertiesEXT( + VkDevice device, VkImage _image, + VkImageDrmFormatModifierPropertiesEXT *pProperties) +{ +// VK_FROM_HANDLE(pvr_image, image, _image); TODO + + assert(pProperties->sType == + VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT); + + pProperties->drmFormatModifier = DRM_FORMAT_MOD_LINEAR; // TODO image->pimage.layout.modifier; ?? + return VK_SUCCESS; +} diff --git a/src/imagination/vulkan/pvr_private.h b/src/imagination/vulkan/pvr_private.h index 2dc7fa033fe..e12dde3caad 100644 --- a/src/imagination/vulkan/pvr_private.h +++ b/src/imagination/vulkan/pvr_private.h @@ -285,6 +285,7 @@ struct pvr_device { struct pvr_device_memory { struct vk_object_base base; struct pvr_winsys_bo *bo; + bool is_for_wsi; }; struct pvr_mip_level { diff --git a/src/imagination/vulkan/winsys/pvr_winsys.h b/src/imagination/vulkan/winsys/pvr_winsys.h index c9faf676bde..cbb68e3d397 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys.h +++ b/src/imagination/vulkan/winsys/pvr_winsys.h @@ -119,6 +119,12 @@ struct pvr_winsys_bo { bool is_imported; + /** + * If this BO was allocated for a swapchain on the display device, the + * handle of the dumb BO on that device. + */ + int32_t dumb_handle; + #if defined(HAVE_VALGRIND) char *vbits; #endif /* defined(HAVE_VALGRIND) */ |