OpenGL: Implement ShaderStage

This commit is contained in:
Lynix 2020-04-19 01:38:38 +02:00
parent 9dd208c3cf
commit 506099fcd7
7 changed files with 99 additions and 268 deletions

View File

@ -10,7 +10,8 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/ShaderStageImpl.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/ShaderModule.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Context.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Shader.hpp>
#include <vector>
namespace Nz
@ -23,17 +24,13 @@ namespace Nz
OpenGLShaderStage(OpenGLShaderStage&&) noexcept = default;
~OpenGLShaderStage() = default;
bool Create(Vk::Device& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize);
inline const Vk::ShaderModule& GetHandle() const;
inline ShaderStageType GetStageType() const;
bool Create(OpenGLDevice& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize);
OpenGLShaderStage& operator=(const OpenGLShaderStage&) = delete;
OpenGLShaderStage& operator=(OpenGLShaderStage&&) noexcept = default;
private:
Vk::ShaderModule m_shaderModule;
ShaderStageType m_stage;
GL::Shader m_shader;
};
}

View File

@ -7,15 +7,6 @@
namespace Nz
{
inline const Vk::ShaderModule& OpenGLShaderStage::GetHandle() const
{
return m_shaderModule;
}
inline ShaderStageType OpenGLShaderStage::GetStageType() const
{
return m_stage;
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -16,22 +16,9 @@
namespace Nz
{
inline VkBufferUsageFlags ToOpenGL(BufferType bufferType);
inline VkFormat ToOpenGL(ComponentType componentType);
inline VkCullModeFlagBits ToOpenGL(FaceSide faceSide);
inline VkPolygonMode ToOpenGL(FaceFilling faceFilling);
inline VkPrimitiveTopology ToOpenGL(PrimitiveMode primitiveMode);
inline VkCompareOp ToOpenGL(RendererComparison comparison);
inline VkFilter ToOpenGL(SamplerFilter samplerFilter);
inline VkSamplerMipmapMode ToOpenGL(SamplerMipmapMode samplerMipmap);
inline VkSamplerAddressMode ToOpenGL(SamplerWrap samplerWrap);
inline VkDescriptorType ToOpenGL(ShaderBindingType bindingType);
inline VkShaderStageFlagBits ToOpenGL(ShaderStageType stageType);
inline VkShaderStageFlags ToOpenGL(ShaderStageTypeFlags stageType);
inline VkStencilOp ToOpenGL(StencilOperation stencilOp);
inline VkVertexInputRate ToOpenGL(VertexInputRate inputRate);
inline GLenum ToOpenGL(ShaderStageType stageType);
NAZARA_OPENGLRENDERER_API std::string TranslateOpenGLError(VkResult code);
//NAZARA_OPENGLRENDERER_API std::string TranslateOpenGLError(GLenum code);
}
#include <Nazara/OpenGLRenderer/Utils.inl>

View File

@ -10,209 +10,17 @@
namespace Nz
{
VkBufferUsageFlags ToOpenGL(BufferType bufferType)
{
switch (bufferType)
{
case BufferType_Index: return VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
case BufferType_Vertex: return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
case BufferType_Uniform: return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
}
NazaraError("Unhandled BufferType 0x" + String::Number(bufferType, 16));
return 0;
}
VkFormat ToOpenGL(ComponentType componentType)
{
switch (componentType)
{
case ComponentType_Color: return VK_FORMAT_R8G8B8A8_UINT;
case ComponentType_Double1: return VK_FORMAT_R64_SFLOAT;
case ComponentType_Double2: return VK_FORMAT_R64G64_SFLOAT;
case ComponentType_Double3: return VK_FORMAT_R64G64B64_SFLOAT;
case ComponentType_Double4: return VK_FORMAT_R64G64B64A64_SFLOAT;
case ComponentType_Float1: return VK_FORMAT_R32_SFLOAT;
case ComponentType_Float2: return VK_FORMAT_R32G32_SFLOAT;
case ComponentType_Float3: return VK_FORMAT_R32G32B32_SFLOAT;
case ComponentType_Float4: return VK_FORMAT_R32G32B32A32_SFLOAT;
case ComponentType_Int1: return VK_FORMAT_R32_SINT;
case ComponentType_Int2: return VK_FORMAT_R32G32_SINT;
case ComponentType_Int3: return VK_FORMAT_R32G32B32_SINT;
case ComponentType_Int4: return VK_FORMAT_R32G32B32A32_SINT;
case ComponentType_Quaternion: return VK_FORMAT_R32G32B32A32_SFLOAT;
}
NazaraError("Unhandled ComponentType 0x" + String::Number(componentType, 16));
return VK_FORMAT_UNDEFINED;
}
VkCullModeFlagBits ToOpenGL(FaceSide faceSide)
{
switch (faceSide)
{
case FaceSide_None: return VK_CULL_MODE_NONE;
case FaceSide_Back: return VK_CULL_MODE_BACK_BIT;
case FaceSide_Front: return VK_CULL_MODE_FRONT_BIT;
case FaceSide_FrontAndBack: return VK_CULL_MODE_FRONT_AND_BACK;
}
NazaraError("Unhandled FaceSide 0x" + String::Number(faceSide, 16));
return VK_CULL_MODE_BACK_BIT;
}
inline VkPolygonMode ToOpenGL(FaceFilling faceFilling)
{
switch (faceFilling)
{
case FaceFilling_Fill: return VK_POLYGON_MODE_FILL;
case FaceFilling_Line: return VK_POLYGON_MODE_LINE;
case FaceFilling_Point: return VK_POLYGON_MODE_POINT;
}
NazaraError("Unhandled FaceFilling 0x" + String::Number(faceFilling, 16));
return VK_POLYGON_MODE_FILL;
}
VkPrimitiveTopology ToOpenGL(PrimitiveMode primitiveMode)
{
switch (primitiveMode)
{
case PrimitiveMode_LineList: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
case PrimitiveMode_LineStrip: return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
case PrimitiveMode_PointList: return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
case PrimitiveMode_TriangleList: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
case PrimitiveMode_TriangleStrip: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
case PrimitiveMode_TriangleFan: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
}
NazaraError("Unhandled FaceFilling 0x" + String::Number(primitiveMode, 16));
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
}
inline VkCompareOp ToOpenGL(RendererComparison comparison)
{
switch (comparison)
{
case RendererComparison_Never: return VK_COMPARE_OP_NEVER;
case RendererComparison_Less: return VK_COMPARE_OP_LESS;
case RendererComparison_Equal: return VK_COMPARE_OP_EQUAL;
case RendererComparison_LessOrEqual: return VK_COMPARE_OP_LESS_OR_EQUAL;
case RendererComparison_Greater: return VK_COMPARE_OP_GREATER;
case RendererComparison_NotEqual: return VK_COMPARE_OP_NOT_EQUAL;
case RendererComparison_GreaterOrEqual: return VK_COMPARE_OP_GREATER_OR_EQUAL;
case RendererComparison_Always: return VK_COMPARE_OP_ALWAYS;
}
NazaraError("Unhandled RendererComparison 0x" + String::Number(comparison, 16));
return VK_COMPARE_OP_NEVER;
}
VkFilter ToOpenGL(SamplerFilter samplerFilter)
{
switch (samplerFilter)
{
case SamplerFilter_Linear: return VK_FILTER_LINEAR;
case SamplerFilter_Nearest: return VK_FILTER_NEAREST;
}
NazaraError("Unhandled SamplerFilter 0x" + String::Number(UnderlyingCast(samplerFilter), 16));
return VK_FILTER_NEAREST;
}
VkSamplerMipmapMode ToOpenGL(SamplerMipmapMode samplerMipmap)
{
switch (samplerMipmap)
{
case SamplerMipmapMode_Linear: return VK_SAMPLER_MIPMAP_MODE_LINEAR;
case SamplerMipmapMode_Nearest: return VK_SAMPLER_MIPMAP_MODE_NEAREST;
}
NazaraError("Unhandled SamplerMipmapMode 0x" + String::Number(UnderlyingCast(samplerMipmap), 16));
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
}
VkSamplerAddressMode ToOpenGL(SamplerWrap samplerWrap)
{
switch (samplerWrap)
{
case SamplerWrap_Clamp: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
case SamplerWrap_MirroredRepeat: return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case SamplerWrap_Repeat: return VK_SAMPLER_ADDRESS_MODE_REPEAT;
}
NazaraError("Unhandled SamplerWrap 0x" + String::Number(UnderlyingCast(samplerWrap), 16));
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
}
VkDescriptorType ToOpenGL(ShaderBindingType bindingType)
{
switch (bindingType)
{
case ShaderBindingType::Texture: return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
case ShaderBindingType::UniformBuffer: return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
}
NazaraError("Unhandled ShaderBindingType 0x" + String::Number(UnderlyingCast(bindingType), 16));
return VK_DESCRIPTOR_TYPE_SAMPLER;
}
VkShaderStageFlagBits ToOpenGL(ShaderStageType stageType)
GLenum ToOpenGL(ShaderStageType stageType)
{
switch (stageType)
{
case ShaderStageType::Fragment: return VK_SHADER_STAGE_FRAGMENT_BIT;
case ShaderStageType::Vertex: return VK_SHADER_STAGE_VERTEX_BIT;
case ShaderStageType::Fragment: return GL_FRAGMENT_SHADER;
case ShaderStageType::Vertex: return GL_VERTEX_SHADER;
}
NazaraError("Unhandled ShaderStageType 0x" + String::Number(UnderlyingCast(stageType), 16));
return {};
}
VkShaderStageFlags ToOpenGL(ShaderStageTypeFlags stageType)
{
VkShaderStageFlags shaderStageBits = 0;
if (stageType.Test(ShaderStageType::Fragment))
shaderStageBits |= VK_SHADER_STAGE_FRAGMENT_BIT;
if (stageType.Test(ShaderStageType::Vertex))
shaderStageBits |= VK_SHADER_STAGE_VERTEX_BIT;
static_assert(UnderlyingCast(ShaderStageType::Max) + 1 == 2);
return shaderStageBits;
}
VkStencilOp ToOpenGL(StencilOperation stencilOp)
{
switch (stencilOp)
{
case StencilOperation_Decrement: return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
case StencilOperation_DecrementNoClamp: return VK_STENCIL_OP_DECREMENT_AND_WRAP;
case StencilOperation_Increment: return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
case StencilOperation_IncrementNoClamp: return VK_STENCIL_OP_INCREMENT_AND_WRAP;
case StencilOperation_Invert: return VK_STENCIL_OP_INVERT;
case StencilOperation_Keep: return VK_STENCIL_OP_KEEP;
case StencilOperation_Replace: return VK_STENCIL_OP_REPLACE;
case StencilOperation_Zero: return VK_STENCIL_OP_ZERO;
}
NazaraError("Unhandled RendererComparison 0x" + String::Number(stencilOp, 16));
return VK_STENCIL_OP_KEEP;
}
VkVertexInputRate ToOpenGL(VertexInputRate inputRate)
{
switch (inputRate)
{
case VertexInputRate::Instance: return VK_VERTEX_INPUT_RATE_INSTANCE;
case VertexInputRate::Vertex: return VK_VERTEX_INPUT_RATE_VERTEX;
}
NazaraError("Unhandled VertexInputRate 0x" + String::Number(UnderlyingCast(inputRate), 16));
return VK_VERTEX_INPUT_RATE_VERTEX;
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -4,39 +4,40 @@
#pragma once
#ifndef NAZARA_OPENGLRENDERER_VKSHADERMODULE_HPP
#define NAZARA_OPENGLRENDERER_VKSHADERMODULE_HPP
#ifndef NAZARA_OPENGLRENDERER_GLSHADER_HPP
#define NAZARA_OPENGLRENDERER_GLSHADER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DeviceObject.hpp>
#include <Nazara/Core/MovableValue.hpp>
#include <Nazara/OpenGLRenderer/OpenGLDevice.hpp>
namespace Nz
namespace Nz::GL
{
namespace Vk
class Shader
{
class ShaderModule : public DeviceObject<ShaderModule, VkShaderModule, VkShaderModuleCreateInfo, VK_OBJECT_TYPE_SHADER_MODULE>
{
friend DeviceObject;
public:
Shader() = default;
Shader(const Shader&) = delete;
Shader(Shader&&) noexcept = default;
inline ~Shader();
public:
ShaderModule() = default;
ShaderModule(const ShaderModule&) = delete;
ShaderModule(ShaderModule&&) = default;
~ShaderModule() = default;
inline bool Compile(std::string* error = nullptr);
using DeviceObject::Create;
inline bool Create(Device& device, const UInt32* code, std::size_t size, VkShaderModuleCreateFlags flags = 0, const VkAllocationCallbacks* allocator = nullptr);
inline bool Create(OpenGLDevice& device, GLenum type);
inline void Destroy();
ShaderModule& operator=(const ShaderModule&) = delete;
ShaderModule& operator=(ShaderModule&&) = delete;
inline void SetBinarySource(GLenum binaryFormat, const void* binary, GLsizei length);
inline void SetSource(const char* source, GLint length);
private:
static inline VkResult CreateHelper(Device& device, const VkShaderModuleCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkShaderModule* handle);
static inline void DestroyHelper(Device& device, VkShaderModule handle, const VkAllocationCallbacks* allocator);
};
}
Shader& operator=(const Shader&) = delete;
Shader& operator=(Shader&&) noexcept = default;
private:
MovablePtr<OpenGLDevice> m_device;
MovableValue<GLuint> m_shader;
};
}
#include <Nazara/OpenGLRenderer/Wrapper/ShaderModule.inl>
#include <Nazara/OpenGLRenderer/Wrapper/Shader.inl>
#endif // NAZARA_OPENGLRENDERER_VKSHADERMODULE_HPP
#endif

View File

@ -2,36 +2,80 @@
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/OpenGLRenderer/Wrapper/ShaderModule.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Shader.hpp>
#include <cassert>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
namespace Nz::GL
{
namespace Vk
inline Shader::~Shader()
{
inline bool ShaderModule::Create(Device& device, const UInt32* code, std::size_t size, VkShaderModuleCreateFlags flags, const VkAllocationCallbacks* allocator)
Destroy();
}
inline bool Shader::Compile(std::string* error)
{
assert(m_shader);
const GL::Context& context = m_device->GetReferenceContext();
context.glCompileShader(m_shader);
GLint success;
context.glGetShaderiv(m_shader, GL_COMPILE_STATUS, &success);
if (!success)
{
VkShaderModuleCreateInfo createInfo =
if (error)
{
VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
nullptr,
flags,
size,
code
};
GLint logLength;
context.glGetShaderiv(m_shader, GL_INFO_LOG_LENGTH, &logLength);
return Create(device, createInfo, allocator);
error->resize(logLength);
if (logLength > 0)
{
GLsizei dummy;
context.glGetShaderInfoLog(m_shader, logLength, &dummy, error->data());
}
}
return false;
}
inline VkResult ShaderModule::CreateHelper(Device& device, const VkShaderModuleCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkShaderModule* handle)
return true;
}
inline bool Shader::Create(OpenGLDevice& device, GLenum type)
{
Destroy();
m_device = &device;
m_shader = device.GetReferenceContext().glCreateShader(type);
if (!m_shader)
return false; //< TODO: Handle error messages
return true;
}
inline void Shader::Destroy()
{
if (m_shader)
{
return device.vkCreateShaderModule(device, createInfo, allocator, handle);
m_device->GetReferenceContext().glDeleteShader(m_shader);
m_shader = 0;
}
}
inline void ShaderModule::DestroyHelper(Device& device, VkShaderModule handle, const VkAllocationCallbacks* allocator)
{
return device.vkDestroyShaderModule(device, handle, allocator);
}
inline void Shader::SetBinarySource(GLenum binaryFormat, const void* binary, GLsizei length)
{
assert(m_shader);
m_device->GetReferenceContext().glShaderBinary(1U, &m_shader.Get(), binaryFormat, binary, length);
}
inline void Shader::SetSource(const char* source, GLint length)
{
assert(m_shader);
m_device->GetReferenceContext().glShaderSource(m_shader, 1U, &source, &length);
}
}

View File

@ -53,8 +53,11 @@ namespace Nz
std::shared_ptr<ShaderStageImpl> OpenGLDevice::InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
{
auto shaderStage = std::make_shared<OpenGLShaderStage>();
if (!shaderStage->Create(*this, type, lang, source, sourceSize))
return {};
return shaderStage;
}
std::unique_ptr<Texture> OpenGLDevice::InstantiateTexture(const TextureInfo& params)