Renderer: Add ShaderStage class

This commit is contained in:
Lynix 2020-02-29 23:28:21 +01:00
parent 798425ce10
commit 5d449095bf
13 changed files with 190 additions and 39 deletions

View File

@ -56,29 +56,6 @@ int main()
instance.vkCreateDebugReportCallbackEXT(instance, &callbackCreateInfo, nullptr, &callback);
Nz::File shaderFile;
std::vector<Nz::UInt8> vertexShaderCode;
std::vector<Nz::UInt8> fragmentShaderCode;
if (!shaderFile.Open("resources/shaders/triangle.vert.spv", Nz::OpenMode_ReadOnly))
{
NazaraError("Failed to open vertex shader code");
return __LINE__;
}
vertexShaderCode.resize(shaderFile.GetSize());
shaderFile.Read(vertexShaderCode.data(), vertexShaderCode.size());
if (!shaderFile.Open("resources/shaders/triangle.frag.spv", Nz::OpenMode_ReadOnly))
{
NazaraError("Failed to open fragment shader code");
return __LINE__;
}
fragmentShaderCode.resize(shaderFile.GetSize());
shaderFile.Read(fragmentShaderCode.data(), fragmentShaderCode.size());
shaderFile.Close();
std::vector<VkLayerProperties> layerProperties;
if (!Nz::Vk::Loader::EnumerateInstanceLayerProperties(&layerProperties))
@ -124,6 +101,20 @@ int main()
std::shared_ptr<Nz::RenderDevice> device = window.GetRenderDevice();
auto fragmentShader = device->InstantiateShaderStage(Nz::ShaderStageType::Fragment, Nz::ShaderLanguage::SpirV, "resources/shaders/triangle.frag.spv");
if (!fragmentShader)
{
std::cout << "Failed to instantiate fragment shader" << std::endl;
return __LINE__;
}
auto vertexShader = device->InstantiateShaderStage(Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::SpirV, "resources/shaders/triangle.vert.spv");
if (!vertexShader)
{
std::cout << "Failed to instantiate fragment shader" << std::endl;
return __LINE__;
}
Nz::VkRenderWindow& vulkanWindow = *static_cast<Nz::VkRenderWindow*>(window.GetImpl());
/*VkPhysicalDeviceFeatures features;
@ -140,20 +131,6 @@ int main()
Nz::VulkanDevice& vulkanDevice = vulkanWindow.GetDevice();
Nz::Vk::ShaderModule vertexShader;
if (!vertexShader.Create(vulkanDevice.shared_from_this(), reinterpret_cast<Nz::UInt32*>(vertexShaderCode.data()), vertexShaderCode.size()))
{
NazaraError("Failed to create vertex shader");
return __LINE__;
}
Nz::Vk::ShaderModule fragmentShader;
if (!fragmentShader.Create(vulkanDevice.shared_from_this(), reinterpret_cast<Nz::UInt32*>(fragmentShaderCode.data()), fragmentShaderCode.size()))
{
NazaraError("Failed to create fragment shader");
return __LINE__;
}
Nz::MeshRef drfreak = Nz::Mesh::LoadFromFile("resources/OILTANK1.md2", meshParams);
if (!drfreak)
@ -297,7 +274,7 @@ int main()
nullptr,
0,
VK_SHADER_STAGE_VERTEX_BIT,
vertexShader,
static_cast<Nz::VulkanShaderStage*>(vertexShader.get())->GetHandle(),
"main",
nullptr
},
@ -306,7 +283,7 @@ int main()
nullptr,
0,
VK_SHADER_STAGE_FRAGMENT_BIT,
fragmentShader,
static_cast<Nz::VulkanShaderStage*>(fragmentShader.get())->GetHandle(),
"main",
nullptr
}

View File

@ -47,6 +47,7 @@
#include <Nazara/Renderer/Shader.hpp>
#include <Nazara/Renderer/ShaderAst.hpp>
#include <Nazara/Renderer/ShaderBuilder.hpp>
#include <Nazara/Renderer/ShaderStageImpl.hpp>
#include <Nazara/Renderer/ShaderWriter.hpp>
#include <Nazara/Renderer/Texture.hpp>

View File

@ -33,6 +33,20 @@ namespace Nz
RenderDeviceType_Max = RenderDeviceType_Unknown
};
enum class ShaderLanguage
{
GLSL,
HLSL,
MSL,
SpirV
};
enum class ShaderStageType
{
Fragment,
Vertex
};
}
#endif // NAZARA_ENUMS_RENDERER_HPP

View File

@ -9,13 +9,16 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/RenderPipeline.hpp>
#include <Nazara/Utility/AbstractBuffer.hpp>
#include <memory>
#include <string>
namespace Nz
{
class Buffer;
class ShaderStageImpl;
class NAZARA_RENDERER_API RenderDevice
{
@ -25,6 +28,8 @@ namespace Nz
virtual std::unique_ptr<AbstractBuffer> InstantiateBuffer(Buffer* parent, BufferType type) = 0;
virtual std::unique_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) = 0;
virtual std::shared_ptr<ShaderStageImpl> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) = 0;
std::shared_ptr<ShaderStageImpl> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const std::filesystem::path& sourcePath);
};
}

View File

@ -0,0 +1,24 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_RENDERER_SHADERSTAGEIMPL_HPP
#define NAZARA_RENDERER_SHADERSTAGEIMPL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Enums.hpp>
namespace Nz
{
class NAZARA_RENDERER_API ShaderStageImpl
{
public:
ShaderStageImpl() = default;
virtual ~ShaderStageImpl();
};
}
#endif // NAZARA_RENDERER_SHADERSTAGEIMPL_HPP

View File

@ -38,6 +38,7 @@
#include <Nazara/VulkanRenderer/VulkanDevice.hpp>
#include <Nazara/VulkanRenderer/VulkanRenderer.hpp>
#include <Nazara/VulkanRenderer/VulkanRenderPipeline.hpp>
#include <Nazara/VulkanRenderer/VulkanShaderStage.hpp>
#include <Nazara/VulkanRenderer/VulkanSurface.hpp>
#include <Nazara/VulkanRenderer/Wrapper.hpp>

View File

@ -25,6 +25,7 @@ namespace Nz
std::unique_ptr<AbstractBuffer> InstantiateBuffer(Buffer* parent, BufferType type) override;
std::unique_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) override;
std::shared_ptr<ShaderStageImpl> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) override;
VulkanDevice& operator=(const VulkanDevice&) = delete;
VulkanDevice& operator=(VulkanDevice&&) = delete; ///TODO?

View File

@ -0,0 +1,41 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Vulkan Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_VULKANRENDERER_VULKANSHADERSTAGE_HPP
#define NAZARA_VULKANRENDERER_VULKANSHADERSTAGE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/ShaderStageImpl.hpp>
#include <Nazara/VulkanRenderer/Wrapper/ShaderModule.hpp>
#include <vector>
namespace Nz
{
class NAZARA_VULKANRENDERER_API VulkanShaderStage : public ShaderStageImpl
{
public:
VulkanShaderStage() = default;
VulkanShaderStage(const VulkanShaderStage&) = delete;
VulkanShaderStage(VulkanShaderStage&&) noexcept = default;
~VulkanShaderStage() = default;
bool Create(const Vk::DeviceHandle& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize);
inline const Vk::ShaderModule& GetHandle() const;
VulkanShaderStage& operator=(const VulkanShaderStage&) = delete;
VulkanShaderStage& operator=(VulkanShaderStage&&) noexcept = default;
private:
Vk::ShaderModule m_shaderModule;
ShaderStageType m_stage;
};
}
#include <Nazara/VulkanRenderer/VulkanShaderStage.inl>
#endif // NAZARA_VULKANRENDERER_VULKANSHADERSTAGE_HPP

View File

@ -0,0 +1,16 @@
// Copyright (C) 2016 Jérôme Leclercq
// This file is part of the "Nazara Engine - Vulkan Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/VulkanRenderer/VulkanShaderStage.hpp>
#include <Nazara/VulkanRenderer/Debug.hpp>
namespace Nz
{
inline const Vk::ShaderModule& VulkanShaderStage::GetHandle() const
{
return m_shaderModule;
}
}
#include <Nazara/VulkanRenderer/DebugOff.hpp>

View File

@ -3,9 +3,32 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/RenderDevice.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/File.hpp>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
RenderDevice::~RenderDevice() = default;
std::shared_ptr<ShaderStageImpl> RenderDevice::InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const std::filesystem::path& sourcePath)
{
File file(sourcePath);
if (!file.Open(OpenMode_ReadOnly | OpenMode_Text))
{
NazaraError("Failed to open \"" + sourcePath.generic_u8string() + '"');
return {};
}
std::size_t length = static_cast<std::size_t>(file.GetSize());
std::vector<Nz::UInt8> source(length);
if (file.Read(&source[0], length) != length)
{
NazaraError("Failed to read program file");
return {};
}
return InstantiateShaderStage(type, lang, source.data(), source.size());
}
}

View File

@ -0,0 +1,11 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/ShaderStageImpl.hpp>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
ShaderStageImpl::~ShaderStageImpl() = default;
}

View File

@ -4,6 +4,7 @@
#include <Nazara/VulkanRenderer/VulkanDevice.hpp>
#include <Nazara/VulkanRenderer/VulkanRenderPipeline.hpp>
#include <Nazara/VulkanRenderer/VulkanShaderStage.hpp>
#include <Nazara/VulkanRenderer/Debug.hpp>
namespace Nz
@ -19,4 +20,13 @@ namespace Nz
{
return std::make_unique<VulkanRenderPipeline>(shared_from_this(), std::move(pipelineInfo));
}
std::shared_ptr<ShaderStageImpl> VulkanDevice::InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
{
auto stage = std::make_shared<VulkanShaderStage>();
if (!stage->Create(shared_from_this(), type, lang, source, sourceSize))
return {};
return stage;
}
}

View File

@ -0,0 +1,27 @@
// Copyright (C) 2016 Jérôme Leclercq
// This file is part of the "Nazara Engine - Vulkan Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/VulkanRenderer/VulkanShaderStage.hpp>
#include <Nazara/VulkanRenderer/Debug.hpp>
namespace Nz
{
bool VulkanShaderStage::Create(const Vk::DeviceHandle& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
{
if (lang != ShaderLanguage::SpirV)
{
NazaraError("Only Spir-V is supported for now");
return false;
}
if (!m_shaderModule.Create(device, reinterpret_cast<const Nz::UInt32*>(source), sourceSize))
{
NazaraError("Failed to create shader module");
return false;
}
m_stage = type;
return true;
}
}