/*------------------------------------------------------------------------- * drawElements Quality Program Tester Core * ---------------------------------------- * * Copyright (c) 2016 The Khronos Group Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Linux Vulkan Platform. *//*--------------------------------------------------------------------*/ #include "tcuLnxVulkanPlatform.hpp" #include "tcuLnxPlatform.hpp" #include "vkWsiPlatform.hpp" #include "gluPlatform.hpp" #include "tcuLnx.hpp" #include "tcuFunctionLibrary.hpp" #include "deUniquePtr.hpp" #include "deMemory.h" #include <sys/utsname.h> using de::MovePtr; using de::UniquePtr; #if defined (DEQP_SUPPORT_X11) # include "tcuLnxX11.hpp" # if defined (DEQP_SUPPORT_XCB) # include "tcuLnxX11Xcb.hpp" # endif // DEQP_SUPPORT_XCB # define X11_DISPLAY "" #endif // DEQP_SUPPORT_X11 #if defined (DEQP_SUPPORT_WAYLAND) # include "tcuLnxWayland.hpp" # define WAYLAND_DISPLAY DE_NULL #endif // DEQP_SUPPORT_WAYLAND namespace tcu { namespace lnx { #if defined (DEQP_SUPPORT_X11) class VulkanWindowXlib : public vk::wsi::XlibWindowInterface { public: VulkanWindowXlib (MovePtr<x11::XlibWindow> window) : vk::wsi::XlibWindowInterface (vk::pt::XlibWindow(window->getXID())) , m_window (window) { } void resize (const UVec2& newSize) { m_window->setDimensions((int)newSize.x(), (int)newSize.y()); } private: UniquePtr<x11::XlibWindow> m_window; }; class VulkanDisplayXlib : public vk::wsi::XlibDisplayInterface { public: VulkanDisplayXlib (MovePtr<x11::DisplayBase> display) : vk::wsi::XlibDisplayInterface (vk::pt::XlibDisplayPtr(((x11::XlibDisplay*)display.get())->getXDisplay())) , m_display (display) { } vk::wsi::Window* createWindow (const Maybe<UVec2>& initialSize) const { x11::XlibDisplay* instance = (x11::XlibDisplay*)(m_display.get()); const deUint32 height = !initialSize ? (deUint32)DEFAULT_WINDOW_HEIGHT : initialSize->y(); const deUint32 width = !initialSize ? (deUint32)DEFAULT_WINDOW_WIDTH : initialSize->x(); return new VulkanWindowXlib(MovePtr<x11::XlibWindow>(new x11::XlibWindow(*instance, (int)width, (int)height, instance->getVisual(0)))); } private: MovePtr<x11::DisplayBase> m_display; }; #endif // DEQP_SUPPORT_X11 #if defined (DEQP_SUPPORT_XCB) class VulkanWindowXcb : public vk::wsi::XcbWindowInterface { public: VulkanWindowXcb (MovePtr<x11::XcbWindow> window) : vk::wsi::XcbWindowInterface (vk::pt::XcbWindow(window->getXID())) , m_window (window) { } void resize (const UVec2& newSize) { m_window->setDimensions((int)newSize.x(), (int)newSize.y()); } private: UniquePtr<x11::XcbWindow> m_window; }; class VulkanDisplayXcb : public vk::wsi::XcbDisplayInterface { public: VulkanDisplayXcb (MovePtr<x11::DisplayBase> display) : vk::wsi::XcbDisplayInterface (vk::pt::XcbConnectionPtr(((x11::XcbDisplay*)display.get())->getConnection())) , m_display (display) { } vk::wsi::Window* createWindow (const Maybe<UVec2>& initialSize) const { x11::XcbDisplay* instance = (x11::XcbDisplay*)(m_display.get()); const deUint32 height = !initialSize ? (deUint32)DEFAULT_WINDOW_HEIGHT : initialSize->y(); const deUint32 width = !initialSize ? (deUint32)DEFAULT_WINDOW_WIDTH : initialSize->x(); return new VulkanWindowXcb(MovePtr<x11::XcbWindow>(new x11::XcbWindow(*instance, (int)width, (int)height, DE_NULL))); } private: MovePtr<x11::DisplayBase> m_display; }; #endif // DEQP_SUPPORT_XCB #if defined (DEQP_SUPPORT_WAYLAND) class VulkanWindowWayland : public vk::wsi::WaylandWindowInterface { public: VulkanWindowWayland (MovePtr<wayland::Window> window) : vk::wsi::WaylandWindowInterface (vk::pt::WaylandSurfacePtr(window->getSurface())) , m_window (window) { } void resize (const UVec2& newSize) { m_window->setDimensions((int)newSize.x(), (int)newSize.y()); } private: UniquePtr<wayland::Window> m_window; }; class VulkanDisplayWayland : public vk::wsi::WaylandDisplayInterface { public: VulkanDisplayWayland (MovePtr<wayland::Display> display) : vk::wsi::WaylandDisplayInterface (vk::pt::WaylandDisplayPtr(display->getDisplay())) , m_display (display) { } vk::wsi::Window* createWindow (const Maybe<UVec2>& initialSize) const { const deUint32 height = !initialSize ? (deUint32)DEFAULT_WINDOW_HEIGHT : initialSize->y(); const deUint32 width = !initialSize ? (deUint32)DEFAULT_WINDOW_WIDTH : initialSize->x(); return new VulkanWindowWayland(MovePtr<wayland::Window>(new wayland::Window(*m_display, (int)width, (int)height))); } private: MovePtr<wayland::Display> m_display; }; #endif // DEQP_SUPPORT_WAYLAND class VulkanLibrary : public vk::Library { public: VulkanLibrary (void) : m_library ("libvulkan.so.1") , m_driver (m_library) { } const vk::PlatformInterface& getPlatformInterface (void) const { return m_driver; } const tcu::FunctionLibrary& getFunctionLibrary (void) const { return m_library; } private: const DynamicFunctionLibrary m_library; const vk::PlatformDriver m_driver; }; VulkanPlatform::VulkanPlatform (EventState& eventState) : m_eventState(eventState) { } vk::wsi::Display* VulkanPlatform::createWsiDisplay (vk::wsi::Type wsiType) const { switch(wsiType) { #if defined (DEQP_SUPPORT_X11) case vk::wsi::TYPE_XLIB: return new VulkanDisplayXlib(MovePtr<x11::DisplayBase>(new x11::XlibDisplay(m_eventState,X11_DISPLAY))); break; #endif // DEQP_SUPPORT_X11 #if defined (DEQP_SUPPORT_XCB) case vk::wsi::TYPE_XCB: return new VulkanDisplayXcb(MovePtr<x11::DisplayBase>(new x11::XcbDisplay(m_eventState,X11_DISPLAY))); break; #endif // DEQP_SUPPORT_XCB #if defined (DEQP_SUPPORT_WAYLAND) case vk::wsi::TYPE_WAYLAND: return new VulkanDisplayWayland(MovePtr<wayland::Display>(new wayland::Display(m_eventState, WAYLAND_DISPLAY))); break; #endif // DEQP_SUPPORT_WAYLAND default: TCU_THROW(NotSupportedError, "WSI type not supported"); }; } bool VulkanPlatform::hasDisplay (vk::wsi::Type wsiType) const { switch(wsiType) { #if defined (DEQP_SUPPORT_X11) case vk::wsi::TYPE_XLIB: return x11::XlibDisplay::hasDisplay(X11_DISPLAY); #endif // DEQP_SUPPORT_X11 #if defined (DEQP_SUPPORT_XCB) case vk::wsi::TYPE_XCB: return x11::XcbDisplay::hasDisplay(X11_DISPLAY); #endif // DEQP_SUPPORT_XCB #if defined (DEQP_SUPPORT_WAYLAND) case vk::wsi::TYPE_WAYLAND: return wayland::Display::hasDisplay(WAYLAND_DISPLAY); #endif // DEQP_SUPPORT_WAYLAND default: return false; }; } vk::Library* VulkanPlatform::createLibrary (void) const { return new VulkanLibrary(); } void VulkanPlatform::describePlatform (std::ostream& dst) const { utsname sysInfo; deMemset(&sysInfo, 0, sizeof(sysInfo)); if (uname(&sysInfo) != 0) throw std::runtime_error("uname() failed"); dst << "OS: " << sysInfo.sysname << " " << sysInfo.release << " " << sysInfo.version << "\n"; dst << "CPU: " << sysInfo.machine << "\n"; } void VulkanPlatform::getMemoryLimits (vk::PlatformMemoryLimits& limits) const { limits.totalSystemMemory = 256*1024*1024; limits.totalDeviceLocalMemory = 128*1024*1024; limits.deviceMemoryAllocationGranularity = 64*1024; limits.devicePageSize = 4096; limits.devicePageTableEntrySize = 8; limits.devicePageTableHierarchyLevels = 3; } } // linux } // tcu