C++程序  |  286行  |  7.63 KB

/*-------------------------------------------------------------------------
 * 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