1*4882a593SmuzhiyunFrom 08d6a8d2e5e16d4a15cb58871c591adec0691ee8 Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Jeffy Chen <jeffy.chen@rock-chips.com> 3*4882a593SmuzhiyunDate: Mon, 23 May 2022 10:57:27 +0800 4*4882a593SmuzhiyunSubject: [PATCH 2/3] kms: Drop dependency on vkCreateDmaBufImageINTEL 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunBased on chromium's gpu/vulkan/vulkan_image{_linux,}.cc 7*4882a593Smuzhiyun 8*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 9*4882a593Smuzhiyun--- 10*4882a593Smuzhiyun meson.build | 7 +- 11*4882a593Smuzhiyun src/ws/kms_window_system.cpp | 172 ++++++++++++++++++++++++++--------- 12*4882a593Smuzhiyun src/ws/kms_window_system.h | 1 - 13*4882a593Smuzhiyun 3 files changed, 130 insertions(+), 50 deletions(-) 14*4882a593Smuzhiyun 15*4882a593Smuzhiyundiff --git a/meson.build b/meson.build 16*4882a593Smuzhiyunindex 7d305dc..0d83918 100644 17*4882a593Smuzhiyun--- a/meson.build 18*4882a593Smuzhiyun+++ b/meson.build 19*4882a593Smuzhiyun@@ -32,16 +32,11 @@ wayland_protocols_dep = dependency('wayland-protocols', version : '>= 1.12', 20*4882a593Smuzhiyun wayland_scanner_dep = dependency('wayland-scanner', required : get_option('wayland') == 'true') 21*4882a593Smuzhiyun libdrm_dep = dependency('libdrm', required : get_option('kms') == 'true') 22*4882a593Smuzhiyun gbm_dep = dependency('gbm', required : get_option('kms') == 'true') 23*4882a593Smuzhiyun-has_vulkan_intel_header = cpp.has_header('vulkan/vulkan_intel.h', dependencies: vulkan_dep) 24*4882a593Smuzhiyun- 25*4882a593Smuzhiyun-if get_option('kms') == 'true' and not has_vulkan_intel_header 26*4882a593Smuzhiyun- error('KMS plugin needs the vulkan_intel.h header, but it couldn\'t be found') 27*4882a593Smuzhiyun-endif 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun build_xcb_ws = xcb_dep.found() and xcb_icccm_dep.found() and get_option('xcb') != 'false' 30*4882a593Smuzhiyun build_wayland_ws = (wayland_client_dep.found() and wayland_protocols_dep.found() and 31*4882a593Smuzhiyun wayland_scanner_dep.found() and get_option('wayland') != 'false') 32*4882a593Smuzhiyun-build_kms_ws = libdrm_dep.found() and gbm_dep.found() and has_vulkan_intel_header and get_option('kms') != 'false' 33*4882a593Smuzhiyun+build_kms_ws = libdrm_dep.found() and gbm_dep.found() and get_option('kms') != 'false' 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun if not build_xcb_ws and not build_wayland_ws and not build_kms_ws 36*4882a593Smuzhiyun error('vkmark needs at least one winsys to work - xcb, wayland or kms') 37*4882a593Smuzhiyundiff --git a/src/ws/kms_window_system.cpp b/src/ws/kms_window_system.cpp 38*4882a593Smuzhiyunindex ca8220f..66618f6 100644 39*4882a593Smuzhiyun--- a/src/ws/kms_window_system.cpp 40*4882a593Smuzhiyun+++ b/src/ws/kms_window_system.cpp 41*4882a593Smuzhiyun@@ -29,7 +29,6 @@ 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun #include <xf86drm.h> 44*4882a593Smuzhiyun #include <drm_fourcc.h> 45*4882a593Smuzhiyun-#include <vulkan/vulkan_intel.h> 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun #include <system_error> 48*4882a593Smuzhiyun #include <fcntl.h> 49*4882a593Smuzhiyun@@ -352,7 +351,6 @@ void KMSWindowSystem::init_vulkan(VulkanState& vulkan_) 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun vk_image_format = vk::Format::eB8G8R8A8Srgb; 52*4882a593Smuzhiyun create_gbm_bos(); 53*4882a593Smuzhiyun- create_drm_fbs(); 54*4882a593Smuzhiyun create_vk_images(); 55*4882a593Smuzhiyun } 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun@@ -428,68 +426,122 @@ void KMSWindowSystem::create_gbm_bos() 58*4882a593Smuzhiyun } 59*4882a593Smuzhiyun } 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun-void KMSWindowSystem::create_drm_fbs() 62*4882a593Smuzhiyun-{ 63*4882a593Smuzhiyun- for (auto const& gbm_bo : gbm_bos) 64*4882a593Smuzhiyun- { 65*4882a593Smuzhiyun- uint32_t fb = 0; 66*4882a593Smuzhiyun- 67*4882a593Smuzhiyun- uint32_t handles[4] = {gbm_bo_get_handle(gbm_bo).u32, 0, 0, 0}; 68*4882a593Smuzhiyun- uint32_t strides[4] = {gbm_bo_get_stride(gbm_bo), 0, 0, 0}; 69*4882a593Smuzhiyun- uint32_t offsets[4] = {0, 0, 0, 0}; 70*4882a593Smuzhiyun- 71*4882a593Smuzhiyun- auto const ret = drmModeAddFB2( 72*4882a593Smuzhiyun- drm_fd, vk_extent.width, vk_extent.height, 73*4882a593Smuzhiyun- DRM_FORMAT_XRGB8888, 74*4882a593Smuzhiyun- handles, strides, offsets, &fb, 0); 75*4882a593Smuzhiyun- 76*4882a593Smuzhiyun- if (ret < 0) 77*4882a593Smuzhiyun- throw std::system_error{-ret, std::system_category(), "Failed to add drm fb"}; 78*4882a593Smuzhiyun+// TODO: Use an official extension to create the VkImages when it becomes 79*4882a593Smuzhiyun+// available (e.g. VK_MESAX_external_image_dma_buf) 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun- drm_fbs.push_back( 82*4882a593Smuzhiyun- ManagedResource<uint32_t>{ 83*4882a593Smuzhiyun- std::move(fb), 84*4882a593Smuzhiyun- [this] (auto& fb) { drmModeRmFB(drm_fd, fb); }}); 85*4882a593Smuzhiyun+static int find_memory_type_index(VkPhysicalDevice physical_device, 86*4882a593Smuzhiyun+ const VkMemoryRequirements* requirements, 87*4882a593Smuzhiyun+ VkMemoryPropertyFlags flags) { 88*4882a593Smuzhiyun+ VkPhysicalDeviceMemoryProperties properties; 89*4882a593Smuzhiyun+ vkGetPhysicalDeviceMemoryProperties(physical_device, &properties); 90*4882a593Smuzhiyun+ for (int i = 0; i <= 31; i++) { 91*4882a593Smuzhiyun+ if (((1u << i) & requirements->memoryTypeBits) == 0) 92*4882a593Smuzhiyun+ continue; 93*4882a593Smuzhiyun+ if ((properties.memoryTypes[i].propertyFlags & flags) != flags) 94*4882a593Smuzhiyun+ continue; 95*4882a593Smuzhiyun+ return i; 96*4882a593Smuzhiyun } 97*4882a593Smuzhiyun+ return -1; 98*4882a593Smuzhiyun } 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun-// TODO: Use an official extension to create the VkImages when it becomes 101*4882a593Smuzhiyun-// available (e.g. VK_MESAX_external_image_dma_buf) 102*4882a593Smuzhiyun void KMSWindowSystem::create_vk_images() 103*4882a593Smuzhiyun { 104*4882a593Smuzhiyun- auto const create_dma_buf_image = 105*4882a593Smuzhiyun- reinterpret_cast<PFN_vkCreateDmaBufImageINTEL>( 106*4882a593Smuzhiyun- vulkan->device().getProcAddr("vkCreateDmaBufImageINTEL")); 107*4882a593Smuzhiyun- 108*4882a593Smuzhiyun- if (!create_dma_buf_image) 109*4882a593Smuzhiyun- throw std::runtime_error{"Failed to get vkCreateDmaBufImageINTEL function pointer"}; 110*4882a593Smuzhiyun- 111*4882a593Smuzhiyun for (auto const& gbm_bo : gbm_bos) 112*4882a593Smuzhiyun { 113*4882a593Smuzhiyun auto const fd = ManagedResource<int>{gbm_bo_get_fd(gbm_bo), close}; 114*4882a593Smuzhiyun- auto const stride = gbm_bo_get_stride(gbm_bo); 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun- VkDmaBufImageCreateInfo create_info{}; 117*4882a593Smuzhiyun- create_info.sType = static_cast<VkStructureType>(VK_STRUCTURE_TYPE_DMA_BUF_IMAGE_CREATE_INFO_INTEL); 118*4882a593Smuzhiyun- create_info.fd = fd; 119*4882a593Smuzhiyun- create_info.format = static_cast<VkFormat>(vk_image_format); 120*4882a593Smuzhiyun- create_info.extent = {vk_extent.width, vk_extent.height, 1}; 121*4882a593Smuzhiyun- create_info.strideInBytes = stride; 122*4882a593Smuzhiyun+ VkExternalMemoryImageCreateInfoKHR external_image_create_info = { 123*4882a593Smuzhiyun+ .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR, 124*4882a593Smuzhiyun+ .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, 125*4882a593Smuzhiyun+ }; 126*4882a593Smuzhiyun+ 127*4882a593Smuzhiyun+ uint64_t modifier = DRM_FORMAT_MOD_LINEAR; 128*4882a593Smuzhiyun+ VkImageDrmFormatModifierListCreateInfoEXT modifier_info = { 129*4882a593Smuzhiyun+ .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT, 130*4882a593Smuzhiyun+ .drmFormatModifierCount = 1, 131*4882a593Smuzhiyun+ .pDrmFormatModifiers = &modifier, 132*4882a593Smuzhiyun+ }; 133*4882a593Smuzhiyun+ external_image_create_info.pNext = &modifier_info; 134*4882a593Smuzhiyun+ 135*4882a593Smuzhiyun+ VkImportMemoryFdInfoKHR import_memory_fd_info = { 136*4882a593Smuzhiyun+ .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, 137*4882a593Smuzhiyun+ .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, 138*4882a593Smuzhiyun+ .fd = fd, 139*4882a593Smuzhiyun+ }; 140*4882a593Smuzhiyun+ 141*4882a593Smuzhiyun+ VkImageCreateInfo create_info{}; 142*4882a593Smuzhiyun+ create_info = { 143*4882a593Smuzhiyun+ .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 144*4882a593Smuzhiyun+ .pNext = &external_image_create_info, 145*4882a593Smuzhiyun+ .flags = 0, 146*4882a593Smuzhiyun+ .imageType = VK_IMAGE_TYPE_2D, 147*4882a593Smuzhiyun+ .format = static_cast<VkFormat>(vk_image_format), 148*4882a593Smuzhiyun+ .extent = {vk_extent.width, vk_extent.height, 1}, 149*4882a593Smuzhiyun+ .mipLevels = 1, 150*4882a593Smuzhiyun+ .arrayLayers = 1, 151*4882a593Smuzhiyun+ .samples = VK_SAMPLE_COUNT_1_BIT, 152*4882a593Smuzhiyun+ .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, 153*4882a593Smuzhiyun+ .usage = 0, 154*4882a593Smuzhiyun+ .sharingMode = VK_SHARING_MODE_EXCLUSIVE, 155*4882a593Smuzhiyun+ .queueFamilyIndexCount = 0, 156*4882a593Smuzhiyun+ .pQueueFamilyIndices = nullptr, 157*4882a593Smuzhiyun+ .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, 158*4882a593Smuzhiyun+ }; 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun VkImage image; 161*4882a593Smuzhiyun- VkDeviceMemory device_memory; 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun- VkResult result = create_dma_buf_image( 164*4882a593Smuzhiyun+ VkResult result = vkCreateImage( 165*4882a593Smuzhiyun vulkan->device(), 166*4882a593Smuzhiyun &create_info, 167*4882a593Smuzhiyun nullptr, 168*4882a593Smuzhiyun- &device_memory, 169*4882a593Smuzhiyun &image); 170*4882a593Smuzhiyun+ if (result != VK_SUCCESS) 171*4882a593Smuzhiyun+ { 172*4882a593Smuzhiyun+ vk::throwResultException(static_cast<vk::Result>(result), 173*4882a593Smuzhiyun+ "vkCreateImage"); 174*4882a593Smuzhiyun+ } 175*4882a593Smuzhiyun+ 176*4882a593Smuzhiyun+ VkMemoryDedicatedAllocateInfoKHR dedicated_memory_info = { 177*4882a593Smuzhiyun+ .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, 178*4882a593Smuzhiyun+ .pNext = &import_memory_fd_info, 179*4882a593Smuzhiyun+ .image = image, 180*4882a593Smuzhiyun+ }; 181*4882a593Smuzhiyun+ 182*4882a593Smuzhiyun+ VkMemoryRequirements requirements; 183*4882a593Smuzhiyun+ vkGetImageMemoryRequirements(vulkan->device(), image, &requirements); 184*4882a593Smuzhiyun+ if (!requirements.memoryTypeBits) { 185*4882a593Smuzhiyun+ throw std::runtime_error{"Failed in vkGetImageMemoryRequirements"}; 186*4882a593Smuzhiyun+ } 187*4882a593Smuzhiyun+ 188*4882a593Smuzhiyun+ int index = find_memory_type_index(vulkan->physical_device(), 189*4882a593Smuzhiyun+ &requirements, 190*4882a593Smuzhiyun+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); 191*4882a593Smuzhiyun+ if (index < 0) { 192*4882a593Smuzhiyun+ throw std::runtime_error{"Failed to get memoryTypeIndex"}; 193*4882a593Smuzhiyun+ } 194*4882a593Smuzhiyun+ 195*4882a593Smuzhiyun+ VkMemoryAllocateInfo memory_allocate_info = { 196*4882a593Smuzhiyun+ .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 197*4882a593Smuzhiyun+ .pNext = &dedicated_memory_info, 198*4882a593Smuzhiyun+ .allocationSize = requirements.size, 199*4882a593Smuzhiyun+ .memoryTypeIndex = (uint32_t)index, 200*4882a593Smuzhiyun+ }; 201*4882a593Smuzhiyun+ 202*4882a593Smuzhiyun+ VkDeviceMemory device_memory = VK_NULL_HANDLE; 203*4882a593Smuzhiyun+ result = vkAllocateMemory(vulkan->device(), &memory_allocate_info, 204*4882a593Smuzhiyun+ nullptr /* pAllocator */, &device_memory); 205*4882a593Smuzhiyun 206*4882a593Smuzhiyun if (result != VK_SUCCESS) 207*4882a593Smuzhiyun { 208*4882a593Smuzhiyun vk::throwResultException(static_cast<vk::Result>(result), 209*4882a593Smuzhiyun- "vkCreateDmbBufImageINTEL"); 210*4882a593Smuzhiyun+ "vkAllocateMemory"); 211*4882a593Smuzhiyun+ } 212*4882a593Smuzhiyun+ 213*4882a593Smuzhiyun+ result = vkBindImageMemory(vulkan->device(), image, device_memory, 214*4882a593Smuzhiyun+ 0 /* memoryOffset */); 215*4882a593Smuzhiyun+ if (result != VK_SUCCESS) { 216*4882a593Smuzhiyun+ vk::throwResultException(static_cast<vk::Result>(result), 217*4882a593Smuzhiyun+ "vkBindImageMemory"); 218*4882a593Smuzhiyun } 219*4882a593Smuzhiyun 220*4882a593Smuzhiyun vk_images.push_back( 221*4882a593Smuzhiyun@@ -500,6 +552,40 @@ void KMSWindowSystem::create_vk_images() 222*4882a593Smuzhiyun vptr->device().destroyImage(image); 223*4882a593Smuzhiyun vptr->device().freeMemory(device_memory); 224*4882a593Smuzhiyun }}); 225*4882a593Smuzhiyun+ 226*4882a593Smuzhiyun+ std::array<VkSubresourceLayout, 4> layouts = {}; 227*4882a593Smuzhiyun+ const VkImageSubresource image_subresource = { 228*4882a593Smuzhiyun+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 229*4882a593Smuzhiyun+ .mipLevel = 0, 230*4882a593Smuzhiyun+ .arrayLayer = 0, 231*4882a593Smuzhiyun+ }; 232*4882a593Smuzhiyun+ vkGetImageSubresourceLayout(vulkan->device(), image, 233*4882a593Smuzhiyun+ &image_subresource, &layouts[0]); 234*4882a593Smuzhiyun+ 235*4882a593Smuzhiyun+ uint32_t fb = 0; 236*4882a593Smuzhiyun+ 237*4882a593Smuzhiyun+ uint32_t handles[4] = {0,}; 238*4882a593Smuzhiyun+ uint32_t strides[4] = {0,}; 239*4882a593Smuzhiyun+ uint32_t offsets[4] = {0,}; 240*4882a593Smuzhiyun+ 241*4882a593Smuzhiyun+ for (auto i = 0; i < gbm_bo_get_plane_count(gbm_bo); i++) { 242*4882a593Smuzhiyun+ handles[i] = gbm_bo_get_handle(gbm_bo).u32; 243*4882a593Smuzhiyun+ offsets[i] = layouts[i].offset; 244*4882a593Smuzhiyun+ strides[i] = layouts[i].rowPitch; 245*4882a593Smuzhiyun+ } 246*4882a593Smuzhiyun+ 247*4882a593Smuzhiyun+ auto const ret = drmModeAddFB2( 248*4882a593Smuzhiyun+ drm_fd, vk_extent.width, vk_extent.height, 249*4882a593Smuzhiyun+ DRM_FORMAT_XRGB8888, 250*4882a593Smuzhiyun+ handles, strides, offsets, &fb, 0); 251*4882a593Smuzhiyun+ 252*4882a593Smuzhiyun+ if (ret < 0) 253*4882a593Smuzhiyun+ throw std::system_error{-ret, std::system_category(), "Failed to add drm fb"}; 254*4882a593Smuzhiyun+ 255*4882a593Smuzhiyun+ drm_fbs.push_back( 256*4882a593Smuzhiyun+ ManagedResource<uint32_t>{ 257*4882a593Smuzhiyun+ std::move(fb), 258*4882a593Smuzhiyun+ [this] (auto& fb) { drmModeRmFB(drm_fd, fb); }}); 259*4882a593Smuzhiyun } 260*4882a593Smuzhiyun } 261*4882a593Smuzhiyun 262*4882a593Smuzhiyundiff --git a/src/ws/kms_window_system.h b/src/ws/kms_window_system.h 263*4882a593Smuzhiyunindex 4389ef7..ca304c0 100644 264*4882a593Smuzhiyun--- a/src/ws/kms_window_system.h 265*4882a593Smuzhiyun+++ b/src/ws/kms_window_system.h 266*4882a593Smuzhiyun@@ -68,7 +68,6 @@ public: 267*4882a593Smuzhiyun 268*4882a593Smuzhiyun protected: 269*4882a593Smuzhiyun void create_gbm_bos(); 270*4882a593Smuzhiyun- void create_drm_fbs(); 271*4882a593Smuzhiyun void create_vk_images(); 272*4882a593Smuzhiyun void wait_for_drm_page_flip_event(); 273*4882a593Smuzhiyun 274*4882a593Smuzhiyun-- 275*4882a593Smuzhiyun2.20.1 276*4882a593Smuzhiyun 277