summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErico Nunes <ernunes@redhat.com>2023-12-07 10:13:24 -0500
committerErico Nunes <ernunes@redhat.com>2023-12-07 10:13:24 -0500
commitf5f610b1a785e829f2b8c2bd29e33a5bc023dfec (patch)
treec124425f5a8753fe5b64e1f89c62cc139290635d
parentd3362bfa6bccb437d52ee5f03fe74930a0c2cf05 (diff)
powervr-mesa-next-wayland-workedpowervr-mesa-next-wayland
Signed-off-by: Erico Nunes <ernunes@redhat.com>
-rw-r--r--src/gbm/main/gbm.c2
-rw-r--r--src/imagination/vulkan/pvr_device.c102
-rw-r--r--src/imagination/vulkan/pvr_formats.c49
-rw-r--r--src/imagination/vulkan/pvr_image.c96
-rw-r--r--src/imagination/vulkan/pvr_private.h1
-rw-r--r--src/imagination/vulkan/winsys/pvr_winsys.h6
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) */