Add basic vulkan driver
This commit is contained in:
parent
40949a03d2
commit
d5c848c4c2
@ -693,10 +693,10 @@ if(NOT SERVER_ONLY)
|
||||
${OGGVORBIS_LIBRARIES}
|
||||
${FREETYPE_LIBRARIES}
|
||||
${HARFBUZZ_LIBRARY}
|
||||
${SDL2_LIBRARY}
|
||||
${SHEENBIDI_LIBRARY}
|
||||
graphics_utils
|
||||
graphics_engine
|
||||
${SDL2_LIBRARY}
|
||||
tinygettext)
|
||||
endif()
|
||||
|
||||
|
@ -147,10 +147,11 @@ include $(CLEAR_VARS)
|
||||
# Graphics engine
|
||||
LOCAL_MODULE := graphics_engine
|
||||
LOCAL_PATH := .
|
||||
LOCAL_CPP_FEATURES += rtti
|
||||
LOCAL_CPP_FEATURES += rtti exceptions
|
||||
LOCAL_SRC_FILES := $(wildcard ../lib/graphics_engine/src/*.c) \
|
||||
$(wildcard ../lib/graphics_engine/src/*.cpp)
|
||||
LOCAL_CFLAGS := -I../lib/graphics_engine/include \
|
||||
-I../lib/sdl2/include/ \
|
||||
-I../lib/irrlicht/include/
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
include $(CLEAR_VARS)
|
||||
@ -189,7 +190,7 @@ include $(CLEAR_VARS)
|
||||
# Irrlicht
|
||||
LOCAL_MODULE := irrlicht
|
||||
LOCAL_PATH := .
|
||||
LOCAL_CPP_FEATURES += rtti
|
||||
LOCAL_CPP_FEATURES += rtti exceptions
|
||||
LOCAL_SRC_FILES := $(wildcard ../lib/irrlicht/source/Irrlicht/*.cpp)
|
||||
LOCAL_CFLAGS := -I../lib/irrlicht/source/Irrlicht/ \
|
||||
-I../lib/irrlicht/include/ \
|
||||
|
@ -1,5 +1,12 @@
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/graphics_engine/include")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/irrlicht/include")
|
||||
find_path(SDL2_INCLUDEDIR NAMES SDL.h PATH_SUFFIXES SDL2 include/SDL2 include PATHS)
|
||||
if (NOT SDL2_INCLUDEDIR)
|
||||
message(FATAL_ERROR "SDL2 not found.")
|
||||
else()
|
||||
include_directories("${SDL2_INCLUDEDIR}")
|
||||
endif()
|
||||
|
||||
if(UNIX OR MINGW)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
|
||||
endif()
|
||||
@ -9,5 +16,6 @@ add_library(graphics_engine STATIC
|
||||
src/ge_main.cpp
|
||||
src/ge_texture.cpp
|
||||
src/ge_dx9_texture.cpp
|
||||
src/ge_vulkan_driver.cpp
|
||||
src/ge_gl_texture.cpp
|
||||
)
|
||||
|
350
lib/graphics_engine/include/ge_vulkan_driver.hpp
Normal file
350
lib/graphics_engine/include/ge_vulkan_driver.hpp
Normal file
@ -0,0 +1,350 @@
|
||||
#ifndef __VULKAN_DRIVER_INCLUDED__
|
||||
#define __VULKAN_DRIVER_INCLUDED__
|
||||
|
||||
#include "IrrCompileConfig.h"
|
||||
|
||||
#ifdef _IRR_COMPILE_WITH_VULKAN_
|
||||
|
||||
#include "glad/vulkan.h"
|
||||
#include "SDL_video.h"
|
||||
|
||||
#include "../source/Irrlicht/CNullDriver.h"
|
||||
#include "SIrrCreationParameters.h"
|
||||
#include "SColor.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace irr;
|
||||
using namespace video;
|
||||
|
||||
namespace GE
|
||||
{
|
||||
class GEVulkanDriver : public video::CNullDriver
|
||||
{
|
||||
public:
|
||||
|
||||
//! constructor
|
||||
GEVulkanDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, SDL_Window* window);
|
||||
|
||||
//! destructor
|
||||
virtual ~GEVulkanDriver();
|
||||
|
||||
//! applications must call this method before performing any rendering. returns false if failed.
|
||||
virtual bool beginScene(bool backBuffer=true, bool zBuffer=true,
|
||||
SColor color=SColor(255,0,0,0),
|
||||
const SExposedVideoData& videoData=SExposedVideoData(),
|
||||
core::rect<s32>* sourceRect=0) { return true; }
|
||||
|
||||
//! applications must call this method after performing any rendering. returns false if failed.
|
||||
virtual bool endScene() { return true; }
|
||||
|
||||
//! queries the features of the driver, returns true if feature is available
|
||||
virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const { return true; }
|
||||
|
||||
//! sets transformation
|
||||
virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) {}
|
||||
|
||||
//! sets a material
|
||||
virtual void setMaterial(const SMaterial& material) {}
|
||||
|
||||
//! sets a render target
|
||||
virtual bool setRenderTarget(video::ITexture* texture,
|
||||
bool clearBackBuffer=true, bool clearZBuffer=true,
|
||||
SColor color=video::SColor(0,0,0,0)) { return true; }
|
||||
|
||||
//! Sets multiple render targets
|
||||
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
|
||||
bool clearBackBuffer=true, bool clearZBuffer=true,
|
||||
SColor color=video::SColor(0,0,0,0)) { return true; }
|
||||
|
||||
//! sets a viewport
|
||||
virtual void setViewPort(const core::rect<s32>& area) {}
|
||||
|
||||
//! gets the area of the current viewport
|
||||
virtual const core::rect<s32>& getViewPort() const
|
||||
{
|
||||
static core::rect<s32> unused;
|
||||
return unused;
|
||||
}
|
||||
|
||||
//! updates hardware buffer if needed
|
||||
virtual bool updateHardwareBuffer(SHWBufferLink *HWBuffer) { return false; }
|
||||
|
||||
//! Create hardware buffer from mesh
|
||||
virtual SHWBufferLink *createHardwareBuffer(const scene::IMeshBuffer* mb) { return NULL; }
|
||||
|
||||
//! Delete hardware buffer (only some drivers can)
|
||||
virtual void deleteHardwareBuffer(SHWBufferLink *HWBuffer) {}
|
||||
|
||||
//! Draw hardware buffer
|
||||
virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer) {}
|
||||
|
||||
//! Create occlusion query.
|
||||
/** Use node for identification and mesh for occlusion test. */
|
||||
virtual void addOcclusionQuery(scene::ISceneNode* node,
|
||||
const scene::IMesh* mesh=0) {}
|
||||
|
||||
//! Remove occlusion query.
|
||||
virtual void removeOcclusionQuery(scene::ISceneNode* node) {}
|
||||
|
||||
//! Run occlusion query. Draws mesh stored in query.
|
||||
/** If the mesh shall not be rendered visible, use
|
||||
overrideMaterial to disable the color and depth buffer. */
|
||||
virtual void runOcclusionQuery(scene::ISceneNode* node, bool visible=false) {}
|
||||
|
||||
//! Update occlusion query. Retrieves results from GPU.
|
||||
/** If the query shall not block, set the flag to false.
|
||||
Update might not occur in this case, though */
|
||||
virtual void updateOcclusionQuery(scene::ISceneNode* node, bool block=true) {}
|
||||
|
||||
//! Return query result.
|
||||
/** Return value is the number of visible pixels/fragments.
|
||||
The value is a safe approximation, i.e. can be larger then the
|
||||
actual value of pixels. */
|
||||
virtual u32 getOcclusionQueryResult(scene::ISceneNode* node) const { return 0; }
|
||||
|
||||
//! draws a vertex primitive list
|
||||
virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
|
||||
const void* indexList, u32 primitiveCount,
|
||||
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType,
|
||||
E_INDEX_TYPE iType) {}
|
||||
|
||||
//! draws a vertex primitive list in 2d
|
||||
virtual void draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount,
|
||||
const void* indexList, u32 primitiveCount,
|
||||
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType,
|
||||
E_INDEX_TYPE iType) {}
|
||||
|
||||
//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted.
|
||||
virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
|
||||
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
|
||||
SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false) {}
|
||||
|
||||
//! Draws a part of the texture into the rectangle.
|
||||
virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
|
||||
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
|
||||
const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false) {}
|
||||
|
||||
//! Draws a set of 2d images, using a color and the alpha channel of the texture.
|
||||
virtual void draw2DImageBatch(const video::ITexture* texture,
|
||||
const core::array<core::position2d<s32> >& positions,
|
||||
const core::array<core::rect<s32> >& sourceRects,
|
||||
const core::rect<s32>* clipRect=0,
|
||||
SColor color=SColor(255,255,255,255),
|
||||
bool useAlphaChannelOfTexture=false) {}
|
||||
|
||||
//!Draws an 2d rectangle with a gradient.
|
||||
virtual void draw2DRectangle(const core::rect<s32>& pos,
|
||||
SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
|
||||
const core::rect<s32>* clip) {}
|
||||
|
||||
//! Draws a 2d line.
|
||||
virtual void draw2DLine(const core::position2d<s32>& start,
|
||||
const core::position2d<s32>& end,
|
||||
SColor color=SColor(255,255,255,255)) {}
|
||||
|
||||
//! Draws a pixel.
|
||||
virtual void drawPixel(u32 x, u32 y, const SColor & color) {}
|
||||
|
||||
//! Draws a 3d line.
|
||||
virtual void draw3DLine(const core::vector3df& start,
|
||||
const core::vector3df& end, SColor color = SColor(255,255,255,255)) {}
|
||||
|
||||
//! \return Returns the name of the video driver. Example: In case of the DIRECT3D8
|
||||
//! driver, it would return "Direct3D8.1".
|
||||
virtual const wchar_t* getName() const { return L""; }
|
||||
|
||||
//! deletes all dynamic lights there are
|
||||
virtual void deleteAllDynamicLights() {}
|
||||
|
||||
//! adds a dynamic light, returning an index to the light
|
||||
//! \param light: the light data to use to create the light
|
||||
//! \return An index to the light, or -1 if an error occurs
|
||||
virtual s32 addDynamicLight(const SLight& light) { return -1; }
|
||||
|
||||
//! Turns a dynamic light on or off
|
||||
//! \param lightIndex: the index returned by addDynamicLight
|
||||
//! \param turnOn: true to turn the light on, false to turn it off
|
||||
virtual void turnLightOn(s32 lightIndex, bool turnOn) {}
|
||||
|
||||
//! returns the maximal amount of dynamic lights the device can handle
|
||||
virtual u32 getMaximalDynamicLightAmount() const { return (u32)-1; }
|
||||
|
||||
//! Sets the dynamic ambient light color. The default color is
|
||||
//! (0,0,0,0) which means it is dark.
|
||||
//! \param color: New color of the ambient light.
|
||||
virtual void setAmbientLight(const SColorf& color) {}
|
||||
|
||||
//! Draws a shadow volume into the stencil buffer.
|
||||
virtual void drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail=true, u32 debugDataVisible=0) {}
|
||||
|
||||
//! Fills the stencil shadow with color.
|
||||
virtual void drawStencilShadow(bool clearStencilBuffer=false,
|
||||
video::SColor leftUpEdge = video::SColor(0,0,0,0),
|
||||
video::SColor rightUpEdge = video::SColor(0,0,0,0),
|
||||
video::SColor leftDownEdge = video::SColor(0,0,0,0),
|
||||
video::SColor rightDownEdge = video::SColor(0,0,0,0)) {}
|
||||
|
||||
//! Returns the maximum amount of primitives (mostly vertices) which
|
||||
//! the device is able to render with one drawIndexedTriangleList
|
||||
//! call.
|
||||
virtual u32 getMaximalPrimitiveCount() const { return (u32)-1; }
|
||||
|
||||
//! Enables or disables a texture creation flag.
|
||||
virtual void setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled) {}
|
||||
|
||||
//! Sets the fog mode.
|
||||
virtual void setFog(SColor color, E_FOG_TYPE fogType, f32 start,
|
||||
f32 end, f32 density, bool pixelFog, bool rangeFog) {}
|
||||
|
||||
//! Only used by the internal engine. Used to notify the driver that
|
||||
//! the window was resized.
|
||||
virtual void OnResize(const core::dimension2d<u32>& size) {}
|
||||
|
||||
//! Returns type of video driver
|
||||
virtual E_DRIVER_TYPE getDriverType() const { return video::EDT_VULKAN; }
|
||||
|
||||
//! Returns the transformation set by setTransform
|
||||
virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const
|
||||
{
|
||||
static core::matrix4 unused;
|
||||
return unused;
|
||||
}
|
||||
|
||||
//! Creates a render target texture.
|
||||
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
|
||||
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN, const bool useStencil = false) { return NULL; }
|
||||
|
||||
//! Clears the ZBuffer.
|
||||
virtual void clearZBuffer() {}
|
||||
|
||||
//! Returns an image created from the last rendered frame.
|
||||
virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER) { return NULL; }
|
||||
|
||||
//! Set/unset a clipping plane.
|
||||
virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable=false) { return true; }
|
||||
|
||||
//! Enable/disable a clipping plane.
|
||||
virtual void enableClipPlane(u32 index, bool enable) {}
|
||||
|
||||
//! Returns the graphics card vendor name.
|
||||
virtual core::stringc getVendorInfo()
|
||||
{
|
||||
switch (m_properties.vendorID)
|
||||
{
|
||||
case 0x1002: return "AMD";
|
||||
case 0x1010: return "ImgTec";
|
||||
case 0x106B: return "Apple";
|
||||
case 0x10DE: return "NVIDIA";
|
||||
case 0x13B5: return "ARM";
|
||||
case 0x14e4: return "Broadcom";
|
||||
case 0x5143: return "Qualcomm";
|
||||
case 0x8086: return "INTEL";
|
||||
// llvmpipe
|
||||
case 0x10005: return "Mesa";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
//! Enable the 2d override material
|
||||
virtual void enableMaterial2D(bool enable=true) {}
|
||||
|
||||
//! Check if the driver was recently reset.
|
||||
virtual bool checkDriverReset() { return false; }
|
||||
|
||||
//! Get the current color format of the color buffer
|
||||
/** \return Color format of the color buffer. */
|
||||
virtual ECOLOR_FORMAT getColorFormat() const { return ECF_A8R8G8B8; }
|
||||
|
||||
//! Returns the maximum texture size supported.
|
||||
virtual core::dimension2du getMaxTextureSize() const { return core::dimension2du(16384, 16384); }
|
||||
|
||||
virtual void enableScissorTest(const core::rect<s32>& r) {}
|
||||
virtual void disableScissorTest() {}
|
||||
|
||||
private:
|
||||
//! returns a device dependent texture from a software surface (IImage)
|
||||
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
|
||||
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0) { return NULL; }
|
||||
|
||||
//! returns the current size of the screen or rendertarget
|
||||
virtual const core::dimension2d<u32>& getCurrentRenderTargetSize() const
|
||||
{
|
||||
static core::dimension2d<u32> unused;
|
||||
return unused;
|
||||
}
|
||||
|
||||
//! Adds a new material renderer to the VideoDriver, based on a high level shading
|
||||
//! language.
|
||||
virtual s32 addHighLevelShaderMaterial(
|
||||
const c8* vertexShaderProgram,
|
||||
const c8* vertexShaderEntryPointName,
|
||||
E_VERTEX_SHADER_TYPE vsCompileTarget,
|
||||
const c8* pixelShaderProgram,
|
||||
const c8* pixelShaderEntryPointName,
|
||||
E_PIXEL_SHADER_TYPE psCompileTarget,
|
||||
const c8* geometryShaderProgram,
|
||||
const c8* geometryShaderEntryPointName = "main",
|
||||
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
|
||||
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
|
||||
scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
|
||||
u32 verticesOut = 0,
|
||||
IShaderConstantSetCallBack* callback = 0,
|
||||
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
|
||||
s32 userData = 0,
|
||||
E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT) { return 0; }
|
||||
|
||||
// RAII to auto cleanup
|
||||
struct VK
|
||||
{
|
||||
VkInstance instance;
|
||||
VkSurfaceKHR surface;
|
||||
VkDevice device;
|
||||
VK()
|
||||
{
|
||||
instance = VK_NULL_HANDLE;
|
||||
surface = VK_NULL_HANDLE;
|
||||
device = VK_NULL_HANDLE;
|
||||
}
|
||||
~VK()
|
||||
{
|
||||
if (device != VK_NULL_HANDLE)
|
||||
vkDestroyDevice(device, NULL);
|
||||
if (surface != VK_NULL_HANDLE)
|
||||
vkDestroySurfaceKHR(instance, surface, NULL);
|
||||
if (instance != VK_NULL_HANDLE)
|
||||
vkDestroyInstance(instance, NULL);
|
||||
}
|
||||
};
|
||||
VK m_vk;
|
||||
VkPhysicalDevice m_physical_device;
|
||||
std::vector<const char*> m_device_extensions;
|
||||
VkSurfaceCapabilitiesKHR m_surface_capabilities;
|
||||
std::vector<VkSurfaceFormatKHR> m_surface_formats;
|
||||
std::vector<VkPresentModeKHR> m_present_modes;
|
||||
VkQueue m_graphics_queue;
|
||||
VkQueue m_present_queue;
|
||||
|
||||
uint32_t m_graphics_family;
|
||||
uint32_t m_present_family;
|
||||
VkPhysicalDeviceProperties m_properties;
|
||||
VkPhysicalDeviceFeatures m_features;
|
||||
|
||||
void createInstance(SDL_Window* window);
|
||||
void findPhysicalDevice();
|
||||
bool checkDeviceExtensions(VkPhysicalDevice device);
|
||||
bool findQueueFamilies(VkPhysicalDevice device, uint32_t* graphics_family, uint32_t* present_family);
|
||||
bool updateSurfaceInformation(VkPhysicalDevice device,
|
||||
VkSurfaceCapabilitiesKHR* surface_capabilities,
|
||||
std::vector<VkSurfaceFormatKHR>* surface_formats,
|
||||
std::vector<VkPresentModeKHR>* present_modes);
|
||||
void createDevice();
|
||||
std::string getVulkanVersionString() const;
|
||||
std::string getDriverVersionString() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _IRR_COMPILE_WITH_VULKAN_
|
||||
#endif // __VULKAN_DRIVER_INCLUDED__
|
||||
|
748
lib/graphics_engine/src/ge_vulkan_driver.cpp
Normal file
748
lib/graphics_engine/src/ge_vulkan_driver.cpp
Normal file
@ -0,0 +1,748 @@
|
||||
#include "ge_vulkan_driver.hpp"
|
||||
|
||||
#ifdef _IRR_COMPILE_WITH_VULKAN_
|
||||
#include "SDL_vulkan.h"
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "../source/Irrlicht/os.h"
|
||||
|
||||
struct GE_VK_UserPointer
|
||||
{
|
||||
VkInstance instance;
|
||||
VkDevice device;
|
||||
PFN_vkGetDeviceProcAddr get_device_proc_addr;
|
||||
PFN_vkGetInstanceProcAddr get_instance_proc_addr;
|
||||
};
|
||||
|
||||
extern "C" PFN_vkVoidFunction loader(void* user_ptr, const char* name)
|
||||
{
|
||||
VkInstance instance = VK_NULL_HANDLE;
|
||||
VkDevice device = VK_NULL_HANDLE;
|
||||
PFN_vkGetDeviceProcAddr get_device_proc_addr = NULL;
|
||||
PFN_vkGetInstanceProcAddr get_instance_proc_addr = NULL;
|
||||
|
||||
if (user_ptr)
|
||||
{
|
||||
instance = ((GE_VK_UserPointer*)user_ptr)->instance;
|
||||
device = ((GE_VK_UserPointer*)user_ptr)->device;
|
||||
get_device_proc_addr =
|
||||
((GE_VK_UserPointer*)user_ptr)->get_device_proc_addr;
|
||||
get_instance_proc_addr =
|
||||
((GE_VK_UserPointer*)user_ptr)->get_instance_proc_addr;
|
||||
}
|
||||
|
||||
if (get_instance_proc_addr == NULL)
|
||||
{
|
||||
get_instance_proc_addr =
|
||||
(PFN_vkGetInstanceProcAddr)SDL_Vulkan_GetVkGetInstanceProcAddr();
|
||||
if (user_ptr)
|
||||
{
|
||||
((GE_VK_UserPointer*)user_ptr)->get_instance_proc_addr =
|
||||
get_instance_proc_addr;
|
||||
}
|
||||
}
|
||||
|
||||
// From vulkan.c glad2 with loader enabled
|
||||
static std::set<std::string> device_function =
|
||||
{{
|
||||
"vkAcquireFullScreenExclusiveModeEXT",
|
||||
"vkAcquireNextImage2KHR",
|
||||
"vkAcquireNextImageKHR",
|
||||
"vkAcquirePerformanceConfigurationINTEL",
|
||||
"vkAcquireProfilingLockKHR",
|
||||
"vkAllocateCommandBuffers",
|
||||
"vkAllocateDescriptorSets",
|
||||
"vkAllocateMemory",
|
||||
"vkBeginCommandBuffer",
|
||||
"vkBindAccelerationStructureMemoryKHR",
|
||||
"vkBindAccelerationStructureMemoryNV",
|
||||
"vkBindBufferMemory",
|
||||
"vkBindBufferMemory2",
|
||||
"vkBindBufferMemory2KHR",
|
||||
"vkBindImageMemory",
|
||||
"vkBindImageMemory2",
|
||||
"vkBindImageMemory2KHR",
|
||||
"vkBuildAccelerationStructureKHR",
|
||||
"vkCmdBeginConditionalRenderingEXT",
|
||||
"vkCmdBeginDebugUtilsLabelEXT",
|
||||
"vkCmdBeginQuery",
|
||||
"vkCmdBeginQueryIndexedEXT",
|
||||
"vkCmdBeginRenderPass",
|
||||
"vkCmdBeginRenderPass2",
|
||||
"vkCmdBeginRenderPass2KHR",
|
||||
"vkCmdBeginTransformFeedbackEXT",
|
||||
"vkCmdBindDescriptorSets",
|
||||
"vkCmdBindIndexBuffer",
|
||||
"vkCmdBindPipeline",
|
||||
"vkCmdBindPipelineShaderGroupNV",
|
||||
"vkCmdBindShadingRateImageNV",
|
||||
"vkCmdBindTransformFeedbackBuffersEXT",
|
||||
"vkCmdBindVertexBuffers",
|
||||
"vkCmdBindVertexBuffers2EXT",
|
||||
"vkCmdBlitImage",
|
||||
"vkCmdBuildAccelerationStructureIndirectKHR",
|
||||
"vkCmdBuildAccelerationStructureKHR",
|
||||
"vkCmdBuildAccelerationStructureNV",
|
||||
"vkCmdClearAttachments",
|
||||
"vkCmdClearColorImage",
|
||||
"vkCmdClearDepthStencilImage",
|
||||
"vkCmdCopyAccelerationStructureKHR",
|
||||
"vkCmdCopyAccelerationStructureNV",
|
||||
"vkCmdCopyAccelerationStructureToMemoryKHR",
|
||||
"vkCmdCopyBuffer",
|
||||
"vkCmdCopyBufferToImage",
|
||||
"vkCmdCopyImage",
|
||||
"vkCmdCopyImageToBuffer",
|
||||
"vkCmdCopyMemoryToAccelerationStructureKHR",
|
||||
"vkCmdCopyQueryPoolResults",
|
||||
"vkCmdDebugMarkerBeginEXT",
|
||||
"vkCmdDebugMarkerEndEXT",
|
||||
"vkCmdDebugMarkerInsertEXT",
|
||||
"vkCmdDispatch",
|
||||
"vkCmdDispatchBase",
|
||||
"vkCmdDispatchBaseKHR",
|
||||
"vkCmdDispatchIndirect",
|
||||
"vkCmdDraw",
|
||||
"vkCmdDrawIndexed",
|
||||
"vkCmdDrawIndexedIndirect",
|
||||
"vkCmdDrawIndexedIndirectCount",
|
||||
"vkCmdDrawIndexedIndirectCountAMD",
|
||||
"vkCmdDrawIndexedIndirectCountKHR",
|
||||
"vkCmdDrawIndirect",
|
||||
"vkCmdDrawIndirectByteCountEXT",
|
||||
"vkCmdDrawIndirectCount",
|
||||
"vkCmdDrawIndirectCountAMD",
|
||||
"vkCmdDrawIndirectCountKHR",
|
||||
"vkCmdDrawMeshTasksIndirectCountNV",
|
||||
"vkCmdDrawMeshTasksIndirectNV",
|
||||
"vkCmdDrawMeshTasksNV",
|
||||
"vkCmdEndConditionalRenderingEXT",
|
||||
"vkCmdEndDebugUtilsLabelEXT",
|
||||
"vkCmdEndQuery",
|
||||
"vkCmdEndQueryIndexedEXT",
|
||||
"vkCmdEndRenderPass",
|
||||
"vkCmdEndRenderPass2",
|
||||
"vkCmdEndRenderPass2KHR",
|
||||
"vkCmdEndTransformFeedbackEXT",
|
||||
"vkCmdExecuteCommands",
|
||||
"vkCmdExecuteGeneratedCommandsNV",
|
||||
"vkCmdFillBuffer",
|
||||
"vkCmdInsertDebugUtilsLabelEXT",
|
||||
"vkCmdNextSubpass",
|
||||
"vkCmdNextSubpass2",
|
||||
"vkCmdNextSubpass2KHR",
|
||||
"vkCmdPipelineBarrier",
|
||||
"vkCmdPreprocessGeneratedCommandsNV",
|
||||
"vkCmdPushConstants",
|
||||
"vkCmdPushDescriptorSetKHR",
|
||||
"vkCmdPushDescriptorSetWithTemplateKHR",
|
||||
"vkCmdResetEvent",
|
||||
"vkCmdResetQueryPool",
|
||||
"vkCmdResolveImage",
|
||||
"vkCmdSetBlendConstants",
|
||||
"vkCmdSetCheckpointNV",
|
||||
"vkCmdSetCoarseSampleOrderNV",
|
||||
"vkCmdSetCullModeEXT",
|
||||
"vkCmdSetDepthBias",
|
||||
"vkCmdSetDepthBounds",
|
||||
"vkCmdSetDepthBoundsTestEnableEXT",
|
||||
"vkCmdSetDepthCompareOpEXT",
|
||||
"vkCmdSetDepthTestEnableEXT",
|
||||
"vkCmdSetDepthWriteEnableEXT",
|
||||
"vkCmdSetDeviceMask",
|
||||
"vkCmdSetDeviceMaskKHR",
|
||||
"vkCmdSetDiscardRectangleEXT",
|
||||
"vkCmdSetEvent",
|
||||
"vkCmdSetExclusiveScissorNV",
|
||||
"vkCmdSetFrontFaceEXT",
|
||||
"vkCmdSetLineStippleEXT",
|
||||
"vkCmdSetLineWidth",
|
||||
"vkCmdSetPerformanceMarkerINTEL",
|
||||
"vkCmdSetPerformanceOverrideINTEL",
|
||||
"vkCmdSetPerformanceStreamMarkerINTEL",
|
||||
"vkCmdSetPrimitiveTopologyEXT",
|
||||
"vkCmdSetSampleLocationsEXT",
|
||||
"vkCmdSetScissor",
|
||||
"vkCmdSetScissorWithCountEXT",
|
||||
"vkCmdSetStencilCompareMask",
|
||||
"vkCmdSetStencilOpEXT",
|
||||
"vkCmdSetStencilReference",
|
||||
"vkCmdSetStencilTestEnableEXT",
|
||||
"vkCmdSetStencilWriteMask",
|
||||
"vkCmdSetViewport",
|
||||
"vkCmdSetViewportShadingRatePaletteNV",
|
||||
"vkCmdSetViewportWScalingNV",
|
||||
"vkCmdSetViewportWithCountEXT",
|
||||
"vkCmdTraceRaysIndirectKHR",
|
||||
"vkCmdTraceRaysKHR",
|
||||
"vkCmdTraceRaysNV",
|
||||
"vkCmdUpdateBuffer",
|
||||
"vkCmdWaitEvents",
|
||||
"vkCmdWriteAccelerationStructuresPropertiesKHR",
|
||||
"vkCmdWriteAccelerationStructuresPropertiesNV",
|
||||
"vkCmdWriteBufferMarkerAMD",
|
||||
"vkCmdWriteTimestamp",
|
||||
"vkCompileDeferredNV",
|
||||
"vkCopyAccelerationStructureKHR",
|
||||
"vkCopyAccelerationStructureToMemoryKHR",
|
||||
"vkCopyMemoryToAccelerationStructureKHR",
|
||||
"vkCreateAccelerationStructureKHR",
|
||||
"vkCreateAccelerationStructureNV",
|
||||
"vkCreateBuffer",
|
||||
"vkCreateBufferView",
|
||||
"vkCreateCommandPool",
|
||||
"vkCreateComputePipelines",
|
||||
"vkCreateDeferredOperationKHR",
|
||||
"vkCreateDescriptorPool",
|
||||
"vkCreateDescriptorSetLayout",
|
||||
"vkCreateDescriptorUpdateTemplate",
|
||||
"vkCreateDescriptorUpdateTemplateKHR",
|
||||
"vkCreateEvent",
|
||||
"vkCreateFence",
|
||||
"vkCreateFramebuffer",
|
||||
"vkCreateGraphicsPipelines",
|
||||
"vkCreateImage",
|
||||
"vkCreateImageView",
|
||||
"vkCreateIndirectCommandsLayoutNV",
|
||||
"vkCreatePipelineCache",
|
||||
"vkCreatePipelineLayout",
|
||||
"vkCreatePrivateDataSlotEXT",
|
||||
"vkCreateQueryPool",
|
||||
"vkCreateRayTracingPipelinesKHR",
|
||||
"vkCreateRayTracingPipelinesNV",
|
||||
"vkCreateRenderPass",
|
||||
"vkCreateRenderPass2",
|
||||
"vkCreateRenderPass2KHR",
|
||||
"vkCreateSampler",
|
||||
"vkCreateSamplerYcbcrConversion",
|
||||
"vkCreateSamplerYcbcrConversionKHR",
|
||||
"vkCreateSemaphore",
|
||||
"vkCreateShaderModule",
|
||||
"vkCreateSharedSwapchainsKHR",
|
||||
"vkCreateSwapchainKHR",
|
||||
"vkCreateValidationCacheEXT",
|
||||
"vkDebugMarkerSetObjectNameEXT",
|
||||
"vkDebugMarkerSetObjectTagEXT",
|
||||
"vkDeferredOperationJoinKHR",
|
||||
"vkDestroyAccelerationStructureKHR",
|
||||
"vkDestroyAccelerationStructureNV",
|
||||
"vkDestroyBuffer",
|
||||
"vkDestroyBufferView",
|
||||
"vkDestroyCommandPool",
|
||||
"vkDestroyDeferredOperationKHR",
|
||||
"vkDestroyDescriptorPool",
|
||||
"vkDestroyDescriptorSetLayout",
|
||||
"vkDestroyDescriptorUpdateTemplate",
|
||||
"vkDestroyDescriptorUpdateTemplateKHR",
|
||||
"vkDestroyDevice",
|
||||
"vkDestroyEvent",
|
||||
"vkDestroyFence",
|
||||
"vkDestroyFramebuffer",
|
||||
"vkDestroyImage",
|
||||
"vkDestroyImageView",
|
||||
"vkDestroyIndirectCommandsLayoutNV",
|
||||
"vkDestroyPipeline",
|
||||
"vkDestroyPipelineCache",
|
||||
"vkDestroyPipelineLayout",
|
||||
"vkDestroyPrivateDataSlotEXT",
|
||||
"vkDestroyQueryPool",
|
||||
"vkDestroyRenderPass",
|
||||
"vkDestroySampler",
|
||||
"vkDestroySamplerYcbcrConversion",
|
||||
"vkDestroySamplerYcbcrConversionKHR",
|
||||
"vkDestroySemaphore",
|
||||
"vkDestroyShaderModule",
|
||||
"vkDestroySwapchainKHR",
|
||||
"vkDestroyValidationCacheEXT",
|
||||
"vkDeviceWaitIdle",
|
||||
"vkDisplayPowerControlEXT",
|
||||
"vkEndCommandBuffer",
|
||||
"vkFlushMappedMemoryRanges",
|
||||
"vkFreeCommandBuffers",
|
||||
"vkFreeDescriptorSets",
|
||||
"vkFreeMemory",
|
||||
"vkGetAccelerationStructureDeviceAddressKHR",
|
||||
"vkGetAccelerationStructureHandleNV",
|
||||
"vkGetAccelerationStructureMemoryRequirementsKHR",
|
||||
"vkGetAccelerationStructureMemoryRequirementsNV",
|
||||
"vkGetAndroidHardwareBufferPropertiesANDROID",
|
||||
"vkGetBufferDeviceAddress",
|
||||
"vkGetBufferDeviceAddressEXT",
|
||||
"vkGetBufferDeviceAddressKHR",
|
||||
"vkGetBufferMemoryRequirements",
|
||||
"vkGetBufferMemoryRequirements2",
|
||||
"vkGetBufferMemoryRequirements2KHR",
|
||||
"vkGetBufferOpaqueCaptureAddress",
|
||||
"vkGetBufferOpaqueCaptureAddressKHR",
|
||||
"vkGetCalibratedTimestampsEXT",
|
||||
"vkGetDeferredOperationMaxConcurrencyKHR",
|
||||
"vkGetDeferredOperationResultKHR",
|
||||
"vkGetDescriptorSetLayoutSupport",
|
||||
"vkGetDescriptorSetLayoutSupportKHR",
|
||||
"vkGetDeviceAccelerationStructureCompatibilityKHR",
|
||||
"vkGetDeviceGroupPeerMemoryFeatures",
|
||||
"vkGetDeviceGroupPeerMemoryFeaturesKHR",
|
||||
"vkGetDeviceGroupPresentCapabilitiesKHR",
|
||||
"vkGetDeviceGroupSurfacePresentModes2EXT",
|
||||
"vkGetDeviceGroupSurfacePresentModesKHR",
|
||||
"vkGetDeviceMemoryCommitment",
|
||||
"vkGetDeviceMemoryOpaqueCaptureAddress",
|
||||
"vkGetDeviceMemoryOpaqueCaptureAddressKHR",
|
||||
"vkGetDeviceProcAddr",
|
||||
"vkGetDeviceQueue",
|
||||
"vkGetDeviceQueue2",
|
||||
"vkGetEventStatus",
|
||||
"vkGetFenceFdKHR",
|
||||
"vkGetFenceStatus",
|
||||
"vkGetFenceWin32HandleKHR",
|
||||
"vkGetGeneratedCommandsMemoryRequirementsNV",
|
||||
"vkGetImageDrmFormatModifierPropertiesEXT",
|
||||
"vkGetImageMemoryRequirements",
|
||||
"vkGetImageMemoryRequirements2",
|
||||
"vkGetImageMemoryRequirements2KHR",
|
||||
"vkGetImageSparseMemoryRequirements",
|
||||
"vkGetImageSparseMemoryRequirements2",
|
||||
"vkGetImageSparseMemoryRequirements2KHR",
|
||||
"vkGetImageSubresourceLayout",
|
||||
"vkGetImageViewAddressNVX",
|
||||
"vkGetImageViewHandleNVX",
|
||||
"vkGetMemoryAndroidHardwareBufferANDROID",
|
||||
"vkGetMemoryFdKHR",
|
||||
"vkGetMemoryFdPropertiesKHR",
|
||||
"vkGetMemoryHostPointerPropertiesEXT",
|
||||
"vkGetMemoryWin32HandleKHR",
|
||||
"vkGetMemoryWin32HandleNV",
|
||||
"vkGetMemoryWin32HandlePropertiesKHR",
|
||||
"vkGetPastPresentationTimingGOOGLE",
|
||||
"vkGetPerformanceParameterINTEL",
|
||||
"vkGetPipelineCacheData",
|
||||
"vkGetPipelineExecutableInternalRepresentationsKHR",
|
||||
"vkGetPipelineExecutablePropertiesKHR",
|
||||
"vkGetPipelineExecutableStatisticsKHR",
|
||||
"vkGetPrivateDataEXT",
|
||||
"vkGetQueryPoolResults",
|
||||
"vkGetQueueCheckpointDataNV",
|
||||
"vkGetRayTracingCaptureReplayShaderGroupHandlesKHR",
|
||||
"vkGetRayTracingShaderGroupHandlesKHR",
|
||||
"vkGetRayTracingShaderGroupHandlesNV",
|
||||
"vkGetRefreshCycleDurationGOOGLE",
|
||||
"vkGetRenderAreaGranularity",
|
||||
"vkGetSemaphoreCounterValue",
|
||||
"vkGetSemaphoreCounterValueKHR",
|
||||
"vkGetSemaphoreFdKHR",
|
||||
"vkGetSemaphoreWin32HandleKHR",
|
||||
"vkGetShaderInfoAMD",
|
||||
"vkGetSwapchainCounterEXT",
|
||||
"vkGetSwapchainImagesKHR",
|
||||
"vkGetSwapchainStatusKHR",
|
||||
"vkGetValidationCacheDataEXT",
|
||||
"vkImportFenceFdKHR",
|
||||
"vkImportFenceWin32HandleKHR",
|
||||
"vkImportSemaphoreFdKHR",
|
||||
"vkImportSemaphoreWin32HandleKHR",
|
||||
"vkInitializePerformanceApiINTEL",
|
||||
"vkInvalidateMappedMemoryRanges",
|
||||
"vkMapMemory",
|
||||
"vkMergePipelineCaches",
|
||||
"vkMergeValidationCachesEXT",
|
||||
"vkQueueBeginDebugUtilsLabelEXT",
|
||||
"vkQueueBindSparse",
|
||||
"vkQueueEndDebugUtilsLabelEXT",
|
||||
"vkQueueInsertDebugUtilsLabelEXT",
|
||||
"vkQueuePresentKHR",
|
||||
"vkQueueSetPerformanceConfigurationINTEL",
|
||||
"vkQueueSubmit",
|
||||
"vkQueueWaitIdle",
|
||||
"vkRegisterDeviceEventEXT",
|
||||
"vkRegisterDisplayEventEXT",
|
||||
"vkReleaseFullScreenExclusiveModeEXT",
|
||||
"vkReleasePerformanceConfigurationINTEL",
|
||||
"vkReleaseProfilingLockKHR",
|
||||
"vkResetCommandBuffer",
|
||||
"vkResetCommandPool",
|
||||
"vkResetDescriptorPool",
|
||||
"vkResetEvent",
|
||||
"vkResetFences",
|
||||
"vkResetQueryPool",
|
||||
"vkResetQueryPoolEXT",
|
||||
"vkSetDebugUtilsObjectNameEXT",
|
||||
"vkSetDebugUtilsObjectTagEXT",
|
||||
"vkSetEvent",
|
||||
"vkSetHdrMetadataEXT",
|
||||
"vkSetLocalDimmingAMD",
|
||||
"vkSetPrivateDataEXT",
|
||||
"vkSignalSemaphore",
|
||||
"vkSignalSemaphoreKHR",
|
||||
"vkTrimCommandPool",
|
||||
"vkTrimCommandPoolKHR",
|
||||
"vkUninitializePerformanceApiINTEL",
|
||||
"vkUnmapMemory",
|
||||
"vkUpdateDescriptorSetWithTemplate",
|
||||
"vkUpdateDescriptorSetWithTemplateKHR",
|
||||
"vkUpdateDescriptorSets",
|
||||
"vkWaitForFences",
|
||||
"vkWaitSemaphores",
|
||||
"vkWaitSemaphoresKHR",
|
||||
"vkWriteAccelerationStructuresPropertiesKHR",
|
||||
}};
|
||||
/* Exists as a workaround for:
|
||||
* https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/issues/2323
|
||||
*
|
||||
* `vkGetDeviceProcAddr` does not return NULL for non-device functions.
|
||||
*/
|
||||
if (!get_device_proc_addr && instance)
|
||||
{
|
||||
get_device_proc_addr = (PFN_vkGetDeviceProcAddr)
|
||||
get_instance_proc_addr(instance, "vkGetDeviceProcAddr");
|
||||
if (user_ptr)
|
||||
{
|
||||
((GE_VK_UserPointer*)user_ptr)->get_device_proc_addr =
|
||||
get_device_proc_addr;
|
||||
}
|
||||
}
|
||||
if (device && get_device_proc_addr &&
|
||||
device_function.find(name) != device_function.end())
|
||||
{
|
||||
PFN_vkVoidFunction ret = get_device_proc_addr(device, name);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Workaround for android vulkan driver return NULL function pointer with
|
||||
// non-NULL instance
|
||||
// See https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkGetInstanceProcAddr.html
|
||||
// Also slient the warnings when loading with NULL instance in android
|
||||
if (strcmp(name, "vkGetInstanceProcAddr") == 0)
|
||||
return (PFN_vkVoidFunction)get_instance_proc_addr;
|
||||
static std::set<std::string> instance_function =
|
||||
{{
|
||||
"vkEnumerateInstanceVersion",
|
||||
"vkEnumerateInstanceExtensionProperties",
|
||||
"vkEnumerateInstanceLayerProperties",
|
||||
"vkCreateInstance",
|
||||
}};
|
||||
if (instance_function.find(name) != instance_function.end())
|
||||
return get_instance_proc_addr(NULL, name);
|
||||
else if (instance == VK_NULL_HANDLE &&
|
||||
instance_function.find(name) == instance_function.end())
|
||||
return NULL;
|
||||
return get_instance_proc_addr(instance, name);
|
||||
} // loader
|
||||
|
||||
namespace GE
|
||||
{
|
||||
GEVulkanDriver::GEVulkanDriver(const SIrrlichtCreationParameters& params,
|
||||
io::IFileSystem* io, SDL_Window* window)
|
||||
: CNullDriver(io, core::dimension2d<u32>(0, 0))
|
||||
{
|
||||
m_physical_device = VK_NULL_HANDLE;
|
||||
m_graphics_queue = VK_NULL_HANDLE;
|
||||
m_present_queue = VK_NULL_HANDLE;
|
||||
m_graphics_family = m_present_family = 0;
|
||||
m_properties = {};
|
||||
m_features = {};
|
||||
|
||||
createInstance(window);
|
||||
|
||||
GE_VK_UserPointer user_ptr = {};
|
||||
user_ptr.instance = m_vk.instance;
|
||||
if (gladLoadVulkanUserPtr(NULL,
|
||||
(GLADuserptrloadfunc)loader, &user_ptr) == 0)
|
||||
{
|
||||
throw std::runtime_error("gladLoadVulkanUserPtr failed "
|
||||
"with non-NULL instance");
|
||||
}
|
||||
if (SDL_Vulkan_CreateSurface(window, m_vk.instance, &m_vk.surface) == SDL_FALSE)
|
||||
throw std::runtime_error("SDL_Vulkan_CreateSurface failed");
|
||||
m_device_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
||||
findPhysicalDevice();
|
||||
createDevice();
|
||||
|
||||
user_ptr.device = m_vk.device;
|
||||
if (gladLoadVulkanUserPtr(m_physical_device,
|
||||
(GLADuserptrloadfunc)loader, &user_ptr) == 0)
|
||||
{
|
||||
throw std::runtime_error("gladLoadVulkanUserPtr failed with "
|
||||
"non-NULL instance and non-NULL m_physical_device");
|
||||
}
|
||||
|
||||
vkGetPhysicalDeviceProperties(m_physical_device, &m_properties);
|
||||
os::Printer::log("Vulkan version", getVulkanVersionString().c_str());
|
||||
os::Printer::log("Vulkan vendor", getVendorInfo().c_str());
|
||||
os::Printer::log("Vulkan renderer", m_properties.deviceName);
|
||||
os::Printer::log("Vulkan driver version", getDriverVersionString().c_str());
|
||||
for (const char* ext : m_device_extensions)
|
||||
os::Printer::log("Vulkan enabled extension", ext);
|
||||
} // GEVulkanDriver
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
GEVulkanDriver::~GEVulkanDriver()
|
||||
{
|
||||
} // ~GEVulkanDriver
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanDriver::createInstance(SDL_Window* window)
|
||||
{
|
||||
if (gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc)loader, NULL) == 0)
|
||||
{
|
||||
throw std::runtime_error("gladLoadVulkanUserPtr failed 1st time");
|
||||
}
|
||||
unsigned int count = 0;
|
||||
if (!SDL_Vulkan_GetInstanceExtensions(window, &count, NULL))
|
||||
throw std::runtime_error("SDL_Vulkan_GetInstanceExtensions failed with NULL extensions");
|
||||
std::vector<const char*> extensions(count, NULL);
|
||||
if (!SDL_Vulkan_GetInstanceExtensions(window, &count, extensions.data()))
|
||||
throw std::runtime_error("SDL_Vulkan_GetInstanceExtensions failed with extensions vector");
|
||||
VkInstanceCreateInfo create_info = {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
create_info.enabledExtensionCount = extensions.size();
|
||||
create_info.ppEnabledExtensionNames = extensions.data();
|
||||
VkResult result = vkCreateInstance(&create_info, NULL, &m_vk.instance);
|
||||
if (result != VK_SUCCESS)
|
||||
throw std::runtime_error("vkCreateInstance failed");
|
||||
} // createInstance
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanDriver::findPhysicalDevice()
|
||||
{
|
||||
uint32_t device_count = 0;
|
||||
vkEnumeratePhysicalDevices(m_vk.instance, &device_count, NULL);
|
||||
|
||||
if (device_count < 1)
|
||||
throw std::runtime_error("findPhysicalDevice has < 1 device_count");
|
||||
|
||||
std::vector<VkPhysicalDevice> devices(device_count);
|
||||
vkEnumeratePhysicalDevices(m_vk.instance, &device_count, &devices[0]);
|
||||
|
||||
for (VkPhysicalDevice& device : devices)
|
||||
{
|
||||
uint32_t graphics_family = 0;
|
||||
uint32_t present_family = 0;
|
||||
|
||||
bool success = findQueueFamilies(device, &graphics_family, &present_family);
|
||||
|
||||
if (!success)
|
||||
continue;
|
||||
|
||||
success = checkDeviceExtensions(device);
|
||||
|
||||
if (!success)
|
||||
continue;
|
||||
|
||||
VkSurfaceCapabilitiesKHR surface_capabilities;
|
||||
std::vector<VkSurfaceFormatKHR> surface_formats;
|
||||
std::vector<VkPresentModeKHR> present_modes;
|
||||
|
||||
success = updateSurfaceInformation(device, &surface_capabilities,
|
||||
&surface_formats, &present_modes);
|
||||
|
||||
if (!success)
|
||||
continue;
|
||||
|
||||
vkGetPhysicalDeviceFeatures(device, &m_features);
|
||||
m_graphics_family = graphics_family;
|
||||
m_present_family = present_family;
|
||||
m_surface_capabilities = surface_capabilities;
|
||||
m_surface_formats = surface_formats;
|
||||
m_present_modes = present_modes;
|
||||
m_physical_device = device;
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_physical_device == VK_NULL_HANDLE)
|
||||
throw std::runtime_error("findPhysicalDevice m_physical_device is VK_NULL_HANDLE");
|
||||
} // findPhysicalDevice
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool GEVulkanDriver::checkDeviceExtensions(VkPhysicalDevice device)
|
||||
{
|
||||
uint32_t extension_count;
|
||||
vkEnumerateDeviceExtensionProperties(device, NULL, &extension_count, NULL);
|
||||
|
||||
std::vector<VkExtensionProperties> extensions(extension_count);
|
||||
vkEnumerateDeviceExtensionProperties(device, NULL, &extension_count,
|
||||
&extensions[0]);
|
||||
|
||||
std::set<std::string> required_extensions(m_device_extensions.begin(),
|
||||
m_device_extensions.end());
|
||||
|
||||
for (VkExtensionProperties& extension : extensions)
|
||||
required_extensions.erase(extension.extensionName);
|
||||
|
||||
return required_extensions.empty();
|
||||
} // checkDeviceExtensions
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool GEVulkanDriver::updateSurfaceInformation(VkPhysicalDevice device,
|
||||
VkSurfaceCapabilitiesKHR* surface_capabilities,
|
||||
std::vector<VkSurfaceFormatKHR>* surface_formats,
|
||||
std::vector<VkPresentModeKHR>* present_modes)
|
||||
{
|
||||
uint32_t format_count;
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR(device, m_vk.surface, &format_count, NULL);
|
||||
|
||||
if (format_count < 1)
|
||||
return false;
|
||||
|
||||
uint32_t mode_count;
|
||||
vkGetPhysicalDeviceSurfacePresentModesKHR(device, m_vk.surface, &mode_count, NULL);
|
||||
|
||||
if (mode_count < 1)
|
||||
return false;
|
||||
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, m_vk.surface, surface_capabilities);
|
||||
|
||||
(*surface_formats).resize(format_count);
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR(device, m_vk.surface, &format_count,
|
||||
&(*surface_formats)[0]);
|
||||
|
||||
(*present_modes).resize(mode_count);
|
||||
vkGetPhysicalDeviceSurfacePresentModesKHR(device, m_vk.surface, &mode_count,
|
||||
&(*present_modes)[0]);
|
||||
|
||||
return true;
|
||||
} // updateSurfaceInformation
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool GEVulkanDriver::findQueueFamilies(VkPhysicalDevice device,
|
||||
uint32_t* graphics_family,
|
||||
uint32_t* present_family)
|
||||
{
|
||||
uint32_t queue_family_count = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, NULL);
|
||||
if (queue_family_count == 0)
|
||||
return false;
|
||||
|
||||
std::vector<VkQueueFamilyProperties> queue_families(queue_family_count);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count,
|
||||
&queue_families[0]);
|
||||
|
||||
bool found_graphics_family = false;
|
||||
bool found_present_family = false;
|
||||
|
||||
for (unsigned int i = 0; i < queue_families.size(); i++)
|
||||
{
|
||||
if (queue_families[i].queueCount > 0 &&
|
||||
queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
||||
{
|
||||
*graphics_family = i;
|
||||
found_graphics_family = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < queue_families.size(); i++)
|
||||
{
|
||||
VkBool32 present_support = false;
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, m_vk.surface, &present_support);
|
||||
|
||||
if (queue_families[i].queueCount > 0 && present_support)
|
||||
{
|
||||
*present_family = i;
|
||||
found_present_family = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found_graphics_family && found_present_family;
|
||||
} // findQueueFamilies
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanDriver::createDevice()
|
||||
{
|
||||
std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
|
||||
float queue_priority = 1.0f;
|
||||
|
||||
VkDeviceQueueCreateInfo queue_create_info = {};
|
||||
queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||
queue_create_info.queueFamilyIndex = m_graphics_family;
|
||||
queue_create_info.queueCount = 1;
|
||||
queue_create_info.pQueuePriorities = &queue_priority;
|
||||
queue_create_infos.push_back(queue_create_info);
|
||||
|
||||
queue_create_info.queueFamilyIndex = m_present_family;
|
||||
queue_create_infos.push_back(queue_create_info);
|
||||
|
||||
VkPhysicalDeviceFeatures device_features = {};
|
||||
if (m_features.samplerAnisotropy == VK_TRUE)
|
||||
device_features.samplerAnisotropy = VK_TRUE;
|
||||
|
||||
VkDeviceCreateInfo create_info = {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
create_info.queueCreateInfoCount = queue_create_infos.size();
|
||||
create_info.pQueueCreateInfos = &queue_create_infos[0];
|
||||
create_info.pEnabledFeatures = &device_features;
|
||||
create_info.enabledExtensionCount = m_device_extensions.size();
|
||||
create_info.ppEnabledExtensionNames = &m_device_extensions[0];
|
||||
create_info.enabledLayerCount = 0;
|
||||
|
||||
VkResult result = vkCreateDevice(m_physical_device, &create_info, NULL, &m_vk.device);
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
throw std::runtime_error("vkCreateDevice failed");
|
||||
|
||||
vkGetDeviceQueue(m_vk.device, m_graphics_family, 0, &m_graphics_queue);
|
||||
vkGetDeviceQueue(m_vk.device, m_present_family, 0, &m_present_queue);
|
||||
} // createDevice
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string GEVulkanDriver::getVulkanVersionString() const
|
||||
{
|
||||
std::stringstream vk_version;
|
||||
vk_version << VK_VERSION_MAJOR(m_properties.apiVersion) << "." <<
|
||||
VK_VERSION_MINOR(m_properties.apiVersion) << "." <<
|
||||
VK_VERSION_PATCH(m_properties.apiVersion);
|
||||
return vk_version.str();
|
||||
} // getVulkanVersionString
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string GEVulkanDriver::getDriverVersionString() const
|
||||
{
|
||||
#ifdef WIN32
|
||||
bool is_win = true;
|
||||
#else
|
||||
bool is_win = false;
|
||||
#endif
|
||||
|
||||
std::stringstream driver_version;
|
||||
// Following https://github.com/SaschaWillems/vulkan.gpuinfo.org/blob/master/includes/functions.php
|
||||
if (m_properties.vendorID == 0x10DE)
|
||||
{
|
||||
// NVIDIA
|
||||
driver_version << ((m_properties.driverVersion >> 22) & 0x3ff) << "." <<
|
||||
((m_properties.driverVersion >> 14) & 0xff) << "." <<
|
||||
((m_properties.driverVersion >> 6) & 0xff) << "." <<
|
||||
(m_properties.driverVersion & 0x3f);
|
||||
}
|
||||
else if (m_properties.vendorID == 0x8086 && is_win)
|
||||
{
|
||||
// Intel on Windows
|
||||
driver_version << (m_properties.driverVersion >> 14) << "." <<
|
||||
(m_properties.driverVersion & 0x3fff);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use Vulkan version conventions if vendor mapping is not available
|
||||
driver_version << VK_VERSION_MAJOR(m_properties.driverVersion) << "." <<
|
||||
VK_VERSION_MINOR(m_properties.driverVersion) << "." <<
|
||||
VK_VERSION_PATCH(m_properties.driverVersion);
|
||||
}
|
||||
return driver_version.str();
|
||||
} // getDriverVersionString
|
||||
|
||||
}
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace video
|
||||
{
|
||||
IVideoDriver* createVulkanDriver(const SIrrlichtCreationParameters& params,
|
||||
io::IFileSystem* io, SDL_Window* window)
|
||||
{
|
||||
return new GE::GEVulkanDriver(params, io, window);
|
||||
} // createVulkanDriver
|
||||
}
|
||||
}
|
||||
#endif
|
@ -7,7 +7,8 @@ if(NOT SERVER_ONLY)
|
||||
"${JPEG_INCLUDE_DIR}"
|
||||
"${PNG_INCLUDE_DIRS}"
|
||||
"${ZLIB_INCLUDE_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../src"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../graphics_engine/include")
|
||||
else()
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include/"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
@ -25,6 +26,8 @@ else()
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_X11_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_WAYLAND_DEVICE_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_SDL_DEVICE_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_DIRECT3D_9_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_VULKAN_)
|
||||
endif()
|
||||
|
||||
if(APPLE AND NOT IOS)
|
||||
|
@ -56,6 +56,9 @@ namespace video
|
||||
/** Supports shaders etc. */
|
||||
EDT_OGLES2,
|
||||
|
||||
//! A driver using vulkan coded by STK
|
||||
EDT_VULKAN,
|
||||
|
||||
//! No driver, just for counting the elements
|
||||
EDT_COUNT
|
||||
};
|
||||
|
@ -43,6 +43,11 @@
|
||||
//! different library versions without having to change the sources.
|
||||
//! Example: NO_IRR_COMPILE_WITH_X11_ would disable X11
|
||||
|
||||
#if defined(NO_IRR_COMPILE_WITH_VULKAN_)
|
||||
#undef _IRR_COMPILE_WITH_VULKAN_
|
||||
#else
|
||||
#define _IRR_COMPILE_WITH_VULKAN_
|
||||
#endif
|
||||
|
||||
//! Uncomment this line to compile with the SDL device
|
||||
//#define _IRR_COMPILE_WITH_SDL_DEVICE_
|
||||
|
@ -362,6 +362,12 @@ namespace irr
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
case video::EDT_VULKAN:
|
||||
#ifdef _IRR_COMPILE_WITH_VULKAN_
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
|
@ -36,6 +36,10 @@ namespace irr
|
||||
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
|
||||
IVideoDriver* createDirectX9Driver(const SIrrlichtCreationParameters& params,
|
||||
io::IFileSystem* io, HWND window);
|
||||
#endif
|
||||
#ifdef _IRR_COMPILE_WITH_VULKAN_
|
||||
IVideoDriver* createVulkanDriver(const SIrrlichtCreationParameters& params,
|
||||
io::IFileSystem* io, SDL_Window* win);
|
||||
#endif
|
||||
} // end namespace video
|
||||
|
||||
@ -354,6 +358,8 @@ bool CIrrDeviceSDL::createWindow()
|
||||
if (CreationParams.DriverType == video::EDT_OPENGL ||
|
||||
CreationParams.DriverType == video::EDT_OGLES2)
|
||||
flags |= SDL_WINDOW_OPENGL;
|
||||
else if (CreationParams.DriverType == video::EDT_VULKAN)
|
||||
flags |= SDL_WINDOW_VULKAN;
|
||||
|
||||
#ifdef MOBILE_STK
|
||||
flags |= SDL_WINDOW_BORDERLESS | SDL_WINDOW_MAXIMIZED;
|
||||
@ -580,6 +586,23 @@ void CIrrDeviceSDL::createDriver()
|
||||
break;
|
||||
}
|
||||
|
||||
case video::EDT_VULKAN:
|
||||
{
|
||||
#ifdef _IRR_COMPILE_WITH_VULKAN_
|
||||
try
|
||||
{
|
||||
VideoDriver = video::createVulkanDriver(CreationParams, FileSystem, Window);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
os::Printer::log("createVulkanDriver failed", e.what(), ELL_ERROR);
|
||||
}
|
||||
#else
|
||||
os::Printer::log("No Vulkan support compiled in.", ELL_ERROR);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case video::EDT_DIRECT3D9:
|
||||
{
|
||||
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
|
||||
|
@ -402,6 +402,10 @@ void IrrDriver::initDevice()
|
||||
{
|
||||
driver_created = video::EDT_DIRECT3D9;
|
||||
}
|
||||
else if (std::string(UserConfigParams::m_render_driver) == "vulkan")
|
||||
{
|
||||
driver_created = video::EDT_VULKAN;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("IrrDriver", "Unknown driver %s, revert to gl",
|
||||
@ -414,6 +418,7 @@ void IrrDriver::initDevice()
|
||||
#endif
|
||||
}
|
||||
|
||||
m_logger_level = irr::ELL_INFORMATION;
|
||||
#ifndef __SWITCH__
|
||||
// If --no-graphics option was used, the null device can still be used.
|
||||
if (!GUIEngine::isNoGraphics())
|
||||
@ -633,6 +638,7 @@ void IrrDriver::initDevice()
|
||||
CVS->init();
|
||||
}
|
||||
#endif
|
||||
m_logger_level = irr::ELL_WARNING;
|
||||
|
||||
m_scene_manager = m_device->getSceneManager();
|
||||
m_gui_env = m_device->getGUIEnvironment();
|
||||
|
Loading…
Reference in New Issue
Block a user