Add GEVulkanShaderManager
This commit is contained in:
12
data/shaders/ge_shaders/2d_render.frag
Normal file
12
data/shaders/ge_shaders/2d_render.frag
Normal file
@@ -0,0 +1,12 @@
|
||||
layout(location = 0) in vec4 f_color;
|
||||
layout(location = 1) in vec2 f_uv;
|
||||
layout(location = 2) flat in int f_sampler_index;
|
||||
|
||||
layout(binding = 0) uniform sampler2D f_tex[SAMPLER_SIZE];
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
o_color = texture(f_tex[f_sampler_index], f_uv) * f_color;
|
||||
}
|
||||
16
data/shaders/ge_shaders/2d_render.vert
Normal file
16
data/shaders/ge_shaders/2d_render.vert
Normal file
@@ -0,0 +1,16 @@
|
||||
layout(location = 0) in vec2 v_position;
|
||||
layout(location = 1) in vec4 v_color;
|
||||
layout(location = 2) in vec2 v_uv;
|
||||
layout(location = 3) in int v_sampler_index;
|
||||
|
||||
layout(location = 0) out vec4 f_color;
|
||||
layout(location = 1) out vec2 f_uv;
|
||||
layout(location = 2) flat out int f_sampler_index;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(v_position, 0.0, 1.0);
|
||||
f_color = v_color.zyxw;
|
||||
f_uv = v_uv;
|
||||
f_sampler_index = v_sampler_index;
|
||||
}
|
||||
@@ -26,6 +26,7 @@ set(GE_SOURCES
|
||||
src/ge_texture.cpp
|
||||
src/ge_dx9_texture.cpp
|
||||
src/ge_vulkan_driver.cpp
|
||||
src/ge_vulkan_shader_manager.cpp
|
||||
src/ge_vulkan_texture.cpp
|
||||
src/ge_gl_texture.cpp
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define HEADER_GE_MAIN_HPP
|
||||
|
||||
#include <IVideoDriver.h>
|
||||
#include <string>
|
||||
|
||||
namespace GE
|
||||
{
|
||||
@@ -11,9 +12,11 @@ struct GEConfig
|
||||
bool m_disable_npot_texture;
|
||||
};
|
||||
|
||||
void init(irr::video::IVideoDriver* driver);
|
||||
void setVideoDriver(irr::video::IVideoDriver* driver);
|
||||
void setShaderFolder(const std::string& path);
|
||||
irr::video::IVideoDriver* getDriver();
|
||||
GE::GEVulkanDriver* getVKDriver();
|
||||
const std::string& getShaderFolder();
|
||||
GEConfig* getGEConfig();
|
||||
void deinit();
|
||||
}
|
||||
|
||||
@@ -275,18 +275,17 @@ namespace GE
|
||||
return m_vk->samplers.at(s);
|
||||
}
|
||||
VkDevice getDevice() const { return m_vk->device; }
|
||||
void destroyVulkan()
|
||||
{
|
||||
delete m_vk.get();
|
||||
m_vk.release();
|
||||
}
|
||||
void destroyVulkan();
|
||||
bool createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
|
||||
VkMemoryPropertyFlags properties, VkBuffer& buffer,
|
||||
VkDeviceMemory& buffer_memory);
|
||||
VkPhysicalDevice getPhysicalDevice() const { return m_physical_device; }
|
||||
void waitIdle() { vkQueueWaitIdle(m_graphics_queue); }
|
||||
const VkPhysicalDeviceProperties& getPhysicalDeviceProperties() const
|
||||
{ return m_properties; }
|
||||
VkCommandBuffer beginSingleTimeCommands();
|
||||
void endSingleTimeCommands(VkCommandBuffer command_buffer);
|
||||
io::IFileSystem* getFileSystem() const { return FileSystem; }
|
||||
|
||||
private:
|
||||
struct SwapChainSupportDetails
|
||||
|
||||
@@ -5,8 +5,9 @@ namespace GE
|
||||
{
|
||||
irr::video::IVideoDriver* g_driver = NULL;
|
||||
GEConfig g_config = {};
|
||||
std::string g_shader_folder = "";
|
||||
|
||||
void init(irr::video::IVideoDriver* driver)
|
||||
void setVideoDriver(irr::video::IVideoDriver* driver)
|
||||
{
|
||||
g_driver = driver;
|
||||
}
|
||||
@@ -26,6 +27,16 @@ GEConfig* getGEConfig()
|
||||
return &g_config;
|
||||
}
|
||||
|
||||
void setShaderFolder(const std::string& path)
|
||||
{
|
||||
g_shader_folder = path + "ge_shaders/";
|
||||
}
|
||||
|
||||
const std::string& getShaderFolder()
|
||||
{
|
||||
return g_shader_folder;
|
||||
}
|
||||
|
||||
void deinit()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "ge_vulkan_driver.hpp"
|
||||
|
||||
#include "ge_vulkan_shader_manager.hpp"
|
||||
|
||||
#ifdef _IRR_COMPILE_WITH_VULKAN_
|
||||
const unsigned int MAX_FRAMES_IN_FLIGHT = 2;
|
||||
#include "SDL_vulkan.h"
|
||||
@@ -491,6 +493,7 @@ GEVulkanDriver::GEVulkanDriver(const SIrrlichtCreationParameters& params,
|
||||
createCommandPool();
|
||||
createCommandBuffers();
|
||||
createSamplers();
|
||||
GEVulkanShaderManager::init(this);
|
||||
os::Printer::log("Vulkan version", getVulkanVersionString().c_str());
|
||||
os::Printer::log("Vulkan vendor", getVendorInfo().c_str());
|
||||
os::Printer::log("Vulkan renderer", m_properties.deviceName);
|
||||
@@ -504,6 +507,14 @@ GEVulkanDriver::~GEVulkanDriver()
|
||||
{
|
||||
} // ~GEVulkanDriver
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanDriver::destroyVulkan()
|
||||
{
|
||||
GEVulkanShaderManager::destroy();
|
||||
delete m_vk.get();
|
||||
m_vk.release();
|
||||
} // destroyVulkan
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanDriver::createInstance(SDL_Window* window)
|
||||
{
|
||||
|
||||
102
lib/graphics_engine/src/ge_vulkan_shader_manager.cpp
Normal file
102
lib/graphics_engine/src/ge_vulkan_shader_manager.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#include "ge_vulkan_shader_manager.hpp"
|
||||
|
||||
#include "ge_main.hpp"
|
||||
#include "ge_vulkan_driver.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "IFileSystem.h"
|
||||
|
||||
namespace GE
|
||||
{
|
||||
// ============================================================================
|
||||
GEVulkanDriver* g_vk = NULL;
|
||||
irr::io::IFileSystem* g_file_system = NULL;
|
||||
|
||||
std::string g_predefines = "";
|
||||
uint32_t g_sampler_size = 0;
|
||||
|
||||
VkShaderModule g_2d_render_vert = VK_NULL_HANDLE;
|
||||
VkShaderModule g_2d_render_frag = VK_NULL_HANDLE;
|
||||
// ============================================================================
|
||||
void GEVulkanShaderManager::init(GEVulkanDriver* vk)
|
||||
{
|
||||
g_vk = vk;
|
||||
g_file_system = vk->getFileSystem();
|
||||
|
||||
VkPhysicalDeviceLimits limit = g_vk->getPhysicalDeviceProperties().limits;
|
||||
// According to https://vulkan.gpuinfo.org/displaydevicelimit.php?name=maxDescriptorSetSampledImages&platform=all
|
||||
// almost all users have at least 96
|
||||
if (limit.maxDescriptorSetSampledImages < 96)
|
||||
throw std::runtime_error("maxDescriptorSetSampledImages is too low");
|
||||
g_sampler_size = 96;
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "#version 450\n";
|
||||
oss << "#define SAMPLER_SIZE " << g_sampler_size << "\n";
|
||||
g_predefines = oss.str();
|
||||
|
||||
// 2D rendering shader
|
||||
g_2d_render_vert = loadShader(shaderc_vertex_shader, "2d_render.vert");
|
||||
g_2d_render_frag = loadShader(shaderc_fragment_shader, "2d_render.frag");
|
||||
} // init
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanShaderManager::destroy()
|
||||
{
|
||||
vkDestroyShaderModule(g_vk->getDevice(), g_2d_render_vert, NULL);
|
||||
vkDestroyShaderModule(g_vk->getDevice(), g_2d_render_frag, NULL);
|
||||
} // destroy
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
VkShaderModule GEVulkanShaderManager::loadShader(shaderc_shader_kind kind,
|
||||
const std::string& name)
|
||||
{
|
||||
std::string shader_fullpath = getShaderFolder() + name;
|
||||
irr::io::IReadFile* r =
|
||||
g_file_system->createAndOpenFile(shader_fullpath.c_str());
|
||||
if (!r)
|
||||
{
|
||||
throw std::runtime_error(std::string("File ") + shader_fullpath +
|
||||
" is missing");
|
||||
}
|
||||
|
||||
std::string shader_data;
|
||||
shader_data.resize(r->getSize());
|
||||
int nb_read = 0;
|
||||
if ((nb_read = r->read(&shader_data[0], r->getSize())) != r->getSize())
|
||||
{
|
||||
r->drop();
|
||||
throw std::runtime_error(
|
||||
std::string("File ") + name + " failed to be read");
|
||||
}
|
||||
r->drop();
|
||||
shader_data = g_predefines + shader_data;
|
||||
|
||||
shaderc::Compiler compiler;
|
||||
shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(
|
||||
shader_data, kind, shader_fullpath.c_str());
|
||||
if (module.GetCompilationStatus() != shaderc_compilation_status_success)
|
||||
throw std::runtime_error(module.GetErrorMessage());
|
||||
|
||||
std::vector<uint32_t> shader_bytecode(module.cbegin(), module.cend());
|
||||
VkShaderModuleCreateInfo create_info = {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
create_info.pNext = NULL;
|
||||
create_info.codeSize = shader_bytecode.size() * sizeof(uint32_t);
|
||||
create_info.pCode = shader_bytecode.data();
|
||||
|
||||
VkShaderModule shader_module;
|
||||
if (vkCreateShaderModule(g_vk->getDevice(), &create_info, NULL,
|
||||
&shader_module) != VK_SUCCESS)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
std::string("vkCreateShaderModule failed for ") + name);
|
||||
}
|
||||
return shader_module;
|
||||
} // loadShader
|
||||
|
||||
}
|
||||
23
lib/graphics_engine/src/ge_vulkan_shader_manager.hpp
Normal file
23
lib/graphics_engine/src/ge_vulkan_shader_manager.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef HEADER_GE_VULKAN_SHADER_MANAGER_HPP
|
||||
#define HEADER_GE_VULKAN_SHADER_MANAGER_HPP
|
||||
|
||||
#include "vulkan_wrapper.h"
|
||||
#include <string>
|
||||
#include <shaderc/shaderc.hpp>
|
||||
|
||||
namespace GE
|
||||
{
|
||||
class GEVulkanDriver;
|
||||
namespace GEVulkanShaderManager
|
||||
{
|
||||
// ----------------------------------------------------------------------------
|
||||
void init(GEVulkanDriver*);
|
||||
// ----------------------------------------------------------------------------
|
||||
void destroy();
|
||||
// ----------------------------------------------------------------------------
|
||||
VkShaderModule loadShader(shaderc_shader_kind, const std::string&);
|
||||
}; // GEVulkanShaderManager
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -388,6 +388,9 @@ void IrrDriver::createListOfVideoModes()
|
||||
*/
|
||||
void IrrDriver::initDevice()
|
||||
{
|
||||
#if !defined(SERVER_ONLY)
|
||||
GE::setShaderFolder(file_manager->getShadersDir());
|
||||
#endif
|
||||
SIrrlichtCreationParameters params;
|
||||
|
||||
video::E_DRIVER_TYPE driver_created = video::EDT_NULL;
|
||||
@@ -596,7 +599,7 @@ void IrrDriver::initDevice()
|
||||
}
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
GE::init(m_device->getVideoDriver());
|
||||
GE::setVideoDriver(m_device->getVideoDriver());
|
||||
// Assume sp is supported
|
||||
CentralVideoSettings::m_supports_sp = true;
|
||||
CVS->init();
|
||||
@@ -635,7 +638,7 @@ void IrrDriver::initDevice()
|
||||
Log::fatal("irr_driver", "Couldn't initialise irrlicht device. Quitting.\n");
|
||||
}
|
||||
|
||||
GE::init(m_device->getVideoDriver());
|
||||
GE::setVideoDriver(m_device->getVideoDriver());
|
||||
CVS->init();
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user