Add OpenGLRenderer (WIP)

This commit is contained in:
Lynix 2020-04-15 19:38:11 +02:00
parent ebb271a089
commit 68760209c1
118 changed files with 19236 additions and 414 deletions

View File

@ -0,0 +1,36 @@
TOOL.Name = "OpenGLRenderer"
TOOL.ClientOnly = true
TOOL.Kind = "Library"
TOOL.TargetDirectory = "../lib"
TOOL.Defines = {
"NAZARA_BUILD",
"NAZARA_OPENGLRENDERER_BUILD"
}
TOOL.Includes = {
"../include",
"../src/",
"../extlibs/include"
}
TOOL.Files = {
"../include/Nazara/OpenGLRenderer/**.hpp",
"../include/Nazara/OpenGLRenderer/**.inl",
"../src/Nazara/OpenGLRenderer/**.hpp",
"../src/Nazara/OpenGLRenderer/**.inl",
"../src/Nazara/OpenGLRenderer/**.cpp"
}
TOOL.Libraries = {
"NazaraCore",
"NazaraRenderer",
"NazaraUtility"
}
TOOL.OsFiles.Windows = {
"../src/Nazara/OpenGLRenderer/Win32/**.hpp",
"../src/Nazara/OpenGLRenderer/Win32/**.cpp"
}

View File

@ -0,0 +1,53 @@
/*
Nazara Engine - OpenGL
Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma once
#ifndef NAZARA_CONFIG_OPENGLRENDERER_HPP
#define NAZARA_CONFIG_OPENGLRENDERER_HPP
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
// Utilise le MemoryManager pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes)
#define NAZARA_OPENGLRENDERER_MANAGE_MEMORY 0
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
#define NAZARA_OPENGLRENDERER_SAFE 1
/// Chaque modification d'un paramètre ci-dessous implique une modification (souvent mineure) du code
/// Vérification des valeurs et types de certaines constantes
#include <Nazara/OpenGLRenderer/ConfigCheck.hpp>
#if !defined(NAZARA_STATIC)
#ifdef NAZARA_OPENGLRENDERER_BUILD
#define NAZARA_OPENGLRENDERER_API NAZARA_EXPORT
#else
#define NAZARA_OPENGLRENDERER_API NAZARA_IMPORT
#endif
#else
#define NAZARA_OPENGLRENDERER_API
#endif
#endif // NAZARA_CONFIG_MODULENAME_HPP

View File

@ -0,0 +1,22 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CONFIG_CHECK_OPENGLE_HPP
#define NAZARA_CONFIG_CHECK_OPENGLE_HPP
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
#include <type_traits>
#define CheckType(name, type, err) static_assert(std::is_ ##type <decltype(name)>::value, #type err)
#define CheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
// On force la valeur de MANAGE_MEMORY en mode debug
#if defined(NAZARA_DEBUG) && !NAZARA_OPENGLRENDERER_MANAGE_MEMORY
#undef NAZARA_MODULENAME_MANAGE_MEMORY
#define NAZARA_MODULENAME_MANAGE_MEMORY 0
#endif
#endif // NAZARA_CONFIG_CHECK_OPENGLRENDERER_HPP

View File

@ -0,0 +1,8 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/Config.hpp>
#if NAZARA_MODULENAME_MANAGE_MEMORY
#include <Nazara/Core/Debug/NewRedefinition.hpp>
#endif

View File

@ -0,0 +1,9 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp
#if NAZARA_MODULENAME_MANAGE_MEMORY
#undef delete
#undef new
#endif

View File

@ -0,0 +1,35 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGL_HPP
#define NAZARA_OPENGL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Initializer.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <list>
#include <memory>
#include <vector>
namespace Nz
{
class OpenGLDevice;
class NAZARA_OPENGLRENDERER_API OpenGL
{
public:
OpenGL() = delete;
~OpenGL() = delete;
static bool Initialize();
static bool IsInitialized();
static void Uninitialize();
};
}
#endif // NAZARA_OPENGL_HPP

View File

@ -0,0 +1,57 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_BUFFER_HPP
#define NAZARA_OPENGLRENDERER_BUFFER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Utility/AbstractBuffer.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Buffer.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DeviceMemory.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Fence.hpp>
#include <memory>
#include <vector>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLBuffer : public AbstractBuffer
{
public:
inline OpenGLBuffer(Vk::Device& device, BufferType type);
OpenGLBuffer(const OpenGLBuffer&) = delete;
OpenGLBuffer(OpenGLBuffer&&) = delete; ///TODO
virtual ~OpenGLBuffer();
bool Fill(const void* data, UInt64 offset, UInt64 size) override;
bool Initialize(UInt64 size, BufferUsageFlags usage) override;
inline VkBuffer GetBuffer();
UInt64 GetSize() const override;
DataStorage GetStorage() const override;
void* Map(BufferAccess access, UInt64 offset, UInt64 size) override;
bool Unmap() override;
OpenGLBuffer& operator=(const OpenGLBuffer&) = delete;
OpenGLBuffer& operator=(OpenGLBuffer&&) = delete; ///TODO
private:
BufferType m_type;
BufferUsageFlags m_usage;
UInt64 m_size;
VkBuffer m_buffer;
VkBuffer m_stagingBuffer;
VmaAllocation m_allocation;
VmaAllocation m_stagingAllocation;
Vk::Device& m_device;
};
}
#include <Nazara/OpenGLRenderer/OpenGLBuffer.inl>
#endif // NAZARA_OPENGLRENDERER_BUFFER_HPP

View File

@ -0,0 +1,22 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLBuffer.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline OpenGLBuffer::OpenGLBuffer(Vk::Device& device, BufferType type) :
m_device(device),
m_type(type)
{
}
inline VkBuffer OpenGLBuffer::GetBuffer()
{
return m_buffer;
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,39 @@
// Copyright (C) 2020 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_OPENGLRENDERER_OPENGLCOMMANDBUFFER_HPP
#define NAZARA_OPENGLRENDERER_OPENGLCOMMANDBUFFER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/CommandBuffer.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CommandBuffer.hpp>
#include <vector>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLCommandBuffer final : public CommandBuffer
{
public:
inline OpenGLCommandBuffer(Vk::AutoCommandBuffer commandBuffer);
inline OpenGLCommandBuffer(std::vector<Vk::AutoCommandBuffer> commandBuffers);
OpenGLCommandBuffer(const OpenGLCommandBuffer&) = delete;
OpenGLCommandBuffer(OpenGLCommandBuffer&&) noexcept = default;
~OpenGLCommandBuffer() = default;
inline Vk::CommandBuffer& GetCommandBuffer(std::size_t imageIndex = 0);
OpenGLCommandBuffer& operator=(const OpenGLCommandBuffer&) = delete;
OpenGLCommandBuffer& operator=(OpenGLCommandBuffer&&) = delete;
private:
std::vector<Vk::AutoCommandBuffer> m_commandBuffers;
};
}
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.inl>
#endif // NAZARA_OPENGLRENDERER_OPENGLCOMMANDBUFFER_HPP

View File

@ -0,0 +1,26 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLCommandBuffer.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline OpenGLCommandBuffer::OpenGLCommandBuffer(Vk::AutoCommandBuffer commandBuffer)
{
m_commandBuffers.push_back(std::move(commandBuffer));
}
inline OpenGLCommandBuffer::OpenGLCommandBuffer(std::vector<Vk::AutoCommandBuffer> commandBuffers) :
m_commandBuffers(std::move(commandBuffers))
{
}
inline Vk::CommandBuffer& OpenGLCommandBuffer::GetCommandBuffer(std::size_t imageIndex)
{
return m_commandBuffers[imageIndex].Get();
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,66 @@
// Copyright (C) 2020 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_OPENGLRENDERER_OPENGLCOMMANDBUFFERBUILDER_HPP
#define NAZARA_OPENGLRENDERER_OPENGLCOMMANDBUFFERBUILDER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/CommandBufferBuilder.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CommandBuffer.hpp>
namespace Nz
{
class OpenGLRenderPass;
class NAZARA_OPENGLRENDERER_API OpenGLCommandBufferBuilder final : public CommandBufferBuilder
{
public:
inline OpenGLCommandBufferBuilder(Vk::CommandBuffer& commandBuffer, std::size_t imageIndex = 0);
OpenGLCommandBufferBuilder(const OpenGLCommandBufferBuilder&) = delete;
OpenGLCommandBufferBuilder(OpenGLCommandBufferBuilder&&) noexcept = default;
~OpenGLCommandBufferBuilder() = default;
void BeginDebugRegion(const std::string_view& regionName, const Nz::Color& color) override;
void BeginRenderPass(const Framebuffer& framebuffer, const RenderPass& renderPass, Nz::Recti renderRect, std::initializer_list<ClearValues> clearValues) override;
void BindIndexBuffer(AbstractBuffer* indexBuffer, UInt64 offset = 0) override;
void BindPipeline(const RenderPipeline& pipeline) override;
void BindShaderBinding(const ShaderBinding& binding) override;
void BindVertexBuffer(UInt32 binding, Nz::AbstractBuffer* vertexBuffer, UInt64 offset = 0) override;
void CopyBuffer(const RenderBufferView& source, const RenderBufferView& target, UInt64 size, UInt64 sourceOffset = 0, UInt64 targetOffset = 0) override;
void CopyBuffer(const UploadPool::Allocation& allocation, const RenderBufferView& target, UInt64 size, UInt64 sourceOffset = 0, UInt64 targetOffset = 0) override;
void Draw(UInt32 vertexCount, UInt32 instanceCount = 1, UInt32 firstVertex = 0, UInt32 firstInstance = 0) override;
void DrawIndexed(UInt32 indexCount, UInt32 instanceCount = 1, UInt32 firstVertex = 0, UInt32 firstInstance = 0) override;
void EndDebugRegion() override;
void EndRenderPass() override;
inline Vk::CommandBuffer& GetCommandBuffer();
inline std::size_t GetMaxFramebufferCount() const;
void PreTransferBarrier() override;
void PostTransferBarrier() override;
void SetScissor(Nz::Recti scissorRegion) override;
void SetViewport(Nz::Recti viewportRegion) override;
OpenGLCommandBufferBuilder& operator=(const OpenGLCommandBufferBuilder&) = delete;
OpenGLCommandBufferBuilder& operator=(OpenGLCommandBufferBuilder&&) = delete;
private:
Vk::CommandBuffer& m_commandBuffer;
const OpenGLRenderPass* m_currentRenderPass;
std::size_t m_framebufferCount;
std::size_t m_imageIndex;
};
}
#include <Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.inl>
#endif // NAZARA_OPENGLRENDERER_OPENGLCOMMANDBUFFERBUILDER_HPP

View File

@ -0,0 +1,28 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLCommandBufferBuilder.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline OpenGLCommandBufferBuilder::OpenGLCommandBufferBuilder(Vk::CommandBuffer& commandBuffer, std::size_t imageIndex) :
m_commandBuffer(commandBuffer),
m_framebufferCount(0),
m_imageIndex(imageIndex)
{
}
inline Vk::CommandBuffer& OpenGLCommandBufferBuilder::GetCommandBuffer()
{
return m_commandBuffer;
}
inline std::size_t OpenGLCommandBufferBuilder::GetMaxFramebufferCount() const
{
return m_framebufferCount;
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,38 @@
// Copyright (C) 2020 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_OPENGLRENDERER_OPENGLCOMMANDPOOL_HPP
#define NAZARA_OPENGLRENDERER_OPENGLCOMMANDPOOL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/CommandPool.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CommandPool.hpp>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLCommandPool final : public CommandPool
{
public:
inline OpenGLCommandPool(Vk::Device& device, QueueType queueType);
inline OpenGLCommandPool(Vk::Device& device, UInt32 queueFamilyIndex);
OpenGLCommandPool(const OpenGLCommandPool&) = delete;
OpenGLCommandPool(OpenGLCommandPool&&) noexcept = default;
~OpenGLCommandPool() = default;
std::unique_ptr<CommandBuffer> BuildCommandBuffer(const std::function<void(CommandBufferBuilder& builder)>& callback) override;
OpenGLCommandPool& operator=(const OpenGLCommandPool&) = delete;
OpenGLCommandPool& operator=(OpenGLCommandPool&&) = delete;
private:
Vk::CommandPool m_commandPool;
};
}
#include <Nazara/OpenGLRenderer/OpenGLCommandPool.inl>
#endif // NAZARA_OPENGLRENDERER_OPENGLCOMMANDPOOL_HPP

View File

@ -0,0 +1,28 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLCommandPool.hpp>
#include <stdexcept>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline OpenGLCommandPool::OpenGLCommandPool(Vk::Device& device, QueueType queueType)
{
UInt32 queueFamilyIndex = device.GetDefaultFamilyIndex(queueType);
if (queueFamilyIndex == Vk::Device::InvalidQueue)
throw std::runtime_error("QueueType " + std::to_string(UnderlyingCast(queueType)) + " is not supported");
if (!m_commandPool.Create(device, queueFamilyIndex))
throw std::runtime_error("Failed to create command pool: " + TranslateOpenGLError(m_commandPool.GetLastErrorCode()));
}
inline OpenGLCommandPool::OpenGLCommandPool(Vk::Device& device, UInt32 queueFamilyIndex)
{
if (!m_commandPool.Create(device, queueFamilyIndex))
throw std::runtime_error("Failed to create command pool: " + TranslateOpenGLError(m_commandPool.GetLastErrorCode()));
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,41 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_OPENGLDEVICE_HPP
#define NAZARA_OPENGLRENDERER_OPENGLDEVICE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/RenderDevice.hpp>
#include <Nazara/OpenGLRenderer/OpenGLBuffer.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Device.hpp>
#include <vector>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLDevice : public RenderDevice, public Vk::Device
{
public:
using Device::Device;
OpenGLDevice(const OpenGLDevice&) = delete;
OpenGLDevice(OpenGLDevice&&) = delete; ///TODO?
~OpenGLDevice();
std::unique_ptr<AbstractBuffer> InstantiateBuffer(BufferType type) override;
std::unique_ptr<CommandPool> InstantiateCommandPool(QueueType queueType) override;
std::unique_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) override;
std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) override;
std::shared_ptr<ShaderStageImpl> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) override;
std::unique_ptr<Texture> InstantiateTexture(const TextureInfo& params) override;
std::unique_ptr<TextureSampler> InstantiateTextureSampler(const TextureSamplerInfo& params) override;
OpenGLDevice& operator=(const OpenGLDevice&) = delete;
OpenGLDevice& operator=(OpenGLDevice&&) = delete; ///TODO?
};
}
#include <Nazara/OpenGLRenderer/OpenGLDevice.inl>
#endif // NAZARA_OPENGLRENDERER_OPENGLDEVICE_HPP

View File

@ -0,0 +1,12 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLDevice.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,43 @@
// Copyright (C) 2020 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_OPENGLRENDERER_OPENGLFRAMEBUFFER_HPP
#define NAZARA_OPENGLRENDERER_OPENGLFRAMEBUFFER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Framebuffer.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Framebuffer.hpp>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLFramebuffer : public Framebuffer
{
public:
enum class Type
{
Multiple,
Single
};
inline OpenGLFramebuffer(Type type);
OpenGLFramebuffer(const OpenGLFramebuffer&) = delete;
OpenGLFramebuffer(OpenGLFramebuffer&&) noexcept = default;
~OpenGLFramebuffer() = default;
inline Type GetType() const;
OpenGLFramebuffer& operator=(const OpenGLFramebuffer&) = delete;
OpenGLFramebuffer& operator=(OpenGLFramebuffer&&) noexcept = default;
private:
Type m_type;
};
}
#include <Nazara/OpenGLRenderer/OpenGLFramebuffer.inl>
#endif // NAZARA_OPENGLRENDERER_OPENGLFRAMEBUFFER_HPP

View File

@ -0,0 +1,21 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLFramebuffer.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline OpenGLFramebuffer::OpenGLFramebuffer(Type type) :
m_type(type)
{
}
inline auto OpenGLFramebuffer::GetType() const -> Type
{
return m_type;
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,65 @@
// Copyright (C) 2020 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_OPENGLRENDERER_OPENGLRENDERIMAGE_HPP
#define NAZARA_OPENGLRENDERER_OPENGLRENDERIMAGE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/RenderImage.hpp>
#include <Nazara/OpenGLRenderer/OpenGLUploadPool.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CommandBuffer.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CommandPool.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Fence.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Semaphore.hpp>
#include <vector>
namespace Nz
{
class VkRenderWindow;
class NAZARA_OPENGLRENDERER_API OpenGLRenderImage : public RenderImage
{
public:
OpenGLRenderImage(VkRenderWindow& owner);
OpenGLRenderImage(const OpenGLRenderImage&) = delete;
OpenGLRenderImage(OpenGLRenderImage&&) noexcept = default;
~OpenGLRenderImage();
void Execute(const std::function<void(CommandBufferBuilder& builder)>& callback, QueueTypeFlags queueTypeFlags) override;
inline Vk::Fence& GetInFlightFence();
inline Vk::Semaphore& GetImageAvailableSemaphore();
inline UInt32 GetImageIndex();
inline Vk::Semaphore& GetRenderFinishedSemaphore();
OpenGLUploadPool& GetUploadPool() override;
void SubmitCommandBuffer(CommandBuffer* commandBuffer, QueueTypeFlags queueTypeFlags) override;
void SubmitCommandBuffer(VkCommandBuffer commandBuffer, QueueTypeFlags queueTypeFlags);
void Present() override;
inline void Reset(UInt32 imageIndex);
OpenGLRenderImage& operator=(const OpenGLRenderImage&) = delete;
OpenGLRenderImage& operator=(OpenGLRenderImage&&) = delete;
private:
std::size_t m_currentCommandBuffer;
std::vector<Vk::AutoCommandBuffer> m_inFlightCommandBuffers;
std::vector<VkCommandBuffer> m_graphicalCommandsBuffers;
VkRenderWindow& m_owner;
Vk::CommandPool m_commandPool;
Vk::Fence m_inFlightFence;
Vk::Semaphore m_imageAvailableSemaphore;
Vk::Semaphore m_renderFinishedSemaphore;
OpenGLUploadPool m_uploadPool;
UInt32 m_imageIndex;
};
}
#include <Nazara/OpenGLRenderer/OpenGLRenderImage.inl>
#endif // NAZARA_OPENGLRENDERER_OPENGLRENDERIMAGE_HPP

View File

@ -0,0 +1,39 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLRenderImage.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline Vk::Fence& Nz::OpenGLRenderImage::GetInFlightFence()
{
return m_inFlightFence;
}
inline Vk::Semaphore& OpenGLRenderImage::GetImageAvailableSemaphore()
{
return m_imageAvailableSemaphore;
}
inline UInt32 OpenGLRenderImage::GetImageIndex()
{
return m_imageIndex;
}
inline Vk::Semaphore& OpenGLRenderImage::GetRenderFinishedSemaphore()
{
return m_renderFinishedSemaphore;
}
inline void OpenGLRenderImage::Reset(UInt32 imageIndex)
{
m_graphicalCommandsBuffers.clear();
m_currentCommandBuffer = 0;
m_imageIndex = imageIndex;
m_uploadPool.Reset();
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,41 @@
// Copyright (C) 2020 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_OPENGLRENDERER_OPENGLRENDERPASS_HPP
#define NAZARA_OPENGLRENDERER_OPENGLRENDERPASS_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/RenderPass.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/RenderPass.hpp>
#include <vector>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLRenderPass final : public RenderPass
{
public:
inline OpenGLRenderPass(Vk::RenderPass renderPass, std::initializer_list<PixelFormat> formats); //< FIXME
OpenGLRenderPass(const OpenGLRenderPass&) = delete;
OpenGLRenderPass(OpenGLRenderPass&&) noexcept = default;
~OpenGLRenderPass() = default;
inline PixelFormat GetAttachmentFormat(std::size_t attachmentIndex) const;
inline Vk::RenderPass& GetRenderPass();
inline const Vk::RenderPass& GetRenderPass() const;
OpenGLRenderPass& operator=(const OpenGLRenderPass&) = delete;
OpenGLRenderPass& operator=(OpenGLRenderPass&&) noexcept = default;
private:
std::vector<PixelFormat> m_formats;
Vk::RenderPass m_renderPass;
};
}
#include <Nazara/OpenGLRenderer/OpenGLRenderPass.inl>
#endif // NAZARA_OPENGLRENDERER_OPENGLRENDERPASS_HPP

View File

@ -0,0 +1,32 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLRenderPass.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline OpenGLRenderPass::OpenGLRenderPass(Vk::RenderPass renderPass, std::initializer_list<PixelFormat> formats) :
m_formats(std::begin(formats), std::end(formats)),
m_renderPass(std::move(renderPass))
{
}
inline PixelFormat OpenGLRenderPass::GetAttachmentFormat(std::size_t attachmentIndex) const
{
return m_formats[attachmentIndex];
}
inline Vk::RenderPass& OpenGLRenderPass::GetRenderPass()
{
return m_renderPass;
}
inline const Vk::RenderPass& OpenGLRenderPass::GetRenderPass() const
{
return m_renderPass;
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,81 @@
// Copyright (C) 2020 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_OPENGLRENDERER_OPENGLRENDERPIPELINE_HPP
#define NAZARA_OPENGLRENDERER_OPENGLRENDERPIPELINE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/Renderer/RenderPipeline.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Device.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Pipeline.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/RenderPass.hpp>
#include <vector>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLRenderPipeline : public RenderPipeline
{
public:
struct CreateInfo;
OpenGLRenderPipeline(Vk::Device& device, RenderPipelineInfo pipelineInfo);
~OpenGLRenderPipeline() = default;
VkPipeline Get(const Vk::RenderPass& renderPass) const;
static std::vector<VkPipelineColorBlendAttachmentState> BuildColorBlendAttachmentStateList(const RenderPipelineInfo& pipelineInfo);
static VkPipelineColorBlendStateCreateInfo BuildColorBlendInfo(const RenderPipelineInfo& pipelineInfo, const std::vector<VkPipelineColorBlendAttachmentState>& attachmentState);
static VkPipelineDepthStencilStateCreateInfo BuildDepthStencilInfo(const RenderPipelineInfo& pipelineInfo);
static VkPipelineDynamicStateCreateInfo BuildDynamicStateInfo(const RenderPipelineInfo& pipelineInfo, const std::vector<VkDynamicState>& dynamicStates);
static std::vector<VkDynamicState> BuildDynamicStateList(const RenderPipelineInfo& pipelineInfo);
static VkPipelineInputAssemblyStateCreateInfo BuildInputAssemblyInfo(const RenderPipelineInfo& pipelineInfo);
static VkPipelineMultisampleStateCreateInfo BuildMultisampleInfo(const RenderPipelineInfo& pipelineInfo);
static VkPipelineRasterizationStateCreateInfo BuildRasterizationInfo(const RenderPipelineInfo& pipelineInfo);
static VkPipelineViewportStateCreateInfo BuildViewportInfo(const RenderPipelineInfo& pipelineInfo);
static VkStencilOpState BuildStencilOp(const RenderPipelineInfo& pipelineInfo, bool front);
static std::vector<VkPipelineShaderStageCreateInfo> BuildShaderStageInfo(const RenderPipelineInfo& pipelineInfo);
static std::vector<VkVertexInputAttributeDescription> BuildVertexAttributeDescription(const RenderPipelineInfo& pipelineInfo);
static std::vector<VkVertexInputBindingDescription> BuildVertexBindingDescription(const RenderPipelineInfo& pipelineInfo);
static VkPipelineVertexInputStateCreateInfo BuildVertexInputInfo(const RenderPipelineInfo& pipelineInfo, const std::vector<VkVertexInputAttributeDescription>& vertexAttributes, const std::vector<VkVertexInputBindingDescription>& bindingDescription);
static CreateInfo BuildCreateInfo(const RenderPipelineInfo& pipelineInfo);
struct CreateInfo
{
struct StateData
{
VkPipelineColorBlendStateCreateInfo colorBlendState;
VkPipelineDepthStencilStateCreateInfo depthStencilState;
VkPipelineDynamicStateCreateInfo dynamicState;
VkPipelineMultisampleStateCreateInfo multiSampleState;
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState;
VkPipelineRasterizationStateCreateInfo rasterizationState;
VkPipelineVertexInputStateCreateInfo vertexInputState;
VkPipelineViewportStateCreateInfo viewportState;
};
std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentState;
std::vector<VkDynamicState> dynamicStates;
std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
std::vector<VkVertexInputAttributeDescription> vertexAttributesDescription;
std::vector<VkVertexInputBindingDescription> vertexBindingDescription;
std::unique_ptr<StateData> stateData;
VkGraphicsPipelineCreateInfo pipelineInfo;
};
private:
mutable std::unordered_map<VkRenderPass, Vk::Pipeline> m_pipelines;
MovablePtr<Vk::Device> m_device;
CreateInfo m_pipelineCreateInfo;
RenderPipelineInfo m_pipelineInfo;
};
}
#include <Nazara/OpenGLRenderer/OpenGLRenderPipeline.inl>
#endif // NAZARA_OPENGLRENDERER_OPENGLRENDERPIPELINE_HPP

View File

@ -0,0 +1,12 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLRenderPipeline.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,70 @@
// Copyright (C) 2020 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_OPENGLRENDERER_OPENGLRENDERPIPELINELAYOUT_HPP
#define NAZARA_OPENGLRENDERER_OPENGLRENDERPIPELINELAYOUT_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Bitset.hpp>
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <Nazara/OpenGLRenderer/OpenGLShaderBinding.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Device.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DescriptorPool.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DescriptorSet.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DescriptorSetLayout.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/PipelineLayout.hpp>
#include <memory>
#include <type_traits>
#include <vector>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLRenderPipelineLayout : public RenderPipelineLayout
{
friend OpenGLShaderBinding;
public:
OpenGLRenderPipelineLayout() = default;
~OpenGLRenderPipelineLayout();
ShaderBindingPtr AllocateShaderBinding() override;
bool Create(Vk::Device& device, RenderPipelineLayoutInfo layoutInfo);
inline Vk::Device* GetDevice() const;
inline const Vk::DescriptorSetLayout& GetDescriptorSetLayout() const;
inline const Vk::PipelineLayout& GetPipelineLayout() const;
private:
struct DescriptorPool;
DescriptorPool& AllocatePool();
ShaderBindingPtr AllocateFromPool(std::size_t poolIndex);
void Release(ShaderBinding& binding);
inline void TryToShrink();
struct DescriptorPool
{
using BindingStorage = std::aligned_storage_t<sizeof(OpenGLShaderBinding), alignof(OpenGLShaderBinding)>;
Bitset<UInt64> freeBindings;
Vk::DescriptorPool descriptorPool;
std::unique_ptr<BindingStorage[]> storage;
};
MovablePtr<Vk::Device> m_device;
std::vector<DescriptorPool> m_descriptorPools;
Vk::DescriptorSetLayout m_descriptorSetLayout;
Vk::PipelineLayout m_pipelineLayout;
RenderPipelineLayoutInfo m_layoutInfo;
};
}
#include <Nazara/OpenGLRenderer/OpenGLRenderPipelineLayout.inl>
#endif // NAZARA_OPENGLRENDERER_OPENGLRENDERPIPELINE_HPP

View File

@ -0,0 +1,41 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLRenderPipelineLayout.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline Vk::Device* OpenGLRenderPipelineLayout::GetDevice() const
{
return m_device.Get();
}
inline const Vk::DescriptorSetLayout& OpenGLRenderPipelineLayout::GetDescriptorSetLayout() const
{
return m_descriptorSetLayout;
}
inline const Vk::PipelineLayout& OpenGLRenderPipelineLayout::GetPipelineLayout() const
{
return m_pipelineLayout;
}
inline void OpenGLRenderPipelineLayout::TryToShrink()
{
std::size_t poolCount = m_descriptorPools.size();
if (poolCount >= 2 && m_descriptorPools.back().freeBindings.TestAll())
{
for (std::size_t i = poolCount - 1; i > 0; ++i)
{
if (m_descriptorPools[i].freeBindings.TestAll())
poolCount--;
}
m_descriptorPools.resize(poolCount);
}
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,90 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_RENDERWINDOW_HPP
#define NAZARA_OPENGLRENDERER_RENDERWINDOW_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Math/Rect.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/RendererImpl.hpp>
#include <Nazara/Renderer/RenderWindowImpl.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <Nazara/OpenGLRenderer/OpenGLDevice.hpp>
#include <Nazara/OpenGLRenderer/OpenGLMultipleFramebuffer.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderImage.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderPass.hpp>
#include <Nazara/OpenGLRenderer/VkRenderTarget.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CommandBuffer.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CommandPool.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Device.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DeviceMemory.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Framebuffer.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Image.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/QueueHandle.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Surface.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Swapchain.hpp>
#include <optional>
#include <vector>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLRenderWindow : public RenderWindowImpl
{
public:
VkRenderWindow();
VkRenderWindow(const VkRenderWindow&) = delete;
VkRenderWindow(VkRenderWindow&&) = delete; ///TODO
virtual ~VkRenderWindow();
OpenGLRenderImage& Acquire() override;
bool Create(RendererImpl* renderer, RenderSurface* surface, const Vector2ui& size, const RenderWindowParameters& parameters) override;
std::unique_ptr<CommandPool> CreateCommandPool(QueueType queueType) override;
inline const OpenGLFramebuffer& GetFramebuffer() const override;
inline OpenGLDevice& GetDevice();
inline const OpenGLDevice& GetDevice() const;
inline Vk::QueueHandle& GetGraphicsQueue();
const OpenGLRenderPass& GetRenderPass() const override;
inline const Vk::Swapchain& GetSwapchain() const;
std::shared_ptr<RenderDevice> GetRenderDevice() override;
void Present(UInt32 imageIndex, VkSemaphore waitSemaphore = VK_NULL_HANDLE);
VkRenderWindow& operator=(const VkRenderWindow&) = delete;
VkRenderWindow& operator=(VkRenderWindow&&) = delete; ///TODO
private:
bool SetupDepthBuffer(const Vector2ui& size);
bool SetupRenderPass();
bool SetupSwapchain(const Vk::PhysicalDevice& deviceInfo, Vk::Surface& surface, const Vector2ui& size);
std::size_t m_currentFrame;
Clock m_clock;
VkFormat m_depthStencilFormat;
VkSurfaceFormatKHR m_surfaceFormat;
std::optional<OpenGLMultipleFramebuffer> m_framebuffer;
std::optional<OpenGLRenderPass> m_renderPass;
std::shared_ptr<OpenGLDevice> m_device;
std::vector<Vk::Fence*> m_inflightFences;
std::vector<OpenGLRenderImage> m_concurrentImageData;
Vk::DeviceMemory m_depthBufferMemory;
Vk::Image m_depthBuffer;
Vk::ImageView m_depthBufferView;
Vk::QueueHandle m_graphicsQueue;
Vk::QueueHandle m_presentQueue;
Vk::QueueHandle m_transferQueue;
Vk::Swapchain m_swapchain;
};
}
#include <Nazara/OpenGLRenderer/VkRenderWindow.inl>
#endif // NAZARA_OPENGLRENDERER_RENDERWINDOW_HPP

View File

@ -0,0 +1,50 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/VkRenderWindow.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline const OpenGLMultipleFramebuffer& VkRenderWindow::GetFramebuffer() const
{
return *m_framebuffer;
}
inline OpenGLDevice& VkRenderWindow::GetDevice()
{
return *m_device;
}
inline const OpenGLDevice& VkRenderWindow::GetDevice() const
{
return *m_device;
}
inline Vk::QueueHandle& VkRenderWindow::GetGraphicsQueue()
{
return m_graphicsQueue;
}
inline const Vk::Swapchain& VkRenderWindow::GetSwapchain() const
{
return m_swapchain;
}
inline std::shared_ptr<RenderDevice> Nz::VkRenderWindow::GetRenderDevice()
{
return m_device;
}
inline void VkRenderWindow::Present(UInt32 imageIndex, VkSemaphore waitSemaphore)
{
NazaraAssert(imageIndex < m_inflightFences.size(), "Invalid image index");
m_presentQueue.Present(m_swapchain, imageIndex, waitSemaphore);
m_currentFrame = (m_currentFrame + 1) % m_inflightFences.size();
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,42 @@
// Copyright (C) 2020 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_OPENGLRENDERER_HPP
#define NAZARA_OPENGLRENDERER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/RendererImpl.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <list>
#include <vector>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLRenderer : public RendererImpl
{
public:
OpenGLRenderer() = default;
~OpenGLRenderer();
std::unique_ptr<RenderSurface> CreateRenderSurfaceImpl() override;
std::unique_ptr<RenderWindowImpl> CreateRenderWindowImpl() override;
std::shared_ptr<RenderDevice> InstanciateRenderDevice(std::size_t deviceIndex) override;
bool IsBetterThan(const RendererImpl* other) const override;
RenderAPI QueryAPI() const override;
std::string QueryAPIString() const override;
UInt32 QueryAPIVersion() const override;
std::vector<RenderDeviceInfo> QueryRenderDevices() const override;
bool Prepare(const ParameterList& parameters) override;
};
}
#include <Nazara/OpenGLRenderer/OpenGLRenderer.inl>
#endif // NAZARA_OPENGLRENDERER_HPP

View File

@ -0,0 +1,12 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLRenderer.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,48 @@
// Copyright (C) 2020 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_OPENGLRENDERER_OPENGLSHADERBINDING_HPP
#define NAZARA_OPENGLRENDERER_OPENGLSHADERBINDING_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DescriptorSet.hpp>
namespace Nz
{
class OpenGLRenderPipelineLayout;
class NAZARA_OPENGLRENDERER_API OpenGLShaderBinding : public ShaderBinding
{
public:
inline OpenGLShaderBinding(OpenGLRenderPipelineLayout& owner, std::size_t poolIndex, std::size_t bindingIndex, Vk::DescriptorSet descriptorSet);
OpenGLShaderBinding(const OpenGLShaderBinding&) = default;
OpenGLShaderBinding(OpenGLShaderBinding&&) noexcept = default;
~OpenGLShaderBinding() = default;
inline std::size_t GetBindingIndex() const;
inline const Vk::DescriptorSet& GetDescriptorSet() const;
inline std::size_t GetPoolIndex() const;
inline const OpenGLRenderPipelineLayout& GetOwner() const;
void Update(std::initializer_list<Binding> bindings) override;
OpenGLShaderBinding& operator=(const OpenGLShaderBinding&) = delete;
OpenGLShaderBinding& operator=(OpenGLShaderBinding&&) = delete;
private:
void Release() override;
Vk::AutoDescriptorSet m_descriptorSet;
OpenGLRenderPipelineLayout& m_owner;
std::size_t m_bindingIndex;
std::size_t m_poolIndex;
};
}
#include <Nazara/OpenGLRenderer/OpenGLShaderBinding.inl>
#endif // NAZARA_OPENGLRENDERER_OPENGLSHADERBINDING_HPP

View File

@ -0,0 +1,39 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLShaderBinding.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline OpenGLShaderBinding::OpenGLShaderBinding(OpenGLRenderPipelineLayout& owner, std::size_t poolIndex, std::size_t bindingIndex, Vk::DescriptorSet descriptorSet) :
m_descriptorSet(std::move(descriptorSet)),
m_owner(owner),
m_bindingIndex(bindingIndex),
m_poolIndex(poolIndex)
{
}
inline std::size_t OpenGLShaderBinding::GetBindingIndex() const
{
return m_bindingIndex;
}
inline std::size_t OpenGLShaderBinding::GetPoolIndex() const
{
return m_poolIndex;
}
inline const Vk::DescriptorSet& OpenGLShaderBinding::GetDescriptorSet() const
{
return m_descriptorSet;
}
inline const OpenGLRenderPipelineLayout& OpenGLShaderBinding::GetOwner() const
{
return m_owner;
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,42 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_OPENGLSHADERSTAGE_HPP
#define NAZARA_OPENGLRENDERER_OPENGLSHADERSTAGE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/ShaderStageImpl.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/ShaderModule.hpp>
#include <vector>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLShaderStage : public ShaderStageImpl
{
public:
OpenGLShaderStage() = default;
OpenGLShaderStage(const OpenGLShaderStage&) = delete;
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;
OpenGLShaderStage& operator=(const OpenGLShaderStage&) = delete;
OpenGLShaderStage& operator=(OpenGLShaderStage&&) noexcept = default;
private:
Vk::ShaderModule m_shaderModule;
ShaderStageType m_stage;
};
}
#include <Nazara/OpenGLRenderer/OpenGLShaderStage.inl>
#endif // NAZARA_OPENGLRENDERER_OPENGLSHADERSTAGE_HPP

View File

@ -0,0 +1,21 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLShaderStage.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
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

@ -0,0 +1,40 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_SURFACE_HPP
#define NAZARA_OPENGLRENDERER_SURFACE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/RenderSurface.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Surface.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Swapchain.hpp>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLSurface : public RenderSurface
{
public:
OpenGLSurface();
OpenGLSurface(const OpenGLSurface&) = delete;
OpenGLSurface(OpenGLSurface&&) = delete; ///TODO
virtual ~OpenGLSurface();
bool Create(WindowHandle handle) override;
void Destroy() override;
inline Vk::Surface& GetSurface();
OpenGLSurface& operator=(const OpenGLSurface&) = delete;
OpenGLSurface& operator=(OpenGLSurface&&) = delete; ///TODO
private:
Vk::Surface m_surface;
};
}
#include <Nazara/OpenGLRenderer/OpenGLSurface.inl>
#endif // NAZARA_OPENGLRENDERER_SURFACE_HPP

View File

@ -0,0 +1,16 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLSurface.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline Vk::Surface& OpenGLSurface::GetSurface()
{
return m_surface;
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,51 @@
// Copyright (C) 2020 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_OPENGLRENDERER_OPENGLTEXTURE_HPP
#define NAZARA_OPENGLRENDERER_OPENGLTEXTURE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Texture.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Image.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/ImageView.hpp>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLTexture : public Texture
{
public:
OpenGLTexture(Vk::Device& device, const TextureInfo& params);
OpenGLTexture(const OpenGLTexture&) = default;
OpenGLTexture(OpenGLTexture&&) noexcept = default;
~OpenGLTexture();
PixelFormat GetFormat() const override;
inline VkImage GetImage() const;
inline VkImageView GetImageView() const;
UInt8 GetLevelCount() const override;
Vector3ui GetSize(UInt8 level = 0) const override;
ImageType GetType() const override;
bool Update(const void* ptr) override;
OpenGLTexture& operator=(const OpenGLTexture&) = delete;
OpenGLTexture& operator=(OpenGLTexture&&) = delete;
private:
static void InitForFormat(PixelFormat pixelFormat, VkImageCreateInfo& createImage, VkImageViewCreateInfo& createImageView);
VkImage m_image;
VmaAllocation m_allocation;
Vk::Device& m_device;
Vk::ImageView m_imageView;
TextureInfo m_params;
};
}
#include <Nazara/OpenGLRenderer/OpenGLTexture.inl>
#endif // NAZARA_OPENGLRENDERER_OPENGLTEXTURE_HPP

View File

@ -0,0 +1,21 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLTexture.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline VkImage OpenGLTexture::GetImage() const
{
return m_image;
}
inline VkImageView OpenGLTexture::GetImageView() const
{
return m_imageView;
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,36 @@
// Copyright (C) 2020 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_OPENGLRENDERER_OPENGLTEXTURESAMPLER_HPP
#define NAZARA_OPENGLRENDERER_OPENGLTEXTURESAMPLER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/TextureSampler.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Sampler.hpp>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLTextureSampler : public TextureSampler
{
public:
OpenGLTextureSampler(Vk::Device& device, TextureSamplerInfo samplerInfo);
OpenGLTextureSampler(const OpenGLTextureSampler&) = default;
OpenGLTextureSampler(OpenGLTextureSampler&&) noexcept = default;
~OpenGLTextureSampler() = default;
inline VkSampler GetSampler() const;
OpenGLTextureSampler& operator=(const OpenGLTextureSampler&) = delete;
OpenGLTextureSampler& operator=(OpenGLTextureSampler&&) = delete;
private:
Vk::Sampler m_sampler;
};
}
#include <Nazara/OpenGLRenderer/OpenGLTextureSampler.inl>
#endif // NAZARA_OPENGLRENDERER_OPENGLTEXTURESAMPLER_HPP

View File

@ -0,0 +1,16 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLShaderBinding.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline VkSampler OpenGLTextureSampler::GetSampler() const
{
return m_sampler;
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,58 @@
// Copyright (C) 2020 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_OPENGLRENDERER_OPENGLUPLOADPOOL_HPP
#define NAZARA_OPENGLRENDERER_OPENGLUPLOADPOOL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/Renderer/UploadPool.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Buffer.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DeviceMemory.hpp>
#include <optional>
#include <vector>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLUploadPool : public UploadPool
{
public:
struct OpenGLAllocation : Allocation
{
VkBuffer buffer;
};
inline OpenGLUploadPool(Vk::Device& device, UInt64 blockSize);
OpenGLUploadPool(const OpenGLUploadPool&) = delete;
OpenGLUploadPool(OpenGLUploadPool&&) noexcept = default;
~OpenGLUploadPool() = default;
OpenGLAllocation& Allocate(UInt64 size) override;
OpenGLAllocation& Allocate(UInt64 size, UInt64 alignment) override;
void Reset() override;
OpenGLUploadPool& operator=(const OpenGLUploadPool&) = delete;
OpenGLUploadPool& operator=(OpenGLUploadPool&&) = delete;
private:
struct Block
{
Vk::DeviceMemory blockMemory;
Vk::Buffer buffer;
UInt64 freeOffset;
};
UInt64 m_blockSize;
Vk::Device& m_device;
std::vector<Block> m_blocks;
std::vector<OpenGLAllocation> m_allocations;
};
}
#include <Nazara/OpenGLRenderer/OpenGLUploadPool.inl>
#endif // NAZARA_OPENGLRENDERER_OPENGLUPLOADPOOL_HPP

View File

@ -0,0 +1,17 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLUploadPool.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline OpenGLUploadPool::OpenGLUploadPool(Vk::Device& device, UInt64 blockSize) :
m_blockSize(blockSize),
m_device(device)
{
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,39 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_UTILS_OPENGL_HPP
#define NAZARA_UTILS_OPENGL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Utility/Enums.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Loader.hpp>
#include <string>
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);
NAZARA_OPENGLRENDERER_API std::string TranslateOpenGLError(VkResult code);
}
#include <Nazara/OpenGLRenderer/Utils.inl>
#endif // NAZARA_UTILS_OPENGL_HPP

View File

@ -0,0 +1,218 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/Utils.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
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)
{
switch (stageType)
{
case ShaderStageType::Fragment: return VK_SHADER_STAGE_FRAGMENT_BIT;
case ShaderStageType::Vertex: return VK_SHADER_STAGE_VERTEX_BIT;
}
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

@ -0,0 +1,38 @@
// This file was automatically generated
#pragma once
#ifndef NAZARA_GLOBAL_OPENGLRENDERER_WRAPPER_HPP
#define NAZARA_GLOBAL_OPENGLRENDERER_WRAPPER_HPP
#include <Nazara/OpenGLRenderer/Wrapper/AutoFree.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Buffer.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CommandBuffer.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CommandPool.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DebugUtilsMessengerEXT.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DescriptorPool.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DescriptorSet.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DescriptorSetLayout.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Device.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DeviceMemory.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DeviceObject.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Fence.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Framebuffer.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Image.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/ImageView.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Instance.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/InstanceObject.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Loader.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/PhysicalDevice.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Pipeline.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/PipelineCache.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/PipelineLayout.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/QueueHandle.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/RenderPass.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Sampler.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Semaphore.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/ShaderModule.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Surface.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Swapchain.hpp>
#endif // NAZARA_GLOBAL_OPENGLRENDERER_WRAPPER_HPP

View File

@ -0,0 +1,39 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_GLCONTEXT_HPP
#define NAZARA_OPENGLRENDERER_GLCONTEXT_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CoreFunctions.hpp>
#include <string>
namespace Nz::GL
{
struct ContextParams
{
};
class GLContext
{
public:
GLContext() = default;
virtual ~GLContext();
virtual bool Activate() = 0;
virtual bool Create(const ContextParams& params) = 0;
virtual void EnableVerticalSync(bool enabled) = 0;
virtual void SwapBuffers() = 0;
};
}
#include <Nazara/OpenGLRenderer/Wrapper/GLContext.inl>
#endif

View File

@ -0,0 +1,12 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/GLContext.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz::Vk
{
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,46 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_VKBUFFER_HPP
#define NAZARA_OPENGLRENDERER_VKBUFFER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DeviceObject.hpp>
namespace Nz
{
namespace Vk
{
class Buffer : public DeviceObject<Buffer, VkBuffer, VkBufferCreateInfo, VK_OBJECT_TYPE_BUFFER>
{
friend DeviceObject;
public:
Buffer() = default;
Buffer(const Buffer&) = delete;
Buffer(Buffer&&) noexcept = default;
~Buffer() = default;
bool BindBufferMemory(VkDeviceMemory memory, VkDeviceSize offset = 0);
using DeviceObject::Create;
inline bool Create(Device& device, VkBufferCreateFlags flags, VkDeviceSize size, VkBufferUsageFlags usage, const VkAllocationCallbacks* allocator = nullptr);
VkMemoryRequirements GetMemoryRequirements() const;
Buffer& operator=(const Buffer&) = delete;
Buffer& operator=(Buffer&&) = delete;
private:
static inline VkResult CreateHelper(Device& device, const VkBufferCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkBuffer* handle);
static inline void DestroyHelper(Device& device, VkBuffer handle, const VkAllocationCallbacks* allocator);
};
}
}
#include <Nazara/OpenGLRenderer/Wrapper/Buffer.inl>
#endif // NAZARA_OPENGLRENDERER_VKBUFFER_HPP

View File

@ -0,0 +1,62 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/Buffer.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
namespace Vk
{
inline bool Buffer::BindBufferMemory(VkDeviceMemory memory, VkDeviceSize offset)
{
m_lastErrorCode = m_device->vkBindBufferMemory(*m_device, m_handle, memory, offset);
if (m_lastErrorCode != VK_SUCCESS)
{
NazaraError("Failed to bind buffer memory");
return false;
}
return true;
}
inline bool Buffer::Create(Device& device, VkBufferCreateFlags flags, VkDeviceSize size, VkBufferUsageFlags usage, const VkAllocationCallbacks* allocator)
{
VkBufferCreateInfo createInfo = {
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
nullptr, // const void* pNext;
flags, // VkBufferCreateFlags flags;
size, // VkDeviceSize size;
usage, // VkBufferUsageFlags usage;
VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
0, // uint32_t queueFamilyIndexCount;
nullptr // const uint32_t* pQueueFamilyIndices;
};
return Create(device, createInfo, allocator);
}
inline VkMemoryRequirements Buffer::GetMemoryRequirements() const
{
NazaraAssert(IsValid(), "Invalid buffer");
VkMemoryRequirements memoryRequirements;
m_device->vkGetBufferMemoryRequirements(*m_device, m_handle, &memoryRequirements);
return memoryRequirements;
}
inline VkResult Buffer::CreateHelper(Device& device, const VkBufferCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkBuffer* handle)
{
return device.vkCreateBuffer(device, createInfo, allocator, handle);
}
inline void Buffer::DestroyHelper(Device& device, VkBuffer handle, const VkAllocationCallbacks* allocator)
{
return device.vkDestroyBuffer(device, handle, allocator);
}
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,34 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_CONTEXT_HPP
#define NAZARA_OPENGLRENDERER_CONTEXT_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/GLContext.hpp>
#include <memory>
namespace Nz::GL
{
class Context
{
public:
Context() = default;
Context(const Context&) = delete;
Context(Context&& object) noexcept = default;
~Context() = default;
Context& operator=(const Context&) = delete;
Context& operator=(Context&& object) noexcept = default;
private:
std::unique_ptr<GLContext> m_impl;
};
}
#include <Nazara/OpenGLRenderer/Wrapper/Context.inl>
#endif

View File

@ -0,0 +1,12 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/Context.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz::GL
{
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,56 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_VKDEVICEOBJECT_HPP
#define NAZARA_OPENGLRENDERER_VKDEVICEOBJECT_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Device.hpp>
#include <vulkan/vulkan.h>
#include <string>
namespace Nz
{
namespace Vk
{
template<typename C, typename VkType, typename CreateInfo, VkObjectType ObjectType>
class DeviceObject
{
public:
DeviceObject();
DeviceObject(const DeviceObject&) = delete;
DeviceObject(DeviceObject&& object) noexcept;
~DeviceObject();
bool Create(Device& device, const CreateInfo& createInfo, const VkAllocationCallbacks* allocator = nullptr);
void Destroy();
bool IsValid() const;
Device* GetDevice() const;
VkResult GetLastErrorCode() const;
void SetDebugName(const char* name);
void SetDebugName(const std::string& name);
DeviceObject& operator=(const DeviceObject&) = delete;
DeviceObject& operator=(DeviceObject&& object) noexcept;
operator VkType() const;
protected:
MovablePtr<Device> m_device;
VkAllocationCallbacks m_allocator;
VkType m_handle;
mutable VkResult m_lastErrorCode;
};
}
}
#include <Nazara/OpenGLRenderer/Wrapper/DeviceObject.inl>
#endif // NAZARA_OPENGLRENDERER_VKDEVICEOBJECT_HPP

View File

@ -0,0 +1,123 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/DeviceObject.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/OpenGLRenderer/Utils.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
namespace Vk
{
template<typename C, typename VkType, typename CreateInfo, VkObjectType ObjectType>
DeviceObject<C, VkType, CreateInfo, ObjectType>::DeviceObject() :
m_handle(VK_NULL_HANDLE)
{
}
template<typename C, typename VkType, typename CreateInfo, VkObjectType ObjectType>
DeviceObject<C, VkType, CreateInfo, ObjectType>::DeviceObject(DeviceObject&& object) noexcept :
m_device(std::move(object.m_device)),
m_allocator(object.m_allocator),
m_handle(object.m_handle),
m_lastErrorCode(object.m_lastErrorCode)
{
object.m_handle = VK_NULL_HANDLE;
}
template<typename C, typename VkType, typename CreateInfo, VkObjectType ObjectType>
DeviceObject<C, VkType, CreateInfo, ObjectType>::~DeviceObject()
{
Destroy();
}
template<typename C, typename VkType, typename CreateInfo, VkObjectType ObjectType>
bool DeviceObject<C, VkType, CreateInfo, ObjectType>::Create(Device& device, const CreateInfo& createInfo, const VkAllocationCallbacks* allocator)
{
m_device = &device;
m_lastErrorCode = C::CreateHelper(*m_device, &createInfo, allocator, &m_handle);
if (m_lastErrorCode != VkResult::VK_SUCCESS)
{
NazaraError("Failed to create OpenGL object: " + TranslateOpenGLError(m_lastErrorCode));
return false;
}
// Store the allocator to access them when needed
if (allocator)
m_allocator = *allocator;
else
m_allocator.pfnAllocation = nullptr;
return true;
}
template<typename C, typename VkType, typename CreateInfo, VkObjectType ObjectType>
void DeviceObject<C, VkType, CreateInfo, ObjectType>::Destroy()
{
if (IsValid())
{
C::DestroyHelper(*m_device, m_handle, (m_allocator.pfnAllocation) ? &m_allocator : nullptr);
m_handle = VK_NULL_HANDLE;
}
}
template<typename C, typename VkType, typename CreateInfo, VkObjectType ObjectType>
bool DeviceObject<C, VkType, CreateInfo, ObjectType>::IsValid() const
{
return m_handle != VK_NULL_HANDLE;
}
template<typename C, typename VkType, typename CreateInfo, VkObjectType ObjectType>
Device* DeviceObject<C, VkType, CreateInfo, ObjectType>::GetDevice() const
{
return m_device;
}
template<typename C, typename VkType, typename CreateInfo, VkObjectType ObjectType>
VkResult DeviceObject<C, VkType, CreateInfo, ObjectType>::GetLastErrorCode() const
{
return m_lastErrorCode;
}
template<typename C, typename VkType, typename CreateInfo, VkObjectType ObjectType>
void DeviceObject<C, VkType, CreateInfo, ObjectType>::SetDebugName(const char* name)
{
if (m_device->vkSetDebugUtilsObjectNameEXT)
{
VkDebugUtilsObjectNameInfoEXT debugName = { VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT };
debugName.objectType = ObjectType;
debugName.objectHandle = static_cast<UInt64>(reinterpret_cast<std::uintptr_t>(m_handle));
debugName.pObjectName = name;
m_device->vkSetDebugUtilsObjectNameEXT(*m_device, &debugName);
}
}
template<typename C, typename VkType, typename CreateInfo, VkObjectType ObjectType>
void DeviceObject<C, VkType, CreateInfo, ObjectType>::SetDebugName(const std::string& name)
{
return SetDebugName(name.data());
}
template<typename C, typename VkType, typename CreateInfo, VkObjectType ObjectType>
auto DeviceObject<C, VkType, CreateInfo, ObjectType>::operator=(DeviceObject&& object) noexcept -> DeviceObject&
{
std::swap(m_allocator, object.m_allocator);
std::swap(m_device, object.m_device);
std::swap(m_handle, object.m_handle);
std::swap(m_lastErrorCode, object.m_lastErrorCode);
return *this;
}
template<typename C, typename VkType, typename CreateInfo, VkObjectType ObjectType>
DeviceObject<C, VkType, CreateInfo, ObjectType>::operator VkType() const
{
return m_handle;
}
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,140 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_COREFUNCTIONS_HPP
#define NAZARA_OPENGLRENDERER_COREFUNCTIONS_HPP
#include <GLES3/gl3.h>
// OpenGL core
#define NAZARA_OPENGLRENDERER_FOREACH_GLES_FUNC(cb) \
cb(glActiveTexture, PFNGLACTIVETEXTUREPROC) \
cb(glAttachShader, PFNGLATTACHSHADERPROC) \
cb(glBeginQuery, PFNGLBEGINQUERYPROC) \
cb(glBindAttribLocation, PFNGLBINDATTRIBLOCATIONPROC) \
cb(glBindBuffer, PFNGLBINDBUFFERPROC) \
cb(glBindFramebuffer, PFNGLBINDFRAMEBUFFERPROC) \
cb(glBindRenderbuffer, PFNGLBINDRENDERBUFFERPROC) \
cb(glBindSampler, PFNGLBINDSAMPLERPROC) \
cb(glBindTexture, PFNGLBINDTEXTUREPROC) \
cb(glBindVertexArray, PFNGLBINDVERTEXARRAYPROC) \
cb(glBlendFunc, PFNGLBLENDFUNCPROC) \
cb(glBlendFuncSeparate, PFNGLBLENDFUNCSEPARATEPROC) \
cb(glBlitFramebuffer, PFNGLBLITFRAMEBUFFERPROC) \
cb(glBufferData, PFNGLBUFFERDATAPROC) \
cb(glBufferSubData, PFNGLBUFFERSUBDATAPROC) \
cb(glClear, PFNGLCLEARPROC) \
cb(glClearColor, PFNGLCLEARCOLORPROC) \
cb(glClearStencil, PFNGLCLEARSTENCILPROC) \
cb(glCreateProgram, PFNGLCREATEPROGRAMPROC) \
cb(glCreateShader, PFNGLCREATESHADERPROC) \
cb(glCheckFramebufferStatus, PFNGLCHECKFRAMEBUFFERSTATUSPROC) \
cb(glColorMask, PFNGLCOLORMASKPROC) \
cb(glCompressedTexSubImage2D, PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) \
cb(glCompressedTexSubImage3D, PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) \
cb(glCullFace, PFNGLCULLFACEPROC) \
cb(glCompileShader, PFNGLCOMPILESHADERPROC) \
cb(glCopyTexSubImage2D, PFNGLCOPYTEXSUBIMAGE2DPROC) \
cb(glDeleteBuffers, PFNGLDELETEBUFFERSPROC) \
cb(glDeleteFramebuffers, PFNGLDELETEFRAMEBUFFERSPROC) \
cb(glDeleteProgram, PFNGLDELETEPROGRAMPROC) \
cb(glDeleteQueries, PFNGLDELETEQUERIESPROC) \
cb(glDeleteRenderbuffers, PFNGLDELETERENDERBUFFERSPROC) \
cb(glDeleteSamplers, PFNGLDELETESAMPLERSPROC) \
cb(glDeleteShader, PFNGLDELETESHADERPROC) \
cb(glDeleteTextures, PFNGLDELETETEXTURESPROC) \
cb(glDeleteVertexArrays, PFNGLDELETEVERTEXARRAYSPROC) \
cb(glDepthFunc, PFNGLDEPTHFUNCPROC) \
cb(glDepthMask, PFNGLDEPTHMASKPROC) \
cb(glDisable, PFNGLDISABLEPROC) \
cb(glDisableVertexAttribArray, PFNGLDISABLEVERTEXATTRIBARRAYPROC) \
cb(glDrawArrays, PFNGLDRAWARRAYSPROC) \
cb(glDrawArraysInstanced, PFNGLDRAWARRAYSINSTANCEDPROC) \
cb(glDrawBuffers, PFNGLDRAWBUFFERSPROC) \
cb(glDrawElements, PFNGLDRAWELEMENTSPROC) \
cb(glDrawElementsInstanced, PFNGLDRAWELEMENTSINSTANCEDPROC) \
cb(glEnable, PFNGLENABLEPROC) \
cb(glEnableVertexAttribArray, PFNGLENABLEVERTEXATTRIBARRAYPROC) \
cb(glEndQuery, PFNGLENDQUERYPROC) \
cb(glFlush, PFNGLFLUSHPROC) \
cb(glFramebufferRenderbuffer, PFNGLFRAMEBUFFERRENDERBUFFERPROC) \
cb(glFramebufferTexture2D, PFNGLFRAMEBUFFERTEXTURE2DPROC) \
cb(glFramebufferTextureLayer, PFNGLFRAMEBUFFERTEXTURELAYERPROC) \
cb(glGenerateMipmap, PFNGLGENERATEMIPMAPPROC) \
cb(glGenBuffers, PFNGLGENBUFFERSPROC) \
cb(glGenFramebuffers, PFNGLGENFRAMEBUFFERSPROC) \
cb(glGenRenderbuffers, PFNGLGENRENDERBUFFERSPROC) \
cb(glGenQueries, PFNGLGENQUERIESPROC) \
cb(glGenSamplers, PFNGLGENSAMPLERSPROC) \
cb(glGenTextures, PFNGLGENTEXTURESPROC) \
cb(glGenVertexArrays, PFNGLGENVERTEXARRAYSPROC) \
cb(glGetActiveUniform, PFNGLGETACTIVEUNIFORMPROC) \
cb(glGetBooleanv, PFNGLGETBOOLEANVPROC) \
cb(glGetBufferParameteriv, PFNGLGETBUFFERPARAMETERIVPROC) \
cb(glGetError, PFNGLGETERRORPROC) \
cb(glGetFloatv, PFNGLGETFLOATVPROC) \
cb(glGetIntegerv, PFNGLGETINTEGERVPROC) \
cb(glGetProgramBinary, PFNGLGETPROGRAMBINARYPROC) \
cb(glGetProgramiv, PFNGLGETPROGRAMIVPROC) \
cb(glGetProgramInfoLog, PFNGLGETPROGRAMINFOLOGPROC) \
cb(glGetQueryiv, PFNGLGETQUERYIVPROC) \
cb(glGetQueryObjectuiv, PFNGLGETQUERYOBJECTUIVPROC) \
cb(glGetShaderInfoLog, PFNGLGETSHADERINFOLOGPROC) \
cb(glGetShaderiv, PFNGLGETSHADERIVPROC) \
cb(glGetShaderSource, PFNGLGETSHADERSOURCEPROC) \
cb(glGetString, PFNGLGETSTRINGPROC) \
cb(glGetStringi, PFNGLGETSTRINGIPROC) \
cb(glGetTexParameterfv, PFNGLGETTEXPARAMETERFVPROC) \
cb(glGetTexParameteriv, PFNGLGETTEXPARAMETERIVPROC) \
cb(glGetUniformfv, PFNGLGETUNIFORMFVPROC) \
cb(glGetUniformiv, PFNGLGETUNIFORMIVPROC) \
cb(glGetUniformLocation, PFNGLGETUNIFORMLOCATIONPROC) \
cb(glIsEnabled, PFNGLISENABLEDPROC) \
cb(glLineWidth, PFNGLLINEWIDTHPROC) \
cb(glLinkProgram, PFNGLLINKPROGRAMPROC) \
cb(glMapBufferRange, PFNGLMAPBUFFERRANGEPROC) \
cb(glPixelStorei, PFNGLPIXELSTOREIPROC) \
cb(glProgramBinary, PFNGLPROGRAMBINARYPROC) \
cb(glProgramParameteri, PFNGLPROGRAMPARAMETERIPROC) \
cb(glReadPixels, PFNGLREADPIXELSPROC) \
cb(glRenderbufferStorage, PFNGLRENDERBUFFERSTORAGEPROC) \
cb(glSamplerParameterf, PFNGLSAMPLERPARAMETERFPROC) \
cb(glSamplerParameteri, PFNGLSAMPLERPARAMETERIPROC) \
cb(glScissor, PFNGLSCISSORPROC) \
cb(glShaderSource, PFNGLSHADERSOURCEPROC) \
cb(glStencilFunc, PFNGLSTENCILFUNCPROC) \
cb(glStencilFuncSeparate, PFNGLSTENCILFUNCSEPARATEPROC) \
cb(glStencilOp, PFNGLSTENCILOPPROC) \
cb(glStencilOpSeparate, PFNGLSTENCILOPSEPARATEPROC) \
cb(glTexImage2D, PFNGLTEXIMAGE2DPROC) \
cb(glTexImage3D, PFNGLTEXIMAGE3DPROC) \
cb(glTexParameterf, PFNGLTEXPARAMETERFPROC) \
cb(glTexParameteri, PFNGLTEXPARAMETERIPROC) \
cb(glTexStorage2D, PFNGLTEXSTORAGE2DPROC) \
cb(glTexStorage3D, PFNGLTEXSTORAGE3DPROC) \
cb(glTexSubImage2D, PFNGLTEXSUBIMAGE2DPROC) \
cb(glTexSubImage3D, PFNGLTEXSUBIMAGE3DPROC) \
cb(glUniform1f, PFNGLUNIFORM1FPROC) \
cb(glUniform1i, PFNGLUNIFORM1IPROC) \
cb(glUniform1fv, PFNGLUNIFORM1FVPROC) \
cb(glUniform1iv, PFNGLUNIFORM1IVPROC) \
cb(glUniform2fv, PFNGLUNIFORM2FVPROC) \
cb(glUniform2iv, PFNGLUNIFORM2IVPROC) \
cb(glUniform3fv, PFNGLUNIFORM3FVPROC) \
cb(glUniform3iv, PFNGLUNIFORM3IVPROC) \
cb(glUniform4fv, PFNGLUNIFORM4FVPROC) \
cb(glUniform4iv, PFNGLUNIFORM4IVPROC) \
cb(glUniformMatrix4fv, PFNGLUNIFORMMATRIX4FVPROC) \
cb(glUnmapBuffer, PFNGLUNMAPBUFFERPROC) \
cb(glUseProgram, PFNGLUSEPROGRAMPROC) \
cb(glValidateProgram, PFNGLVALIDATEPROGRAMPROC) \
cb(glVertexAttrib4f, PFNGLVERTEXATTRIB4FPROC) \
cb(glVertexAttribDivisor, PFNGLVERTEXATTRIBDIVISORPROC) \
cb(glVertexAttribPointer, PFNGLVERTEXATTRIBPOINTERPROC) \
cb(glVertexAttribIPointer, PFNGLVERTEXATTRIBIPOINTERPROC) \
cb(glViewport, PFNGLVIEWPORTPROC) \
#endif

View File

@ -0,0 +1,39 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_VKFRAMEBUFFER_HPP
#define NAZARA_OPENGLRENDERER_VKFRAMEBUFFER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DeviceObject.hpp>
namespace Nz
{
namespace Vk
{
class Framebuffer : public DeviceObject<Framebuffer, VkFramebuffer, VkFramebufferCreateInfo, VK_OBJECT_TYPE_FRAMEBUFFER>
{
friend DeviceObject;
public:
Framebuffer() = default;
Framebuffer(const Framebuffer&) = delete;
Framebuffer(Framebuffer&&) = default;
~Framebuffer() = default;
Framebuffer& operator=(const Framebuffer&) = delete;
Framebuffer& operator=(Framebuffer&&) = delete;
private:
static inline VkResult CreateHelper(Device& device, const VkFramebufferCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkFramebuffer* handle);
static inline void DestroyHelper(Device& device, VkFramebuffer handle, const VkAllocationCallbacks* allocator);
};
}
}
#include <Nazara/OpenGLRenderer/Wrapper/Framebuffer.inl>
#endif // NAZARA_OPENGLRENDERER_VKFRAMEBUFFER_HPP

View File

@ -0,0 +1,24 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/Framebuffer.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
namespace Vk
{
inline VkResult Framebuffer::CreateHelper(Device& device, const VkFramebufferCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkFramebuffer* handle)
{
return device.vkCreateFramebuffer(device, createInfo, allocator, handle);
}
inline void Framebuffer::DestroyHelper(Device& device, VkFramebuffer handle, const VkAllocationCallbacks* allocator)
{
return device.vkDestroyFramebuffer(device, handle, allocator);
}
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,52 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_CONTEXTIMPL_HPP
#define NAZARA_OPENGLRENDERER_CONTEXTIMPL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CoreFunctions.hpp>
#include <string>
namespace Nz::GL
{
struct ContextParams
{
bool doubleBuffering = true;
unsigned int sampleCount = 1;
unsigned int bitsPerPixel = 32;
unsigned int depthBits = 24;
unsigned int stencilBits = 8;
};
class Loader;
class GLContext
{
public:
GLContext() = default;
virtual ~GLContext();
virtual bool Activate() = 0;
virtual bool Create(const ContextParams& params) = 0;
virtual void EnableVerticalSync(bool enabled) = 0;
bool LoadCoreFunctions(Loader& loader);
virtual void SwapBuffers() = 0;
private:
#define NAZARA_OPENGLRENDERER_FUNC(name, sig) sig name = nullptr;
NAZARA_OPENGLRENDERER_FOREACH_GLES_FUNC(NAZARA_OPENGLRENDERER_FUNC)
#undef NAZARA_OPENGLRENDERER_FUNC
};
}
#include <Nazara/OpenGLRenderer/Wrapper/GLContext.inl>
#endif

View File

@ -0,0 +1,12 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/GLContext.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz::Vk
{
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,34 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_LOADER_HPP
#define NAZARA_OPENGLRENDERER_LOADER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <memory>
namespace Nz::GL
{
class GLContext;
using GLFunction = int(*)();
class NAZARA_OPENGLRENDERER_API Loader
{
public:
Loader() = default;
virtual ~Loader();
virtual std::unique_ptr<GLContext> CreateContext() = 0;
virtual GLFunction LoadFunction(const char* name) = 0;
};
}
#include <Nazara/OpenGLRenderer/Wrapper/Loader.inl>
#endif

View File

@ -0,0 +1,12 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/Loader.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz::GL
{
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,43 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_VKIMAGE_HPP
#define NAZARA_OPENGLRENDERER_VKIMAGE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DeviceObject.hpp>
namespace Nz
{
namespace Vk
{
class Image : public DeviceObject<Image, VkImage, VkImageCreateInfo, VK_OBJECT_TYPE_IMAGE>
{
friend DeviceObject;
public:
Image() = default;
Image(const Image&) = delete;
Image(Image&&) = default;
~Image() = default;
bool BindImageMemory(VkDeviceMemory memory, VkDeviceSize offset = 0);
VkMemoryRequirements GetMemoryRequirements() const;
Image& operator=(const Image&) = delete;
Image& operator=(Image&&) = delete;
private:
static inline VkResult CreateHelper(Device& device, const VkImageCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkImage* handle);
static inline void DestroyHelper(Device& device, VkImage handle, const VkAllocationCallbacks* allocator);
};
}
}
#include <Nazara/OpenGLRenderer/Wrapper/Image.inl>
#endif // NAZARA_OPENGLRENDERER_VKIMAGE_HPP

View File

@ -0,0 +1,47 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/Image.hpp>
#include <Nazara/OpenGLRenderer/Utils.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
namespace Vk
{
inline bool Image::BindImageMemory(VkDeviceMemory memory, VkDeviceSize offset)
{
m_lastErrorCode = m_device->vkBindImageMemory(*m_device, m_handle, memory, offset);
if (m_lastErrorCode != VK_SUCCESS)
{
NazaraError("Failed to bind image memory: " + TranslateOpenGLError(m_lastErrorCode));
return false;
}
return true;
}
inline VkMemoryRequirements Image::GetMemoryRequirements() const
{
NazaraAssert(IsValid(), "Invalid image");
VkMemoryRequirements memoryRequirements;
m_device->vkGetImageMemoryRequirements(*m_device, m_handle, &memoryRequirements);
return memoryRequirements;
}
inline VkResult Image::CreateHelper(Device& device, const VkImageCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkImage* handle)
{
return device.vkCreateImage(device, createInfo, allocator, handle);
}
inline void Image::DestroyHelper(Device& device, VkImage handle, const VkAllocationCallbacks* allocator)
{
return device.vkDestroyImage(device, handle, allocator);
}
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,47 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_VKFENCE_HPP
#define NAZARA_OPENGLRENDERER_VKFENCE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DeviceObject.hpp>
namespace Nz
{
namespace Vk
{
class Fence : public DeviceObject<Fence, VkFence, VkFenceCreateInfo, VK_OBJECT_TYPE_FENCE>
{
friend DeviceObject;
public:
Fence() = default;
Fence(const Fence&) = delete;
Fence(Fence&&) = default;
~Fence() = default;
using DeviceObject::Create;
inline bool Create(Device& device, VkFenceCreateFlags flags = 0, const VkAllocationCallbacks* allocator = nullptr);
inline bool Reset();
inline bool Wait();
inline bool Wait(UInt64 timeout, bool* didTimeout = nullptr);
Fence& operator=(const Fence&) = delete;
Fence& operator=(Fence&&) = delete;
private:
static inline VkResult CreateHelper(Device& device, const VkFenceCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkFence* handle);
static inline void DestroyHelper(Device& device, VkFence handle, const VkAllocationCallbacks* allocator);
};
}
}
#include <Nazara/OpenGLRenderer/Wrapper/Fence.inl>
#endif // NAZARA_OPENGLRENDERER_VKFENCE_HPP

View File

@ -0,0 +1,68 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/Fence.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
namespace Vk
{
inline bool Fence::Create(Device& device, VkFenceCreateFlags flags, const VkAllocationCallbacks* allocator)
{
VkFenceCreateInfo createInfo =
{
VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
nullptr,
flags
};
return Create(device, createInfo, allocator);
}
inline bool Fence::Reset()
{
m_lastErrorCode = m_device->vkResetFences(*m_device, 1U, &m_handle);
if (m_lastErrorCode != VK_SUCCESS)
{
NazaraError("Failed to reset fence: " + TranslateOpenGLError(m_lastErrorCode));
return false;
}
return true;
}
inline bool Fence::Wait()
{
return Wait(std::numeric_limits<UInt64>::max());
}
inline bool Fence::Wait(UInt64 timeout, bool* didTimeout)
{
m_lastErrorCode = m_device->vkWaitForFences(*m_device, 1U, &m_handle, VK_TRUE, timeout);
if (m_lastErrorCode != VK_SUCCESS && m_lastErrorCode != VK_TIMEOUT)
{
NazaraError("Failed to wait for fence: " + TranslateOpenGLError(m_lastErrorCode));
return false;
}
if (didTimeout)
*didTimeout = (m_lastErrorCode == VK_TIMEOUT);
return true;
}
inline VkResult Fence::CreateHelper(Device& device, const VkFenceCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkFence* handle)
{
return device.vkCreateFence(device, createInfo, allocator, handle);
}
inline void Fence::DestroyHelper(Device& device, VkFence handle, const VkAllocationCallbacks* allocator)
{
return device.vkDestroyFence(device, handle, allocator);
}
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,39 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_VKSAMPLER_HPP
#define NAZARA_OPENGLRENDERER_VKSAMPLER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DeviceObject.hpp>
namespace Nz
{
namespace Vk
{
class Sampler : public DeviceObject<Sampler, VkSampler, VkSamplerCreateInfo, VK_OBJECT_TYPE_SAMPLER>
{
friend DeviceObject;
public:
Sampler() = default;
Sampler(const Sampler&) = delete;
Sampler(Sampler&&) = default;
~Sampler() = default;
Sampler& operator=(const Sampler&) = delete;
Sampler& operator=(Sampler&&) = delete;
private:
static inline VkResult CreateHelper(Device& device, const VkSamplerCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkSampler* handle);
static inline void DestroyHelper(Device& device, VkSampler handle, const VkAllocationCallbacks* allocator);
};
}
}
#include <Nazara/OpenGLRenderer/Wrapper/Sampler.inl>
#endif // NAZARA_OPENGLRENDERER_VKSAMPLER_HPP

View File

@ -0,0 +1,24 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/Sampler.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
namespace Vk
{
inline VkResult Sampler::CreateHelper(Device& device, const VkSamplerCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkSampler* handle)
{
return device.vkCreateSampler(device, createInfo, allocator, handle);
}
inline void Sampler::DestroyHelper(Device& device, VkSampler handle, const VkAllocationCallbacks* allocator)
{
return device.vkDestroySampler(device, handle, allocator);
}
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,42 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_VKSHADERMODULE_HPP
#define NAZARA_OPENGLRENDERER_VKSHADERMODULE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DeviceObject.hpp>
namespace Nz
{
namespace Vk
{
class ShaderModule : public DeviceObject<ShaderModule, VkShaderModule, VkShaderModuleCreateInfo, VK_OBJECT_TYPE_SHADER_MODULE>
{
friend DeviceObject;
public:
ShaderModule() = default;
ShaderModule(const ShaderModule&) = delete;
ShaderModule(ShaderModule&&) = default;
~ShaderModule() = default;
using DeviceObject::Create;
inline bool Create(Device& device, const UInt32* code, std::size_t size, VkShaderModuleCreateFlags flags = 0, const VkAllocationCallbacks* allocator = nullptr);
ShaderModule& operator=(const ShaderModule&) = delete;
ShaderModule& operator=(ShaderModule&&) = delete;
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);
};
}
}
#include <Nazara/OpenGLRenderer/Wrapper/ShaderModule.inl>
#endif // NAZARA_OPENGLRENDERER_VKSHADERMODULE_HPP

View File

@ -0,0 +1,38 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/Debug.hpp>
namespace Nz
{
namespace Vk
{
inline bool ShaderModule::Create(Device& device, const UInt32* code, std::size_t size, VkShaderModuleCreateFlags flags, const VkAllocationCallbacks* allocator)
{
VkShaderModuleCreateInfo createInfo =
{
VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
nullptr,
flags,
size,
code
};
return Create(device, createInfo, allocator);
}
inline VkResult ShaderModule::CreateHelper(Device& device, const VkShaderModuleCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkShaderModule* handle)
{
return device.vkCreateShaderModule(device, createInfo, allocator, handle);
}
inline void ShaderModule::DestroyHelper(Device& device, VkShaderModule handle, const VkAllocationCallbacks* allocator)
{
return device.vkDestroyShaderModule(device, handle, allocator);
}
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,43 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_VKPIPELINELAYOUT_HPP
#define NAZARA_OPENGLRENDERER_VKPIPELINELAYOUT_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DeviceObject.hpp>
namespace Nz
{
namespace Vk
{
class PipelineLayout : public DeviceObject<PipelineLayout, VkPipelineLayout, VkPipelineLayoutCreateInfo, VK_OBJECT_TYPE_PIPELINE_LAYOUT>
{
friend DeviceObject;
public:
PipelineLayout() = default;
PipelineLayout(const PipelineLayout&) = delete;
PipelineLayout(PipelineLayout&&) = default;
~PipelineLayout() = default;
using DeviceObject::Create;
bool Create(Device& device, VkDescriptorSetLayout layout, VkPipelineLayoutCreateFlags flags = 0);
bool Create(Device& device, UInt32 layoutCount, const VkDescriptorSetLayout* layouts, VkPipelineLayoutCreateFlags flags = 0);
PipelineLayout& operator=(const PipelineLayout&) = delete;
PipelineLayout& operator=(PipelineLayout&&) = delete;
private:
static inline VkResult CreateHelper(Device& device, const VkPipelineLayoutCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkPipelineLayout* handle);
static inline void DestroyHelper(Device& device, VkPipelineLayout handle, const VkAllocationCallbacks* allocator);
};
}
}
#include <Nazara/OpenGLRenderer/Wrapper/PipelineLayout.inl>
#endif // NAZARA_OPENGLRENDERER_VKPIPELINELAYOUT_HPP

View File

@ -0,0 +1,44 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/PipelineLayout.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
namespace Vk
{
inline bool PipelineLayout::Create(Device& device, VkDescriptorSetLayout layout, VkPipelineLayoutCreateFlags flags)
{
return Create(device, 1U, &layout, flags);
}
inline bool PipelineLayout::Create(Device& device, UInt32 layoutCount, const VkDescriptorSetLayout* layouts, VkPipelineLayoutCreateFlags flags)
{
VkPipelineLayoutCreateInfo createInfo = {
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
nullptr,
flags,
layoutCount,
layouts,
0U,
nullptr
};
return Create(device, createInfo);
}
inline VkResult PipelineLayout::CreateHelper(Device& device, const VkPipelineLayoutCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkPipelineLayout* handle)
{
return device.vkCreatePipelineLayout(device, createInfo, allocator, handle);
}
inline void PipelineLayout::DestroyHelper(Device& device, VkPipelineLayout handle, const VkAllocationCallbacks* allocator)
{
return device.vkDestroyPipelineLayout(device, handle, allocator);
}
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,39 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_VKIMAGEVIEW_HPP
#define NAZARA_OPENGLRENDERER_VKIMAGEVIEW_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DeviceObject.hpp>
namespace Nz
{
namespace Vk
{
class ImageView : public DeviceObject<ImageView, VkImageView, VkImageViewCreateInfo, VK_OBJECT_TYPE_IMAGE_VIEW>
{
friend DeviceObject;
public:
ImageView() = default;
ImageView(const ImageView&) = delete;
ImageView(ImageView&&) = default;
~ImageView() = default;
ImageView& operator=(const ImageView&) = delete;
ImageView& operator=(ImageView&&) = delete;
private:
static inline VkResult CreateHelper(Device& device, const VkImageViewCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkImageView* handle);
static inline void DestroyHelper(Device& device, VkImageView handle, const VkAllocationCallbacks* allocator);
};
}
}
#include <Nazara/OpenGLRenderer/Wrapper/ImageView.inl>
#endif // NAZARA_OPENGLRENDERER_VKIMAGEVIEW_HPP

View File

@ -0,0 +1,24 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/ImageView.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
namespace Vk
{
inline VkResult ImageView::CreateHelper(Device& device, const VkImageViewCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkImageView* handle)
{
return device.vkCreateImageView(device, createInfo, allocator, handle);
}
inline void ImageView::DestroyHelper(Device& device, VkImageView handle, const VkAllocationCallbacks* allocator)
{
return device.vkDestroyImageView(device, handle, allocator);
}
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,71 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_WGLCONTEXT_HPP
#define NAZARA_OPENGLRENDERER_WGLCONTEXT_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/DynLib.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/GLContext.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Win32/WGLLoader.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Win32/Win32Helper.hpp>
#include <string>
#include <type_traits>
#include <unordered_set>
#undef WIN32_LEAN_AND_MEAN //< Redefined by OpenGL header (ty Khronos)
#include <Nazara/OpenGLRenderer/Wrapper/Win32/WGLFunctions.hpp>
namespace Nz::GL
{
class WGLLoader;
class WGLContext : public GLContext
{
public:
WGLContext(WGLLoader& loader);
WGLContext(const WGLContext&) = delete;
WGLContext(WGLContext&&) = delete;
~WGLContext();
bool Activate() override;
bool Create(const ContextParams& params) override;
void Destroy();
void EnableVerticalSync(bool enabled) override;
void SwapBuffers() override;
WGLContext& operator=(const WGLContext&) = delete;
WGLContext& operator=(WGLContext&&) = delete;
private:
void Desactivate();
bool LoadWGLExt();
bool SetPixelFormat(const ContextParams& params);
#define NAZARA_OPENGLRENDERER_FUNC(name, sig)
#define NAZARA_OPENGLRENDERER_EXT_BEGIN(ext)
#define NAZARA_OPENGLRENDERER_EXT_END()
#define NAZARA_OPENGLRENDERER_EXT_FUNC(name, sig) sig name = nullptr;
NAZARA_OPENGLRENDERER_FOREACH_WGL_FUNC(NAZARA_OPENGLRENDERER_FUNC, NAZARA_OPENGLRENDERER_EXT_BEGIN, NAZARA_OPENGLRENDERER_EXT_END, NAZARA_OPENGLRENDERER_EXT_FUNC)
#undef NAZARA_OPENGLRENDERER_EXT_BEGIN
#undef NAZARA_OPENGLRENDERER_EXT_END
#undef NAZARA_OPENGLRENDERER_EXT_FUNC
#undef NAZARA_OPENGLRENDERER_FUNC
std::unordered_set<std::string> m_supportedExtensions;
WGLLoader& m_loader;
HDC m_deviceContext;
HGLRC m_handle;
HWNDHandle m_window;
};
}
#include <Nazara/OpenGLRenderer/Wrapper/Win32/WGLContext.inl>
#endif

View File

@ -0,0 +1,12 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/Win32/WGLContext.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz::Vk
{
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,48 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_WGLFUNCTIONS_HPP
#define NAZARA_OPENGLRENDERER_WGLFUNCTIONS_HPP
#include <GLES3/gl3.h>
#include <GL/wgl.h>
#include <GL/wglext.h>
#define NAZARA_OPENGLRENDERER_FOREACH_WGL_FUNC(func, extBegin, extEnd, extFunc) \
func(wglCreateContext, PFNWGLCREATECONTEXTPROC) \
func(wglDeleteContext, PFNWGLDELETECONTEXTPROC) \
func(wglGetCurrentContext, PFNWGLGETCURRENTCONTEXTPROC) \
func(wglGetProcAddress, PFNWGLGETPROCADDRESSPROC) \
func(wglMakeCurrent, PFNWGLMAKECURRENTPROC) \
func(wglShareLists, PFNWGLSHARELISTSPROC) \
\
extBegin(WGL_ARB_create_context) \
extFunc(wglCreateContextAttribsARB, PFNWGLCREATECONTEXTATTRIBSARBPROC) \
extEnd() \
\
extBegin(WGL_ARB_pixel_format) \
extFunc(wglChoosePixelFormatARB, PFNWGLCHOOSEPIXELFORMATARBPROC) \
extEnd() \
\
extBegin(WGL_EXT_pixel_format) \
extFunc(wglChoosePixelFormatEXT, PFNWGLCHOOSEPIXELFORMATEXTPROC) \
extEnd() \
\
extBegin(WGL_ARB_extensions_string) \
extFunc(wglGetExtensionsStringARB, PFNWGLGETEXTENSIONSSTRINGARBPROC) \
extEnd() \
\
extBegin(WGL_EXT_extensions_string) \
extFunc(wglGetExtensionsStringEXT, PFNWGLGETEXTENSIONSSTRINGEXTPROC) \
extEnd() \
#define NAZARA_OPENGLRENDERER_FOREACH_GDI32_FUNC(func) \
func(ChoosePixelFormat, PFNCHOOSEPIXELFORMATPROC) \
func(DescribePixelFormat, PFNDESCRIBEPIXELFORMATPROC) \
func(SetPixelFormat, PFNSETPIXELFORMATPROC) \
func(SwapBuffers, PFNSWAPBUFFERSPROC) \
#endif

View File

@ -0,0 +1,49 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_WGLLOADER_HPP
#define NAZARA_OPENGLRENDERER_WGLLOADER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/DynLib.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Loader.hpp>
#include <string>
#undef WIN32_LEAN_AND_MEAN //< Redefined by OpenGL header (ty Khronos)
#include <Nazara/OpenGLRenderer/Wrapper/Win32/WGLFunctions.hpp>
namespace Nz::GL
{
class WGLLoader : public Loader
{
public:
WGLLoader(DynLib& openglLib);
~WGLLoader() = default;
std::unique_ptr<GLContext> CreateContext() override;
GLFunction LoadFunction(const char* name) override;
#define NAZARA_OPENGLRENDERER_FUNC(name, sig) sig name = nullptr;
#define NAZARA_OPENGLRENDERER_EXT_BEGIN(ext)
#define NAZARA_OPENGLRENDERER_EXT_END()
#define NAZARA_OPENGLRENDERER_EXT_FUNC(name, sig)
NAZARA_OPENGLRENDERER_FOREACH_GDI32_FUNC(NAZARA_OPENGLRENDERER_FUNC)
NAZARA_OPENGLRENDERER_FOREACH_WGL_FUNC(NAZARA_OPENGLRENDERER_FUNC, NAZARA_OPENGLRENDERER_EXT_BEGIN, NAZARA_OPENGLRENDERER_EXT_END, NAZARA_OPENGLRENDERER_EXT_FUNC)
#undef NAZARA_OPENGLRENDERER_EXT_BEGIN
#undef NAZARA_OPENGLRENDERER_EXT_END
#undef NAZARA_OPENGLRENDERER_EXT_FUNC
#undef NAZARA_OPENGLRENDERER_FUNC
private:
DynLib m_gdi32Lib;
DynLib& m_opengl32Lib;
};
}
#include <Nazara/OpenGLRenderer/Wrapper/Win32/WGLLoader.inl>
#endif

View File

@ -0,0 +1,12 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/Win32/WGLLoader.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz::Vk
{
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@ -0,0 +1,26 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_WIN32HELPER_HPP
#define NAZARA_OPENGLRENDERER_WIN32HELPER_HPP
#include <Nazara/Prerequisites.hpp>
#include <windows.h>
namespace Nz::GL
{
struct WindowDeleter
{
void operator()(HWND handle) const
{
DestroyWindow(handle);
}
};
using HWNDHandle = std::unique_ptr<std::remove_pointer_t<HWND>, WindowDeleter>;
}
#endif

View File

@ -0,0 +1,31 @@
// Copyright (C) 2014 AUTHORS
// This file is part of the "Nazara Engine - Module name"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/OpenGLRenderer/Config.hpp>
#if NAZARA_OPENGLRENDERER_MANAGE_MEMORY
#include <Nazara/Core/MemoryManager.hpp>
#include <new> // Nécessaire ?
void* operator new(std::size_t size)
{
return Nz::MemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size)
{
return Nz::MemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) noexcept
{
Nz::MemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) noexcept
{
Nz::MemoryManager::Free(pointer, true);
}
#endif // NAZARA_OPENGLRENDERER_MANAGE_MEMORY

View File

@ -0,0 +1,15 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderer.hpp>
extern "C"
{
NAZARA_EXPORT Nz::RendererImpl* NazaraRenderer_Instantiate()
{
std::unique_ptr<Nz::OpenGLRenderer> renderer = std::make_unique<Nz::OpenGLRenderer>();
return renderer.release();
}
}

View File

@ -0,0 +1,72 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGL.hpp>
#include <Nazara/Core/DynLib.hpp>
#include <Nazara/Core/Error.hpp>
#ifdef NAZARA_PLATFORM_WINDOWS
#include <Nazara/OpenGLRenderer/Wrapper/Win32/WGLLoader.hpp>
#endif
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
struct OpenGLImpl
{
DynLib opengl32Lib;
};
static std::unique_ptr<OpenGLImpl> s_impl;
bool OpenGL::Initialize()
{
if (s_impl)
return true;
auto impl = std::make_unique<OpenGLImpl>();
if (!impl->opengl32Lib.Load("opengl32" NAZARA_DYNLIB_EXTENSION))
{
NazaraError("Failed to load opengl32 library, is OpenGL installed on your system?");
return false;
}
std::unique_ptr<GL::Loader> loader;
#ifdef NAZARA_PLATFORM_WINDOWS
try
{
loader = std::make_unique<GL::WGLLoader>(impl->opengl32Lib);
}
catch (const std::exception& e)
{
NazaraWarning(std::string("Failed to load WGL: ") + e.what());
}
#endif
if (!loader)
{
NazaraError("Failed to initialize OpenGL loader");
return false;
}
s_impl = std::move(impl);
return true;
}
bool OpenGL::IsInitialized()
{
return s_impl != nullptr;
}
void OpenGL::Uninitialize()
{
if (!s_impl)
return;
s_impl.reset();
}
}

View File

@ -0,0 +1,151 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLBuffer.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CommandBuffer.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/QueueHandle.hpp>
#include <vma/vk_mem_alloc.h>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
OpenGLBuffer::~OpenGLBuffer()
{
vmaDestroyBuffer(m_device.GetMemoryAllocator(), m_buffer, m_allocation);
}
bool OpenGLBuffer::Fill(const void* data, UInt64 offset, UInt64 size)
{
void* ptr = Map(BufferAccess_WriteOnly, offset, size);
if (!ptr)
return false;
Nz::CallOnExit unmapOnExit([this]() { Unmap(); });
std::memcpy(ptr, data, size);
return true;
}
bool OpenGLBuffer::Initialize(UInt64 size, BufferUsageFlags usage)
{
m_size = size;
m_usage = usage;
VkBufferUsageFlags bufferUsage = ToOpenGL(m_type);
if ((usage & BufferUsage_DirectMapping) == 0)
bufferUsage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
VkBufferCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
createInfo.size = size;
createInfo.usage = bufferUsage;
VmaAllocationCreateInfo allocInfo = {};
if (usage & BufferUsage_DeviceLocal)
{
if (usage & BufferUsage_DirectMapping)
allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
else
allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
}
else
allocInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
if (usage & BufferUsage_PersistentMapping)
allocInfo.flags |= VMA_ALLOCATION_CREATE_MAPPED_BIT;
VkResult result = vmaCreateBuffer(m_device.GetMemoryAllocator(), &createInfo, &allocInfo, &m_buffer, &m_allocation, nullptr);
if (result != VK_SUCCESS)
{
NazaraError("Failed to allocate buffer: " + TranslateOpenGLError(result));
return false;
}
return true;
}
UInt64 OpenGLBuffer::GetSize() const
{
return m_size;
}
DataStorage OpenGLBuffer::GetStorage() const
{
return DataStorage_Hardware;
}
void* OpenGLBuffer::Map(BufferAccess /*access*/, UInt64 offset, UInt64 size)
{
if (m_usage & BufferUsage_DirectMapping)
{
void* mappedPtr;
VkResult result = vmaMapMemory(m_device.GetMemoryAllocator(), m_allocation, &mappedPtr);
if (result != VK_SUCCESS)
{
NazaraError("Failed to map buffer: " + TranslateOpenGLError(result));
return nullptr;
}
return static_cast<UInt8*>(mappedPtr) + offset;
}
else
{
VkBufferCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
createInfo.size = size;
createInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
VmaAllocationCreateInfo allocInfo = {};
allocInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT;
allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
VmaAllocationInfo allocationInfo;
VkResult result = vmaCreateBuffer(m_device.GetMemoryAllocator(), &createInfo, &allocInfo, &m_stagingBuffer, &m_stagingAllocation, &allocationInfo);
if (result != VK_SUCCESS)
{
NazaraError("Failed to allocate staging buffer: " + TranslateOpenGLError(result));
return nullptr;
}
return allocationInfo.pMappedData;
}
}
bool OpenGLBuffer::Unmap()
{
if (m_usage & BufferUsage_DirectMapping)
{
vmaUnmapMemory(m_device.GetMemoryAllocator(), m_allocation);
return true;
}
else
{
Vk::AutoCommandBuffer copyCommandBuffer = m_device.AllocateCommandBuffer(QueueType::Transfer);
if (!copyCommandBuffer->Begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT))
return false;
copyCommandBuffer->CopyBuffer(m_stagingBuffer, m_buffer, m_size);
if (!copyCommandBuffer->End())
return false;
Vk::QueueHandle transferQueue = m_device.GetQueue(m_device.GetDefaultFamilyIndex(QueueType::Transfer), 0);
if (!transferQueue.Submit(copyCommandBuffer))
return false;
transferQueue.WaitIdle();
vmaDestroyBuffer(m_device.GetMemoryAllocator(), m_stagingBuffer, m_stagingAllocation);
return true;
}
}
}
#endif

View File

@ -0,0 +1,14 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
}
#endif

View File

@ -0,0 +1,189 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.hpp>
#include <Nazara/Core/StackArray.hpp>
#include <Nazara/OpenGLRenderer/OpenGLBuffer.hpp>
#include <Nazara/OpenGLRenderer/OpenGLMultipleFramebuffer.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderPass.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderPipeline.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderPipelineLayout.hpp>
#include <Nazara/OpenGLRenderer/OpenGLSingleFramebuffer.hpp>
#include <Nazara/OpenGLRenderer/OpenGLShaderBinding.hpp>
#include <Nazara/OpenGLRenderer/OpenGLUploadPool.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
void OpenGLCommandBufferBuilder::BeginDebugRegion(const std::string_view& regionName, const Nz::Color& color)
{
// Ensure \0 at the end of string
StackArray<char> regionNameEOS = NazaraStackArrayNoInit(char, regionName.size() + 1);
std::memcpy(regionNameEOS.data(), regionName.data(), regionName.size());
regionNameEOS[regionName.size()] = '\0';
m_commandBuffer.BeginDebugRegion(regionNameEOS.data(), color);
}
void OpenGLCommandBufferBuilder::BeginRenderPass(const Framebuffer& framebuffer, const RenderPass& renderPass, Nz::Recti renderRect, std::initializer_list<ClearValues> clearValues)
{
const OpenGLRenderPass& vkRenderPass = static_cast<const OpenGLRenderPass&>(renderPass);
const Vk::Framebuffer& vkFramebuffer = [&] () -> const Vk::Framebuffer&
{
const OpenGLFramebuffer& vkFramebuffer = static_cast<const OpenGLFramebuffer&>(framebuffer);
switch (vkFramebuffer.GetType())
{
case OpenGLFramebuffer::Type::Multiple:
{
const OpenGLMultipleFramebuffer& vkMultipleFramebuffer = static_cast<const OpenGLMultipleFramebuffer&>(vkFramebuffer);
m_framebufferCount = std::max(m_framebufferCount, vkMultipleFramebuffer.GetFramebufferCount());
return vkMultipleFramebuffer.GetFramebuffer(m_imageIndex);
}
case OpenGLFramebuffer::Type::Single:
return static_cast<const OpenGLSingleFramebuffer&>(vkFramebuffer).GetFramebuffer();
}
throw std::runtime_error("Unhandled framebuffer type " + std::to_string(UnderlyingCast(vkFramebuffer.GetType())));
}();
VkRect2D renderArea;
renderArea.offset.x = renderRect.x;
renderArea.offset.y = renderRect.y;
renderArea.extent.width = renderRect.width;
renderArea.extent.height = renderRect.height;
StackArray<VkClearValue> vkClearValues = NazaraStackArray(VkClearValue, clearValues.size());
std::size_t index = 0;
for (const ClearValues& values : clearValues)
{
auto& vkValues = vkClearValues[index];
if (PixelFormatInfo::GetContent(vkRenderPass.GetAttachmentFormat(index)) == PixelFormatContent_ColorRGBA)
{
vkValues.color.float32[0] = values.color.r / 255.f;
vkValues.color.float32[1] = values.color.g / 255.f;
vkValues.color.float32[2] = values.color.b / 255.f;
vkValues.color.float32[3] = values.color.a / 255.f;
}
else
{
vkValues.depthStencil.depth = values.depth;
vkValues.depthStencil.stencil = values.stencil;
}
index++;
}
VkRenderPassBeginInfo beginInfo = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO };
beginInfo.renderPass = vkRenderPass.GetRenderPass();
beginInfo.framebuffer = vkFramebuffer;
beginInfo.renderArea.offset.x = renderRect.x;
beginInfo.renderArea.offset.y = renderRect.y;
beginInfo.renderArea.extent.width = renderRect.width;
beginInfo.renderArea.extent.height = renderRect.height;
beginInfo.clearValueCount = vkClearValues.size();
beginInfo.pClearValues = vkClearValues.data();
m_commandBuffer.BeginRenderPass(beginInfo);
m_currentRenderPass = &vkRenderPass;
}
void OpenGLCommandBufferBuilder::BindIndexBuffer(Nz::AbstractBuffer* indexBuffer, UInt64 offset)
{
OpenGLBuffer& vkBuffer = *static_cast<OpenGLBuffer*>(indexBuffer);
m_commandBuffer.BindIndexBuffer(vkBuffer.GetBuffer(), offset, VK_INDEX_TYPE_UINT16); //< Fuck me right?
}
void OpenGLCommandBufferBuilder::BindPipeline(const RenderPipeline& pipeline)
{
if (!m_currentRenderPass)
throw std::runtime_error("BindPipeline must be called in a RenderPass");
const OpenGLRenderPipeline& vkBinding = static_cast<const OpenGLRenderPipeline&>(pipeline);
m_commandBuffer.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, vkBinding.Get(m_currentRenderPass->GetRenderPass()));
}
void OpenGLCommandBufferBuilder::BindShaderBinding(const ShaderBinding& binding)
{
const OpenGLShaderBinding& vkBinding = static_cast<const OpenGLShaderBinding&>(binding);
const OpenGLRenderPipelineLayout& pipelineLayout = vkBinding.GetOwner();
m_commandBuffer.BindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.GetPipelineLayout(), 0U, vkBinding.GetDescriptorSet());
}
void OpenGLCommandBufferBuilder::BindVertexBuffer(UInt32 binding, Nz::AbstractBuffer* vertexBuffer, UInt64 offset)
{
OpenGLBuffer& vkBuffer = *static_cast<OpenGLBuffer*>(vertexBuffer);
m_commandBuffer.BindVertexBuffer(binding, vkBuffer.GetBuffer(), offset);
}
void OpenGLCommandBufferBuilder::CopyBuffer(const RenderBufferView& source, const RenderBufferView& target, UInt64 size, UInt64 sourceOffset, UInt64 targetOffset)
{
OpenGLBuffer& sourceBuffer = *static_cast<OpenGLBuffer*>(source.GetBuffer());
OpenGLBuffer& targetBuffer = *static_cast<OpenGLBuffer*>(target.GetBuffer());
m_commandBuffer.CopyBuffer(sourceBuffer.GetBuffer(), targetBuffer.GetBuffer(), size, sourceOffset + source.GetOffset(), targetOffset + target.GetOffset());
}
void OpenGLCommandBufferBuilder::CopyBuffer(const UploadPool::Allocation& allocation, const RenderBufferView& target, UInt64 size, UInt64 sourceOffset, UInt64 targetOffset)
{
const auto& vkAllocation = static_cast<const OpenGLUploadPool::OpenGLAllocation&>(allocation);
OpenGLBuffer& targetBuffer = *static_cast<OpenGLBuffer*>(target.GetBuffer());
m_commandBuffer.CopyBuffer(vkAllocation.buffer, targetBuffer.GetBuffer(), size, vkAllocation.offset + sourceOffset, target.GetOffset() + targetOffset);
}
void OpenGLCommandBufferBuilder::Draw(UInt32 vertexCount, UInt32 instanceCount, UInt32 firstVertex, UInt32 firstInstance)
{
m_commandBuffer.Draw(vertexCount, instanceCount, firstVertex, firstInstance);
}
void OpenGLCommandBufferBuilder::DrawIndexed(UInt32 indexCount, UInt32 instanceCount, UInt32 firstVertex, UInt32 firstInstance)
{
m_commandBuffer.DrawIndexed(indexCount, instanceCount, firstVertex, 0, firstInstance);
}
void OpenGLCommandBufferBuilder::EndDebugRegion()
{
m_commandBuffer.EndDebugRegion();
}
void OpenGLCommandBufferBuilder::EndRenderPass()
{
m_commandBuffer.EndRenderPass();
m_currentRenderPass = nullptr;
}
void OpenGLCommandBufferBuilder::PreTransferBarrier()
{
m_commandBuffer.MemoryBarrier(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0U, VK_ACCESS_TRANSFER_READ_BIT);
}
void OpenGLCommandBufferBuilder::PostTransferBarrier()
{
m_commandBuffer.MemoryBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_UNIFORM_READ_BIT);
}
void OpenGLCommandBufferBuilder::SetScissor(Nz::Recti scissorRegion)
{
m_commandBuffer.SetScissor(scissorRegion);
}
void OpenGLCommandBufferBuilder::SetViewport(Nz::Recti viewportRegion)
{
m_commandBuffer.SetViewport(Nz::Rectf(viewportRegion), 0.f, 1.f);
}
}
#endif

View File

@ -0,0 +1,42 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLCommandPool.hpp>
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
#include <Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CommandBuffer.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
std::unique_ptr<CommandBuffer> OpenGLCommandPool::BuildCommandBuffer(const std::function<void(CommandBufferBuilder& builder)>& callback)
{
std::vector<Vk::AutoCommandBuffer> commandBuffers;
auto BuildCommandBuffer = [&](std::size_t imageIndex)
{
Vk::AutoCommandBuffer& commandBuffer = commandBuffers.emplace_back(m_commandPool.AllocateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY));
if (!commandBuffer->Begin(VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT))
throw std::runtime_error("failed to begin command buffer: " + TranslateOpenGLError(commandBuffer->GetLastErrorCode()));
OpenGLCommandBufferBuilder builder(commandBuffer.Get(), imageIndex);
callback(builder);
if (!commandBuffer->End())
throw std::runtime_error("failed to build command buffer: " + TranslateOpenGLError(commandBuffer->GetLastErrorCode()));
return builder.GetMaxFramebufferCount();
};
std::size_t maxFramebufferCount = BuildCommandBuffer(0);
for (std::size_t i = 1; i < maxFramebufferCount; ++i)
BuildCommandBuffer(i);
return std::make_unique<OpenGLCommandBuffer>(std::move(commandBuffers));
}
}
#endif

View File

@ -0,0 +1,64 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLDevice.hpp>
#include <Nazara/OpenGLRenderer/OpenGLCommandPool.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderPipeline.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderPipelineLayout.hpp>
#include <Nazara/OpenGLRenderer/OpenGLShaderStage.hpp>
#include <Nazara/OpenGLRenderer/OpenGLTexture.hpp>
#include <Nazara/OpenGLRenderer/OpenGLTextureSampler.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
OpenGLDevice::~OpenGLDevice() = default;
std::unique_ptr<AbstractBuffer> OpenGLDevice::InstantiateBuffer(BufferType type)
{
return std::make_unique<OpenGLBuffer>(*this, type);
}
std::unique_ptr<CommandPool> OpenGLDevice::InstantiateCommandPool(QueueType queueType)
{
return std::make_unique<OpenGLCommandPool>(*this, queueType);
}
std::unique_ptr<RenderPipeline> OpenGLDevice::InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo)
{
return std::make_unique<OpenGLRenderPipeline>(*this, std::move(pipelineInfo));
}
std::shared_ptr<RenderPipelineLayout> OpenGLDevice::InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo)
{
auto pipelineLayout = std::make_shared<OpenGLRenderPipelineLayout>();
if (!pipelineLayout->Create(*this, std::move(pipelineLayoutInfo)))
return {};
return pipelineLayout;
}
std::shared_ptr<ShaderStageImpl> OpenGLDevice::InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
{
auto stage = std::make_shared<OpenGLShaderStage>();
if (!stage->Create(*this, type, lang, source, sourceSize))
return {};
return stage;
}
std::unique_ptr<Texture> OpenGLDevice::InstantiateTexture(const TextureInfo& params)
{
return std::make_unique<OpenGLTexture>(*this, params);
}
std::unique_ptr<TextureSampler> OpenGLDevice::InstantiateTextureSampler(const TextureSamplerInfo& params)
{
return std::make_unique<OpenGLTextureSampler>(*this, params);
}
}
#endif

View File

@ -0,0 +1,14 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLFramebuffer.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
}
#endif

View File

@ -0,0 +1,97 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLRenderImage.hpp>
#include <Nazara/OpenGLRenderer/VkRenderWindow.hpp>
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
#include <Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.hpp>
#include <stdexcept>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
OpenGLRenderImage::OpenGLRenderImage(VkRenderWindow& owner) :
m_owner(owner),
m_uploadPool(m_owner.GetDevice(), 2 * 1024 * 1024)
{
Vk::QueueHandle& graphicsQueue = m_owner.GetGraphicsQueue();
if (!m_commandPool.Create(m_owner.GetDevice(), graphicsQueue.GetQueueFamilyIndex(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT))
throw std::runtime_error("failed to create command pool: " + TranslateOpenGLError(m_commandPool.GetLastErrorCode()));
if (!m_imageAvailableSemaphore.Create(m_owner.GetDevice()))
throw std::runtime_error("failed to create image available semaphore: " + TranslateOpenGLError(m_imageAvailableSemaphore.GetLastErrorCode()));
if (!m_renderFinishedSemaphore.Create(m_owner.GetDevice()))
throw std::runtime_error("failed to create image finished semaphore: " + TranslateOpenGLError(m_imageAvailableSemaphore.GetLastErrorCode()));
if (!m_inFlightFence.Create(m_owner.GetDevice(), VK_FENCE_CREATE_SIGNALED_BIT))
throw std::runtime_error("failed to create in-flight fence: " + TranslateOpenGLError(m_inFlightFence.GetLastErrorCode()));
}
OpenGLRenderImage::~OpenGLRenderImage()
{
m_inFlightCommandBuffers.clear();
}
void OpenGLRenderImage::Execute(const std::function<void(CommandBufferBuilder& builder)>& callback, QueueTypeFlags queueTypeFlags)
{
Vk::CommandBuffer* commandBuffer;
if (m_currentCommandBuffer >= m_inFlightCommandBuffers.size())
{
Vk::AutoCommandBuffer& newlyAllocatedBuffer = m_inFlightCommandBuffers.emplace_back(m_commandPool.AllocateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY));
commandBuffer = &newlyAllocatedBuffer.Get();
m_currentCommandBuffer++;
}
else
commandBuffer = &m_inFlightCommandBuffers[m_currentCommandBuffer++].Get();
if (!commandBuffer->Begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT))
throw std::runtime_error("failed to begin command buffer: " + TranslateOpenGLError(commandBuffer->GetLastErrorCode()));
OpenGLCommandBufferBuilder builder(*commandBuffer, m_imageIndex);
callback(builder);
if (!commandBuffer->End())
throw std::runtime_error("failed to build command buffer: " + TranslateOpenGLError(commandBuffer->GetLastErrorCode()));
SubmitCommandBuffer(*commandBuffer, queueTypeFlags);
}
OpenGLUploadPool& OpenGLRenderImage::GetUploadPool()
{
return m_uploadPool;
}
void OpenGLRenderImage::SubmitCommandBuffer(CommandBuffer* commandBuffer, QueueTypeFlags queueTypeFlags)
{
OpenGLCommandBuffer& vkCommandBuffer = *static_cast<OpenGLCommandBuffer*>(commandBuffer);
return SubmitCommandBuffer(vkCommandBuffer.GetCommandBuffer(m_imageIndex), queueTypeFlags);
}
void OpenGLRenderImage::SubmitCommandBuffer(VkCommandBuffer commandBuffer, QueueTypeFlags queueTypeFlags)
{
if (queueTypeFlags & QueueType::Graphics)
m_graphicalCommandsBuffers.push_back(commandBuffer);
else
{
Vk::QueueHandle& graphicsQueue = m_owner.GetGraphicsQueue();
if (!graphicsQueue.Submit(commandBuffer))
throw std::runtime_error("Failed to submit command buffer: " + TranslateOpenGLError(graphicsQueue.GetLastErrorCode()));
}
}
void OpenGLRenderImage::Present()
{
Vk::QueueHandle& graphicsQueue = m_owner.GetGraphicsQueue();
if (!graphicsQueue.Submit(UInt32(m_graphicalCommandsBuffers.size()), m_graphicalCommandsBuffers.data(), m_imageAvailableSemaphore, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, m_renderFinishedSemaphore, m_inFlightFence))
throw std::runtime_error("Failed to submit command buffers: " + TranslateOpenGLError(graphicsQueue.GetLastErrorCode()));
m_owner.Present(m_imageIndex, m_renderFinishedSemaphore);
}
}
#endif

View File

@ -0,0 +1,14 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLRenderPass.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
}
#endif

View File

@ -0,0 +1,274 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLRenderPipeline.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/OpenGLRenderer/Utils.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderPipelineLayout.hpp>
#include <Nazara/OpenGLRenderer/OpenGLShaderStage.hpp>
#include <cassert>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
OpenGLRenderPipeline::OpenGLRenderPipeline(Vk::Device& device, RenderPipelineInfo pipelineInfo) :
m_device(&device),
m_pipelineInfo(std::move(pipelineInfo))
{
m_pipelineCreateInfo = BuildCreateInfo(m_pipelineInfo);
}
VkPipeline OpenGLRenderPipeline::Get(const Vk::RenderPass& renderPass) const
{
if (auto it = m_pipelines.find(renderPass); it != m_pipelines.end())
return it->second;
// Copy create info to make Get re-entrant
VkGraphicsPipelineCreateInfo pipelineCreateInfo = m_pipelineCreateInfo.pipelineInfo;
pipelineCreateInfo.renderPass = renderPass;
Vk::Pipeline newPipeline;
if (!newPipeline.CreateGraphics(*m_device, pipelineCreateInfo))
return VK_NULL_HANDLE;
auto it = m_pipelines.emplace(renderPass, std::move(newPipeline)).first;
return it->second;
}
std::vector<VkPipelineColorBlendAttachmentState> OpenGLRenderPipeline::BuildColorBlendAttachmentStateList(const RenderPipelineInfo& pipelineInfo)
{
std::vector<VkPipelineColorBlendAttachmentState> colorBlendStates;
VkPipelineColorBlendAttachmentState& colorBlendState = colorBlendStates.emplace_back();
colorBlendState.blendEnable = pipelineInfo.blending;
colorBlendState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; //< TODO
if (pipelineInfo.blending)
{
//TODO
/*switch (pipelineInfo.dstBlend)
{
blendState.dstAlphaBlendFactor
}*/
}
else
{
colorBlendState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
colorBlendState.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
colorBlendState.colorBlendOp = VK_BLEND_OP_ADD;
colorBlendState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
colorBlendState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
colorBlendState.alphaBlendOp = VK_BLEND_OP_ADD;
}
return colorBlendStates;
}
VkPipelineColorBlendStateCreateInfo OpenGLRenderPipeline::BuildColorBlendInfo(const RenderPipelineInfo& pipelineInfo, const std::vector<VkPipelineColorBlendAttachmentState>& attachmentState)
{
VkPipelineColorBlendStateCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
createInfo.attachmentCount = std::uint32_t(attachmentState.size());
createInfo.pAttachments = attachmentState.data();
return createInfo;
}
VkPipelineDepthStencilStateCreateInfo OpenGLRenderPipeline::BuildDepthStencilInfo(const RenderPipelineInfo& pipelineInfo)
{
VkPipelineDepthStencilStateCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
createInfo.depthTestEnable = pipelineInfo.depthBuffer;
createInfo.depthWriteEnable = pipelineInfo.depthWrite;
createInfo.depthCompareOp = ToOpenGL(pipelineInfo.depthCompare);
createInfo.stencilTestEnable = pipelineInfo.stencilTest;
createInfo.front = BuildStencilOp(pipelineInfo, true);
createInfo.back = BuildStencilOp(pipelineInfo, false);
return createInfo;
}
VkPipelineDynamicStateCreateInfo OpenGLRenderPipeline::BuildDynamicStateInfo(const RenderPipelineInfo& pipelineInfo, const std::vector<VkDynamicState>& dynamicStates)
{
VkPipelineDynamicStateCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
createInfo.dynamicStateCount = std::uint32_t(dynamicStates.size());
createInfo.pDynamicStates = dynamicStates.data();
return createInfo;
}
std::vector<VkDynamicState> OpenGLRenderPipeline::BuildDynamicStateList(const RenderPipelineInfo& pipelineInfo)
{
return { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
}
VkPipelineInputAssemblyStateCreateInfo OpenGLRenderPipeline::BuildInputAssemblyInfo(const RenderPipelineInfo& pipelineInfo)
{
VkPipelineInputAssemblyStateCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
createInfo.topology = ToOpenGL(pipelineInfo.primitiveMode);
return createInfo;
}
VkPipelineMultisampleStateCreateInfo OpenGLRenderPipeline::BuildMultisampleInfo(const RenderPipelineInfo& pipelineInfo)
{
VkPipelineMultisampleStateCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
createInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
createInfo.minSampleShading = 1.0f; //< TODO: Remove
return createInfo;
}
VkPipelineRasterizationStateCreateInfo OpenGLRenderPipeline::BuildRasterizationInfo(const RenderPipelineInfo& pipelineInfo)
{
VkPipelineRasterizationStateCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
createInfo.polygonMode = ToOpenGL(pipelineInfo.faceFilling);
createInfo.cullMode = ToOpenGL(pipelineInfo.cullingSide);
createInfo.frontFace = VK_FRONT_FACE_CLOCKWISE; //< TODO
createInfo.lineWidth = pipelineInfo.lineWidth;
return createInfo;
}
VkPipelineViewportStateCreateInfo OpenGLRenderPipeline::BuildViewportInfo(const RenderPipelineInfo& pipelineInfo)
{
VkPipelineViewportStateCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
createInfo.scissorCount = createInfo.viewportCount = 1; //< TODO
return createInfo;
}
VkStencilOpState OpenGLRenderPipeline::BuildStencilOp(const RenderPipelineInfo& pipelineInfo, bool front)
{
const auto& pipelineStencil = (front) ? pipelineInfo.stencilFront : pipelineInfo.stencilBack;
VkStencilOpState stencilStates;
stencilStates.compareMask = pipelineStencil.compareMask;
stencilStates.compareOp = ToOpenGL(pipelineStencil.compare);
stencilStates.depthFailOp = ToOpenGL(pipelineStencil.depthFail);
stencilStates.failOp = ToOpenGL(pipelineStencil.fail);
stencilStates.passOp = ToOpenGL(pipelineStencil.pass);
stencilStates.reference = pipelineStencil.reference;
stencilStates.writeMask = pipelineStencil.writeMask;
return stencilStates;
}
std::vector<VkPipelineShaderStageCreateInfo> OpenGLRenderPipeline::BuildShaderStageInfo(const RenderPipelineInfo& pipelineInfo)
{
std::vector<VkPipelineShaderStageCreateInfo> shaderStageCreateInfos;
for (auto&& stagePtr : pipelineInfo.shaderStages)
{
Nz::OpenGLShaderStage& vulkanStage = *static_cast<Nz::OpenGLShaderStage*>(stagePtr.get());
VkPipelineShaderStageCreateInfo& createInfo = shaderStageCreateInfos.emplace_back();
createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
createInfo.module = vulkanStage.GetHandle();
createInfo.pName = "main";
createInfo.stage = ToOpenGL(vulkanStage.GetStageType());
}
return shaderStageCreateInfos;
}
std::vector<VkVertexInputAttributeDescription> OpenGLRenderPipeline::BuildVertexAttributeDescription(const RenderPipelineInfo& pipelineInfo)
{
std::vector<VkVertexInputAttributeDescription> vertexAttributes;
std::uint32_t locationIndex = 0;
for (const auto& bufferData : pipelineInfo.vertexBuffers)
{
std::uint32_t binding = std::uint32_t(bufferData.binding);
for (const auto& componentInfo : *bufferData.declaration)
{
auto& bufferAttribute = vertexAttributes.emplace_back();
bufferAttribute.binding = binding;
bufferAttribute.location = locationIndex++;
bufferAttribute.offset = std::uint32_t(componentInfo.offset);
bufferAttribute.format = ToOpenGL(componentInfo.type);
}
}
return vertexAttributes;
}
std::vector<VkVertexInputBindingDescription> OpenGLRenderPipeline::BuildVertexBindingDescription(const RenderPipelineInfo& pipelineInfo)
{
std::vector<VkVertexInputBindingDescription> vertexBindings;
for (const auto& bufferData : pipelineInfo.vertexBuffers)
{
auto& bufferBinding = vertexBindings.emplace_back();
bufferBinding.binding = std::uint32_t(bufferData.binding);
bufferBinding.stride = std::uint32_t(bufferData.declaration->GetStride());
bufferBinding.inputRate = ToOpenGL(bufferData.declaration->GetInputRate());
}
return vertexBindings;
}
VkPipelineVertexInputStateCreateInfo OpenGLRenderPipeline::BuildVertexInputInfo(const RenderPipelineInfo& pipelineInfo, const std::vector<VkVertexInputAttributeDescription>& vertexAttributes, const std::vector<VkVertexInputBindingDescription>& bindingDescriptions)
{
VkPipelineVertexInputStateCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
createInfo.vertexAttributeDescriptionCount = std::uint32_t(vertexAttributes.size());
createInfo.pVertexAttributeDescriptions = vertexAttributes.data();
createInfo.vertexBindingDescriptionCount = std::uint32_t(bindingDescriptions.size());
createInfo.pVertexBindingDescriptions = bindingDescriptions.data();
return createInfo;
}
auto OpenGLRenderPipeline::BuildCreateInfo(const RenderPipelineInfo& pipelineInfo) -> CreateInfo
{
CreateInfo createInfo = {};
createInfo.stateData = std::make_unique<CreateInfo::StateData>();
createInfo.colorBlendAttachmentState = BuildColorBlendAttachmentStateList(pipelineInfo);
createInfo.dynamicStates = BuildDynamicStateList(pipelineInfo);
createInfo.shaderStages = BuildShaderStageInfo(pipelineInfo);
createInfo.vertexAttributesDescription = BuildVertexAttributeDescription(pipelineInfo);
createInfo.vertexBindingDescription = BuildVertexBindingDescription(pipelineInfo);
createInfo.stateData->colorBlendState = BuildColorBlendInfo(pipelineInfo, createInfo.colorBlendAttachmentState);
createInfo.stateData->depthStencilState = BuildDepthStencilInfo(pipelineInfo);
createInfo.stateData->dynamicState = BuildDynamicStateInfo(pipelineInfo, createInfo.dynamicStates);
createInfo.stateData->inputAssemblyState = BuildInputAssemblyInfo(pipelineInfo);
createInfo.stateData->multiSampleState = BuildMultisampleInfo(pipelineInfo);
createInfo.stateData->rasterizationState = BuildRasterizationInfo(pipelineInfo);
createInfo.stateData->viewportState = BuildViewportInfo(pipelineInfo);
createInfo.stateData->vertexInputState = BuildVertexInputInfo(pipelineInfo, createInfo.vertexAttributesDescription, createInfo.vertexBindingDescription);
createInfo.pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
createInfo.pipelineInfo.stageCount = std::uint32_t(createInfo.shaderStages.size());
createInfo.pipelineInfo.pStages = createInfo.shaderStages.data();
createInfo.pipelineInfo.pColorBlendState = &createInfo.stateData->colorBlendState;
createInfo.pipelineInfo.pDepthStencilState = &createInfo.stateData->depthStencilState;
createInfo.pipelineInfo.pDynamicState = &createInfo.stateData->dynamicState;
createInfo.pipelineInfo.pInputAssemblyState = &createInfo.stateData->inputAssemblyState;
createInfo.pipelineInfo.pMultisampleState = &createInfo.stateData->multiSampleState;
createInfo.pipelineInfo.pRasterizationState = &createInfo.stateData->rasterizationState;
createInfo.pipelineInfo.pVertexInputState = &createInfo.stateData->vertexInputState;
createInfo.pipelineInfo.pViewportState = &createInfo.stateData->viewportState;
OpenGLRenderPipelineLayout& pipelineLayout = *static_cast<OpenGLRenderPipelineLayout*>(pipelineInfo.pipelineLayout.get());
createInfo.pipelineInfo.layout = pipelineLayout.GetPipelineLayout();
return createInfo;
}
}
#endif

View File

@ -0,0 +1,140 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLRenderPipelineLayout.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/MemoryHelper.hpp>
#include <Nazara/Core/StackVector.hpp>
#include <Nazara/OpenGLRenderer/Utils.hpp>
#include <cassert>
#include <stdexcept>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
OpenGLRenderPipelineLayout::~OpenGLRenderPipelineLayout()
{
for (auto& pool : m_descriptorPools)
{
if (!pool.freeBindings.TestAll())
NazaraWarning("Not all ShaderBinding have been released!");
}
}
ShaderBindingPtr OpenGLRenderPipelineLayout::AllocateShaderBinding()
{
for (std::size_t i = 0; i < m_descriptorPools.size(); ++i)
{
ShaderBindingPtr bindingPtr = AllocateFromPool(i);
if (!bindingPtr)
continue;
return bindingPtr;
}
// No allocation could be made, time to allocate a new pool
std::size_t newPoolIndex = m_descriptorPools.size();
AllocatePool();
ShaderBindingPtr bindingPtr = AllocateFromPool(newPoolIndex);
if (!bindingPtr)
throw std::runtime_error("Failed to allocate shader binding");
return bindingPtr;
}
bool OpenGLRenderPipelineLayout::Create(Vk::Device& device, RenderPipelineLayoutInfo layoutInfo)
{
m_device = &device;
m_layoutInfo = std::move(layoutInfo);
StackVector<VkDescriptorSetLayoutBinding> layoutBindings = NazaraStackVector(VkDescriptorSetLayoutBinding, m_layoutInfo.bindings.size());
for (const auto& bindingInfo : m_layoutInfo.bindings)
{
VkDescriptorSetLayoutBinding& layoutBinding = layoutBindings.emplace_back();
layoutBinding.binding = bindingInfo.index;
layoutBinding.descriptorCount = 1U;
layoutBinding.descriptorType = ToOpenGL(bindingInfo.type);
layoutBinding.stageFlags = ToOpenGL(bindingInfo.shaderStageFlags);
}
if (!m_descriptorSetLayout.Create(*m_device, UInt32(layoutBindings.size()), layoutBindings.data()))
return false;
if (!m_pipelineLayout.Create(*m_device, m_descriptorSetLayout))
return false;
return true;
}
auto OpenGLRenderPipelineLayout::AllocatePool() -> DescriptorPool&
{
StackVector<VkDescriptorPoolSize> poolSizes = NazaraStackVector(VkDescriptorPoolSize, m_layoutInfo.bindings.size());
constexpr UInt32 MaxSet = 128;
for (const auto& bindingInfo : m_layoutInfo.bindings)
{
VkDescriptorPoolSize& poolSize = poolSizes.emplace_back();
poolSize.descriptorCount = MaxSet;
poolSize.type = ToOpenGL(bindingInfo.type);
}
DescriptorPool pool;
if (!pool.descriptorPool.Create(*m_device, MaxSet, UInt32(poolSizes.size()), poolSizes.data(), VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT))
throw std::runtime_error("Failed to allocate new descriptor pool: " + TranslateOpenGLError(pool.descriptorPool.GetLastErrorCode()));
pool.freeBindings.Resize(MaxSet, true);
pool.storage = std::make_unique<DescriptorPool::BindingStorage[]>(MaxSet);
return m_descriptorPools.emplace_back(std::move(pool));
}
ShaderBindingPtr OpenGLRenderPipelineLayout::AllocateFromPool(std::size_t poolIndex)
{
auto& pool = m_descriptorPools[poolIndex];
std::size_t freeBindingId = pool.freeBindings.FindFirst();
if (freeBindingId == pool.freeBindings.npos)
return {}; //< No free binding in this pool
Vk::DescriptorSet descriptorSet = pool.descriptorPool.AllocateDescriptorSet(m_descriptorSetLayout);
if (!descriptorSet)
{
NazaraWarning("Failed to allocate descriptor set: " + TranslateOpenGLError(pool.descriptorPool.GetLastErrorCode()));
return {};
}
pool.freeBindings.Reset(freeBindingId);
OpenGLShaderBinding* freeBindingMemory = reinterpret_cast<OpenGLShaderBinding*>(&pool.storage[freeBindingId]);
return ShaderBindingPtr(PlacementNew(freeBindingMemory, *this, poolIndex, freeBindingId, std::move(descriptorSet)));
}
void OpenGLRenderPipelineLayout::Release(ShaderBinding& binding)
{
OpenGLShaderBinding& vulkanBinding = static_cast<OpenGLShaderBinding&>(binding);
std::size_t poolIndex = vulkanBinding.GetPoolIndex();
std::size_t bindingIndex = vulkanBinding.GetBindingIndex();
assert(poolIndex < m_descriptorPools.size());
auto& pool = m_descriptorPools[poolIndex];
assert(!pool.freeBindings.Test(bindingIndex));
OpenGLShaderBinding* bindingMemory = reinterpret_cast<OpenGLShaderBinding*>(&pool.storage[bindingIndex]);
PlacementDestroy(bindingMemory);
pool.freeBindings.Set(bindingIndex);
// Try to free pool if it's one of the last one
if (poolIndex >= m_descriptorPools.size() - 1 && poolIndex <= m_descriptorPools.size())
TryToShrink();
}
}
#endif

View File

@ -0,0 +1,486 @@
// 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
#if 0
#include <Nazara/OpenGLRenderer/VkRenderWindow.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/StackArray.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
#include <Nazara/OpenGLRenderer/OpenGL.hpp>
#include <Nazara/OpenGLRenderer/OpenGLCommandPool.hpp>
#include <Nazara/OpenGLRenderer/OpenGLDevice.hpp>
#include <Nazara/OpenGLRenderer/OpenGLSurface.hpp>
#include <array>
#include <stdexcept>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
VkRenderWindow::VkRenderWindow() :
m_currentFrame(0),
m_depthStencilFormat(VK_FORMAT_MAX_ENUM)
{
}
VkRenderWindow::~VkRenderWindow()
{
if (m_device)
m_device->WaitForIdle();
m_concurrentImageData.clear();
m_renderPass.reset();
m_framebuffer.reset();
m_swapchain.Destroy();
}
OpenGLRenderImage& VkRenderWindow::Acquire()
{
OpenGLRenderImage& currentFrame = m_concurrentImageData[m_currentFrame];
Vk::Fence& inFlightFence = currentFrame.GetInFlightFence();
// Wait until previous rendering to this image has been done
inFlightFence.Wait();
UInt32 imageIndex;
if (!m_swapchain.AcquireNextImage(std::numeric_limits<UInt64>::max(), currentFrame.GetImageAvailableSemaphore(), VK_NULL_HANDLE, &imageIndex))
throw std::runtime_error("Failed to acquire next image: " + TranslateOpenGLError(m_swapchain.GetLastErrorCode()));
if (m_inflightFences[imageIndex])
m_inflightFences[imageIndex]->Wait();
m_inflightFences[imageIndex] = &inFlightFence;
m_inflightFences[imageIndex]->Reset();
currentFrame.Reset(imageIndex);
return currentFrame;
}
bool VkRenderWindow::Create(RendererImpl* /*renderer*/, RenderSurface* surface, const Vector2ui& size, const RenderWindowParameters& parameters)
{
const auto& deviceInfo = OpenGL::GetPhysicalDevices()[0];
Vk::Surface& vulkanSurface = static_cast<OpenGLSurface*>(surface)->GetSurface();
UInt32 graphicsFamilyQueueIndex;
UInt32 presentableFamilyQueueIndex;
UInt32 transferFamilyQueueIndex;
m_device = OpenGL::SelectDevice(deviceInfo, vulkanSurface, &graphicsFamilyQueueIndex, &presentableFamilyQueueIndex, &transferFamilyQueueIndex);
if (!m_device)
{
NazaraError("Failed to get compatible OpenGL device");
return false;
}
m_graphicsQueue = m_device->GetQueue(graphicsFamilyQueueIndex, 0);
m_presentQueue = m_device->GetQueue(presentableFamilyQueueIndex, 0);
m_transferQueue = m_device->GetQueue(transferFamilyQueueIndex, 0);
std::vector<VkSurfaceFormatKHR> surfaceFormats;
if (!vulkanSurface.GetFormats(deviceInfo.physDevice, &surfaceFormats))
{
NazaraError("Failed to query supported surface formats");
return false;
}
m_surfaceFormat = [&] () -> VkSurfaceFormatKHR
{
if (surfaceFormats.size() == 1 && surfaceFormats.front().format == VK_FORMAT_UNDEFINED)
{
// If the list contains one undefined format, it means any format can be used
return { VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR };
}
else
{
// Search for RGBA8 and default to first format
for (const VkSurfaceFormatKHR& surfaceFormat : surfaceFormats)
{
if (surfaceFormat.format == VK_FORMAT_R8G8B8A8_UNORM)
return surfaceFormat;
}
return surfaceFormats.front();
}
}();
if (!parameters.depthFormats.empty())
{
for (PixelFormat format : parameters.depthFormats)
{
switch (format)
{
case PixelFormat_Depth16:
m_depthStencilFormat = VK_FORMAT_D16_UNORM;
break;
case PixelFormat_Depth24:
case PixelFormat_Depth24Stencil8:
m_depthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT;
break;
case PixelFormat_Depth32:
m_depthStencilFormat = VK_FORMAT_D32_SFLOAT;
break;
case PixelFormat_Stencil1:
case PixelFormat_Stencil4:
case PixelFormat_Stencil8:
m_depthStencilFormat = VK_FORMAT_S8_UINT;
break;
case PixelFormat_Stencil16:
m_depthStencilFormat = VK_FORMAT_MAX_ENUM;
break;
default:
{
PixelFormatContent formatContent = PixelFormatInfo::GetContent(format);
if (formatContent != PixelFormatContent_DepthStencil && formatContent != PixelFormatContent_Stencil)
NazaraWarning("Invalid format " + PixelFormatInfo::GetName(format) + " for depth-stencil attachment");
m_depthStencilFormat = VK_FORMAT_MAX_ENUM;
break;
}
}
if (m_depthStencilFormat != VK_FORMAT_MAX_ENUM)
{
VkFormatProperties formatProperties = m_device->GetInstance().GetPhysicalDeviceFormatProperties(deviceInfo.physDevice, m_depthStencilFormat);
if (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
break; //< Found it
m_depthStencilFormat = VK_FORMAT_MAX_ENUM;
}
}
}
if (!SetupSwapchain(deviceInfo, vulkanSurface, size))
{
NazaraError("Failed to create swapchain");
return false;
}
if (m_depthStencilFormat != VK_FORMAT_MAX_ENUM && !SetupDepthBuffer(size))
{
NazaraError("Failed to create depth buffer");
return false;
}
if (!SetupRenderPass())
{
NazaraError("Failed to create render pass");
return false;
}
UInt32 imageCount = m_swapchain.GetBufferCount();
// Framebuffers
m_inflightFences.resize(imageCount);
Nz::StackArray<Vk::Framebuffer> framebuffers = NazaraStackArray(Vk::Framebuffer, imageCount);
for (UInt32 i = 0; i < imageCount; ++i)
{
std::array<VkImageView, 2> attachments = { m_swapchain.GetBuffer(i).view, m_depthBufferView };
VkFramebufferCreateInfo frameBufferCreate = {
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
nullptr,
0,
m_renderPass->GetRenderPass(),
(attachments[1] != VK_NULL_HANDLE) ? 2U : 1U,
attachments.data(),
size.x,
size.y,
1U
};
if (!framebuffers[i].Create(*m_device, frameBufferCreate))
{
NazaraError("Failed to create framebuffer for image #" + String::Number(i) + ": " + TranslateOpenGLError(framebuffers[i].GetLastErrorCode()));
return false;
}
}
m_framebuffer.emplace(framebuffers.data(), framebuffers.size());
const std::size_t MaxConcurrentImage = imageCount;
m_concurrentImageData.reserve(MaxConcurrentImage);
for (std::size_t i = 0; i < MaxConcurrentImage; ++i)
m_concurrentImageData.emplace_back(*this);
m_clock.Restart();
return true;
}
std::unique_ptr<CommandPool> VkRenderWindow::CreateCommandPool(QueueType queueType)
{
UInt32 queueFamilyIndex;
switch (queueType)
{
case QueueType::Compute:
queueFamilyIndex = m_device->GetDefaultFamilyIndex(QueueType::Compute);
break;
case QueueType::Graphics:
queueFamilyIndex = m_graphicsQueue.GetQueueFamilyIndex();
break;
case QueueType::Transfer:
queueFamilyIndex = m_transferQueue.GetQueueFamilyIndex();
break;
}
return std::make_unique<OpenGLCommandPool>(*m_device, queueFamilyIndex);
}
const OpenGLRenderPass& VkRenderWindow::GetRenderPass() const
{
return *m_renderPass;
}
bool VkRenderWindow::SetupDepthBuffer(const Vector2ui& size)
{
VkImageCreateInfo imageCreateInfo = {
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
nullptr, // const void* pNext;
0U, // VkImageCreateFlags flags;
VK_IMAGE_TYPE_2D, // VkImageType imageType;
m_depthStencilFormat, // VkFormat format;
{size.x, size.y, 1U}, // VkExtent3D extent;
1U, // uint32_t mipLevels;
1U, // uint32_t arrayLayers;
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
0U, // uint32_t queueFamilyIndexCount;
nullptr, // const uint32_t* pQueueFamilyIndices;
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
};
if (!m_depthBuffer.Create(*m_device, imageCreateInfo))
{
NazaraError("Failed to create depth buffer");
return false;
}
VkMemoryRequirements memoryReq = m_depthBuffer.GetMemoryRequirements();
if (!m_depthBufferMemory.Create(*m_device, memoryReq.size, memoryReq.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
{
NazaraError("Failed to allocate depth buffer memory");
return false;
}
if (!m_depthBuffer.BindImageMemory(m_depthBufferMemory))
{
NazaraError("Failed to bind depth buffer to buffer");
return false;
}
VkImageViewCreateInfo imageViewCreateInfo = {
VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
nullptr, // const void* pNext;
0, // VkImageViewCreateFlags flags;
m_depthBuffer, // VkImage image;
VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
m_depthStencilFormat, // VkFormat format;
{ // VkComponentMapping components;
VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle .r;
VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle .g;
VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle .b;
VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle .a;
},
{ // VkImageSubresourceRange subresourceRange;
VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags .aspectMask;
0, // uint32_t .baseMipLevel;
1, // uint32_t .levelCount;
0, // uint32_t .baseArrayLayer;
1 // uint32_t .layerCount;
}
};
if (!m_depthBufferView.Create(*m_device, imageViewCreateInfo))
{
NazaraError("Failed to create depth buffer view");
return false;
}
return true;
}
bool VkRenderWindow::SetupRenderPass()
{
std::array<VkAttachmentDescription, 2> attachments = {
{
{
0, // VkAttachmentDescriptionFlags flags;
m_surfaceFormat.format, // VkFormat format;
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR // VkImageLayout finalLayout;
},
{
0, // VkAttachmentDescriptionFlags flags;
m_depthStencilFormat, // VkFormat format;
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
},
}
};
VkAttachmentReference colorReference = {
0, // uint32_t attachment;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
};
VkAttachmentReference depthReference = {
1, // uint32_t attachment;
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout;
};
VkSubpassDescription subpass = {
0, // VkSubpassDescriptionFlags flags;
VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
0U, // uint32_t inputAttachmentCount;
nullptr, // const VkAttachmentReference* pInputAttachments;
1U, // uint32_t colorAttachmentCount;
&colorReference, // const VkAttachmentReference* pColorAttachments;
nullptr, // const VkAttachmentReference* pResolveAttachments;
(m_depthStencilFormat != VK_FORMAT_MAX_ENUM) ? &depthReference : nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
0U, // uint32_t preserveAttachmentCount;
nullptr // const uint32_t* pPreserveAttachments;
};
std::array<VkSubpassDependency, 2> dependencies;
// First dependency at the start of the render pass
// Does the transition from final to initial layout
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL; // Producer of the dependency
dependencies[0].dstSubpass = 0; // Consumer is our single subpass that will wait for the execution dependency
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[0].srcAccessMask = 0;
dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
// Second dependency at the end the render pass
// Does the transition from the initial to the final layout
dependencies[1].srcSubpass = 0; // Producer of the dependency is our single subpass
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL; // Consumer are all commands outside of the render pass
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
VkRenderPassCreateInfo createInfo = {
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
nullptr, // const void* pNext;
0, // VkRenderPassCreateFlags flags;
(m_depthStencilFormat != VK_FORMAT_MAX_ENUM) ? 2U : 1U, // uint32_t attachmentCount;
attachments.data(), // const VkAttachmentDescription* pAttachments;
1U, // uint32_t subpassCount;
&subpass, // const VkSubpassDescription* pSubpasses;
UInt32(dependencies.size()), // uint32_t dependencyCount;
dependencies.data() // const VkSubpassDependency* pDependencies;
};
Vk::RenderPass renderPass;
if (!renderPass.Create(*m_device, createInfo))
{
NazaraError("Failed to create render pass: " + TranslateOpenGLError(renderPass.GetLastErrorCode()));
return false;
}
std::initializer_list<PixelFormat> fixmeplease = { PixelFormat::PixelFormat_RGB8, PixelFormat::PixelFormat_Depth24Stencil8 };
m_renderPass.emplace(std::move(renderPass), fixmeplease);
return true;
}
bool VkRenderWindow::SetupSwapchain(const Vk::PhysicalDevice& deviceInfo, Vk::Surface& surface, const Vector2ui& size)
{
VkSurfaceCapabilitiesKHR surfaceCapabilities;
if (!surface.GetCapabilities(deviceInfo.physDevice, &surfaceCapabilities))
{
NazaraError("Failed to query surface capabilities");
return false;
}
Nz::UInt32 imageCount = surfaceCapabilities.minImageCount + 1;
if (surfaceCapabilities.maxImageCount > 0 && imageCount > surfaceCapabilities.maxImageCount)
imageCount = surfaceCapabilities.maxImageCount;
VkExtent2D extent;
if (surfaceCapabilities.currentExtent.width == -1)
{
extent.width = Nz::Clamp<Nz::UInt32>(size.x, surfaceCapabilities.minImageExtent.width, surfaceCapabilities.maxImageExtent.width);
extent.height = Nz::Clamp<Nz::UInt32>(size.y, surfaceCapabilities.minImageExtent.height, surfaceCapabilities.maxImageExtent.height);
}
else
extent = surfaceCapabilities.currentExtent;
std::vector<VkPresentModeKHR> presentModes;
if (!surface.GetPresentModes(deviceInfo.physDevice, &presentModes))
{
NazaraError("Failed to query supported present modes");
return false;
}
VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
for (VkPresentModeKHR presentMode : presentModes)
{
if (presentMode == VK_PRESENT_MODE_MAILBOX_KHR)
{
swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
break;
}
if (presentMode == VK_PRESENT_MODE_IMMEDIATE_KHR)
swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
}
VkSwapchainCreateInfoKHR swapchainInfo = {
VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
nullptr,
0,
surface,
imageCount,
m_surfaceFormat.format,
m_surfaceFormat.colorSpace,
extent,
1,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_SHARING_MODE_EXCLUSIVE,
0, nullptr,
surfaceCapabilities.currentTransform,
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
swapchainPresentMode,
VK_TRUE,
VK_NULL_HANDLE
};
if (!m_swapchain.Create(*m_device, swapchainInfo))
{
NazaraError("Failed to create swapchain");
return false;
}
return true;
}
}
#endif

View File

@ -0,0 +1,79 @@
// Copyright (C) 2020 Jérôme Leclercq
// 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/OpenGLRenderer.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Renderer/RenderDevice.hpp>
#include <Nazara/Renderer/RenderSurface.hpp>
#include <Nazara/Renderer/RenderWindowImpl.hpp>
#include <Nazara/OpenGLRenderer/OpenGL.hpp>
#include <cassert>
#include <sstream>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
OpenGLRenderer::~OpenGLRenderer()
{
OpenGL::Uninitialize();
}
std::unique_ptr<RenderSurface> OpenGLRenderer::CreateRenderSurfaceImpl()
{
return {};
}
std::unique_ptr<RenderWindowImpl> OpenGLRenderer::CreateRenderWindowImpl()
{
return {};
}
std::shared_ptr<RenderDevice> OpenGLRenderer::InstanciateRenderDevice(std::size_t deviceIndex)
{
//assert(deviceIndex < m_physDevices.size());
//return OpenGL::SelectDevice(m_physDevices[deviceIndex]);
return {};
}
bool OpenGLRenderer::IsBetterThan(const RendererImpl* other) const
{
if (other->QueryAPI() == RenderAPI::OpenGL && QueryAPIVersion() > other->QueryAPIVersion())
return true;
return false; //< OpenGL is mostly a fallback to other renderers
}
bool OpenGLRenderer::Prepare(const ParameterList& parameters)
{
return OpenGL::Initialize();
}
RenderAPI OpenGLRenderer::QueryAPI() const
{
return RenderAPI::OpenGL;
}
std::string OpenGLRenderer::QueryAPIString() const
{
std::ostringstream ss;
ss << "OpenGL ES renderer 3.0";
return ss.str();
}
UInt32 OpenGLRenderer::QueryAPIVersion() const
{
return 300;
}
std::vector<RenderDeviceInfo> OpenGLRenderer::QueryRenderDevices() const
{
std::vector<RenderDeviceInfo> devices;
auto& dummyDevice = devices.emplace_back();
dummyDevice.name = "OpenGL Default Device";
dummyDevice.type = RenderDeviceType::Unknown;
return devices;
}
}

View File

@ -0,0 +1,79 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLShaderBinding.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/StackVector.hpp>
#include <Nazara/OpenGLRenderer/OpenGLBuffer.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderPipelineLayout.hpp>
#include <Nazara/OpenGLRenderer/OpenGLTexture.hpp>
#include <Nazara/OpenGLRenderer/OpenGLTextureSampler.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
void OpenGLShaderBinding::Update(std::initializer_list<Binding> bindings)
{
StackVector<VkDescriptorBufferInfo> bufferBinding = NazaraStackVector(VkDescriptorBufferInfo, bindings.size());
StackVector<VkDescriptorImageInfo> imageBinding = NazaraStackVector(VkDescriptorImageInfo, bindings.size());
StackVector<VkWriteDescriptorSet> writeOps = NazaraStackVector(VkWriteDescriptorSet, bindings.size());
for (const Binding& binding : bindings)
{
VkWriteDescriptorSet& writeOp = writeOps.emplace_back();
writeOp.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeOp.dstSet = m_descriptorSet;
writeOp.dstBinding = UInt32(binding.bindingIndex);
std::visit([&](auto&& arg)
{
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, TextureBinding>)
{
OpenGLTexture& vkTexture = *static_cast<OpenGLTexture*>(arg.texture);
OpenGLTextureSampler& vkSampler = *static_cast<OpenGLTextureSampler*>(arg.sampler);
VkDescriptorImageInfo& imageInfo = imageBinding.emplace_back();
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
imageInfo.imageView = vkTexture.GetImageView();
imageInfo.sampler = vkSampler.GetSampler();
writeOp.descriptorCount = 1;
writeOp.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
writeOp.pImageInfo = &imageInfo;
}
else if constexpr (std::is_same_v<T, UniformBufferBinding>)
{
OpenGLBuffer& vkBuffer = *static_cast<OpenGLBuffer*>(arg.buffer);
VkDescriptorBufferInfo& bufferInfo = bufferBinding.emplace_back();
bufferInfo.buffer = vkBuffer.GetBuffer();
bufferInfo.offset = arg.offset;
bufferInfo.range = arg.range;
writeOp.descriptorCount = 1;
writeOp.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
writeOp.pBufferInfo = &bufferInfo;
}
else
static_assert(AlwaysFalse<T>::value, "non-exhaustive visitor");
}, binding.content);
}
m_owner.GetDevice()->vkUpdateDescriptorSets(*m_owner.GetDevice(), UInt32(writeOps.size()), writeOps.data(), 0U, nullptr);
}
void OpenGLShaderBinding::Release()
{
m_owner.Release(*this);
}
}
#endif

View File

@ -0,0 +1,31 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLShaderStage.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
bool OpenGLShaderStage::Create(Vk::Device& 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;
}
}
#endif

View File

@ -0,0 +1,49 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLSurface.hpp>
#include <Nazara/OpenGLRenderer/OpenGL.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
OpenGLSurface::OpenGLSurface() :
m_surface(OpenGL::GetInstance())
{
}
OpenGLSurface::~OpenGLSurface() = default;
bool OpenGLSurface::Create(WindowHandle handle)
{
bool success = false;
#if defined(NAZARA_PLATFORM_WINDOWS)
{
HWND winHandle = reinterpret_cast<HWND>(handle);
HINSTANCE instance = reinterpret_cast<HINSTANCE>(GetWindowLongPtrW(winHandle, GWLP_HINSTANCE));
success = m_surface.Create(instance, winHandle);
}
#else
#error This OS is not supported by OpenGL
#endif
if (!success)
{
NazaraError("Failed to create OpenGL surface: " + TranslateOpenGLError(m_surface.GetLastErrorCode()));
return false;
}
return true;
}
void OpenGLSurface::Destroy()
{
m_surface.Destroy();
}
}
#endif

View File

@ -0,0 +1,291 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLTexture.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CommandBuffer.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/QueueHandle.hpp>
#include <stdexcept>
#include <vma/vk_mem_alloc.h>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
namespace
{
inline unsigned int GetLevelSize(unsigned int size, UInt8 level)
{
if (size == 0) // Possible dans le cas d'une image invalide
return 0;
return std::max(size >> level, 1U);
}
}
OpenGLTexture::OpenGLTexture(Vk::Device& device, const TextureInfo& params) :
m_image(VK_NULL_HANDLE),
m_allocation(nullptr),
m_device(device),
m_params(params)
{
VkImageCreateInfo createInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
createInfo.mipLevels = params.mipmapLevel;
createInfo.samples = VK_SAMPLE_COUNT_1_BIT;
createInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
createInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
VkImageViewCreateInfo createInfoView = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
createInfoView.subresourceRange = {
VK_IMAGE_ASPECT_COLOR_BIT,
0,
1,
0,
1
};
InitForFormat(params.pixelFormat, createInfo, createInfoView);
switch (params.type)
{
case ImageType_1D:
NazaraAssert(params.width > 0, "Width must be over zero");
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_1D;
createInfo.imageType = VK_IMAGE_TYPE_1D;
createInfo.extent.width = params.width;
createInfo.extent.height = 1;
createInfo.extent.depth = 1;
createInfo.arrayLayers = 1;
break;
case ImageType_1D_Array:
NazaraAssert(params.width > 0, "Width must be over zero");
NazaraAssert(params.height > 0, "Height must be over zero");
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_1D_ARRAY;
createInfo.imageType = VK_IMAGE_TYPE_1D;
createInfo.extent.width = params.width;
createInfo.extent.height = 1;
createInfo.extent.depth = 1;
createInfo.arrayLayers = params.height;
break;
case ImageType_2D:
NazaraAssert(params.width > 0, "Width must be over zero");
NazaraAssert(params.height > 0, "Height must be over zero");
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_2D;
createInfo.imageType = VK_IMAGE_TYPE_2D;
createInfo.extent.width = params.width;
createInfo.extent.height = params.height;
createInfo.extent.depth = 1;
createInfo.arrayLayers = 1;
break;
case ImageType_2D_Array:
NazaraAssert(params.width > 0, "Width must be over zero");
NazaraAssert(params.height > 0, "Height must be over zero");
NazaraAssert(params.depth > 0, "Depth must be over zero");
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
createInfo.imageType = VK_IMAGE_TYPE_2D;
createInfo.extent.width = params.width;
createInfo.extent.height = params.height;
createInfo.extent.depth = 1;
createInfo.arrayLayers = params.height;
break;
case ImageType_3D:
NazaraAssert(params.width > 0, "Width must be over zero");
NazaraAssert(params.height > 0, "Height must be over zero");
NazaraAssert(params.depth > 0, "Depth must be over zero");
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_3D;
createInfo.imageType = VK_IMAGE_TYPE_3D;
createInfo.extent.width = params.width;
createInfo.extent.height = params.height;
createInfo.extent.depth = params.depth;
createInfo.arrayLayers = 1;
break;
case ImageType_Cubemap:
NazaraAssert(params.width > 0, "Width must be over zero");
NazaraAssert(params.height > 0, "Height must be over zero");
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
createInfo.imageType = VK_IMAGE_TYPE_2D;
createInfo.extent.width = params.width;
createInfo.extent.height = params.height;
createInfo.extent.depth = 1;
createInfo.arrayLayers = 6;
createInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
break;
default:
break;
}
VmaAllocationCreateInfo allocInfo = {};
allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
VkResult result = vmaCreateImage(m_device.GetMemoryAllocator(), &createInfo, &allocInfo, &m_image, &m_allocation, nullptr);
if (result != VK_SUCCESS)
throw std::runtime_error("Failed to allocate image: " + TranslateOpenGLError(result));
createInfoView.image = m_image;
if (!m_imageView.Create(device, createInfoView))
{
// FIXME
vmaDestroyImage(m_device.GetMemoryAllocator(), m_image, m_allocation);
throw std::runtime_error("Failed to create image view: " + TranslateOpenGLError(m_imageView.GetLastErrorCode()));
}
}
OpenGLTexture::~OpenGLTexture()
{
vmaDestroyImage(m_device.GetMemoryAllocator(), m_image, m_allocation);
}
PixelFormat OpenGLTexture::GetFormat() const
{
return m_params.pixelFormat;
}
UInt8 OpenGLTexture::GetLevelCount() const
{
return m_params.mipmapLevel;
}
Vector3ui OpenGLTexture::GetSize(UInt8 level) const
{
return Vector3ui(GetLevelSize(m_params.width, level), GetLevelSize(m_params.height, level), GetLevelSize(m_params.depth, level));
}
ImageType OpenGLTexture::GetType() const
{
return m_params.type;
}
bool OpenGLTexture::Update(const void* ptr)
{
std::size_t textureSize = m_params.width * m_params.height * m_params.depth * PixelFormatInfo::GetBytesPerPixel(m_params.pixelFormat);
VkBufferCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
createInfo.size = textureSize;
createInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
VmaAllocationCreateInfo allocInfo = {};
allocInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT;
allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
VmaAllocationInfo allocationInfo;
VkBuffer stagingBuffer;
VmaAllocation stagingAllocation;
VkResult result = vmaCreateBuffer(m_device.GetMemoryAllocator(), &createInfo, &allocInfo, &stagingBuffer, &stagingAllocation, &allocationInfo);
if (result != VK_SUCCESS)
{
NazaraError("Failed to allocate staging buffer: " + TranslateOpenGLError(result));
return false;
}
CallOnExit freeStaging([&] {
vmaDestroyBuffer(m_device.GetMemoryAllocator(), stagingBuffer, stagingAllocation);
});
std::memcpy(allocationInfo.pMappedData, ptr, textureSize);
Vk::AutoCommandBuffer copyCommandBuffer = m_device.AllocateCommandBuffer(QueueType::Graphics);
if (!copyCommandBuffer->Begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT))
return false;
copyCommandBuffer->SetImageLayout(m_image, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
copyCommandBuffer->CopyBufferToImage(stagingBuffer, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, m_params.width, m_params.height, m_params.depth);
copyCommandBuffer->SetImageLayout(m_image, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
if (!copyCommandBuffer->End())
return false;
Vk::QueueHandle transferQueue = m_device.GetQueue(m_device.GetDefaultFamilyIndex(QueueType::Graphics), 0);
if (!transferQueue.Submit(copyCommandBuffer))
return false;
transferQueue.WaitIdle();
return true;
}
void OpenGLTexture::InitForFormat(PixelFormat pixelFormat, VkImageCreateInfo& createImage, VkImageViewCreateInfo& createImageView)
{
createImageView.components = {
VK_COMPONENT_SWIZZLE_R,
VK_COMPONENT_SWIZZLE_G,
VK_COMPONENT_SWIZZLE_B,
VK_COMPONENT_SWIZZLE_A
};
switch (pixelFormat)
{
case PixelFormat_L8:
{
createImage.format = VK_FORMAT_R8_SRGB;
createImageView.format = createImage.format;
createImageView.components = {
VK_COMPONENT_SWIZZLE_R,
VK_COMPONENT_SWIZZLE_R,
VK_COMPONENT_SWIZZLE_R,
VK_COMPONENT_SWIZZLE_A
};
break;
}
case PixelFormat_LA8:
{
createImage.format = VK_FORMAT_R8G8_SRGB;
createImageView.format = createImage.format;
createImageView.components = {
VK_COMPONENT_SWIZZLE_R,
VK_COMPONENT_SWIZZLE_R,
VK_COMPONENT_SWIZZLE_R,
VK_COMPONENT_SWIZZLE_G
};
break;
}
case PixelFormat_RGB8:
{
createImage.format = VK_FORMAT_R8G8B8_SRGB;
createImageView.format = createImage.format;
break;
}
case PixelFormat_RGBA8:
{
createImage.format = VK_FORMAT_R8G8B8A8_SRGB;
createImageView.format = createImage.format;
break;
}
default:
throw std::runtime_error(("Unsupported pixel format " + PixelFormatInfo::GetName(pixelFormat)).ToStdString());
}
}
}
#endif

View File

@ -0,0 +1,35 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLTextureSampler.hpp>
#include <stdexcept>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
OpenGLTextureSampler::OpenGLTextureSampler(Vk::Device& device, TextureSamplerInfo samplerInfo)
{
VkSamplerCreateInfo createInfo = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
createInfo.magFilter = ToOpenGL(samplerInfo.magFilter);
createInfo.minFilter = ToOpenGL(samplerInfo.minFilter);
createInfo.addressModeU = ToOpenGL(samplerInfo.wrapModeU);
createInfo.addressModeV = ToOpenGL(samplerInfo.wrapModeV);
createInfo.addressModeW = ToOpenGL(samplerInfo.wrapModeW);
createInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
createInfo.mipmapMode = ToOpenGL(samplerInfo.mipmapMode);
if (samplerInfo.anisotropyLevel > 0.f)
{
createInfo.anisotropyEnable = VK_TRUE;
createInfo.maxAnisotropy = samplerInfo.anisotropyLevel;
}
if (!m_sampler.Create(device, createInfo))
throw std::runtime_error("Failed to create sampler: " + TranslateOpenGLError(m_sampler.GetLastErrorCode()));
}
}
#endif

View File

@ -0,0 +1,91 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/OpenGLUploadPool.hpp>
#include <cassert>
#include <stdexcept>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
auto OpenGLUploadPool::Allocate(UInt64 size) -> OpenGLAllocation&
{
const auto& deviceProperties = m_device.GetPhysicalDeviceInfo().properties;
UInt64 preferredAlignement = deviceProperties.limits.optimalBufferCopyOffsetAlignment;
return Allocate(size, preferredAlignement);
}
auto OpenGLUploadPool::Allocate(UInt64 size, UInt64 alignment) -> OpenGLAllocation&
{
assert(size <= m_blockSize);
// Try to minimize lost space
struct
{
Block* block = nullptr;
UInt64 alignedOffset = 0;
UInt64 lostSpace = 0;
} bestBlock;
for (Block& block : m_blocks)
{
UInt64 alignedOffset = AlignPow2(block.freeOffset, alignment);
if (alignedOffset + size > m_blockSize)
continue; //< Not enough space
UInt64 lostSpace = alignedOffset - block.freeOffset;
if (!bestBlock.block || lostSpace < bestBlock.lostSpace)
{
bestBlock.block = &block;
bestBlock.alignedOffset = alignedOffset;
bestBlock.lostSpace = lostSpace;
}
}
// No block found, allocate a new one
if (!bestBlock.block)
{
Block newBlock;
if (!newBlock.buffer.Create(m_device, 0U, m_blockSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT))
throw std::runtime_error("Failed to create block buffer: " + TranslateOpenGLError(newBlock.buffer.GetLastErrorCode()));
VkMemoryRequirements requirement = newBlock.buffer.GetMemoryRequirements();
if (!newBlock.blockMemory.Create(m_device, requirement.size, requirement.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
throw std::runtime_error("Failed to allocate block memory: " + TranslateOpenGLError(newBlock.blockMemory.GetLastErrorCode()));
if (!newBlock.buffer.BindBufferMemory(newBlock.blockMemory))
throw std::runtime_error("Failed to bind buffer memory: " + TranslateOpenGLError(newBlock.buffer.GetLastErrorCode()));
if (!newBlock.blockMemory.Map())
throw std::runtime_error("Failed to map buffer memory: " + TranslateOpenGLError(newBlock.buffer.GetLastErrorCode()));
bestBlock.block = &m_blocks.emplace_back(std::move(newBlock));
bestBlock.alignedOffset = 0;
bestBlock.lostSpace = 0;
}
OpenGLAllocation& allocationData = m_allocations.emplace_back();
allocationData.buffer = bestBlock.block->buffer;
allocationData.mappedPtr = static_cast<UInt8*>(bestBlock.block->blockMemory.GetMappedPointer()) + bestBlock.alignedOffset;
allocationData.offset = bestBlock.alignedOffset;
allocationData.size = size;
return allocationData;
}
void OpenGLUploadPool::Reset()
{
for (Block& block : m_blocks)
block.freeOffset = 0;
m_allocations.clear();
}
}
#endif

View File

@ -0,0 +1,106 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if 0
#include <Nazara/OpenGLRenderer/Utils.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
std::string TranslateOpenGLError(VkResult code)
{
// From https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/xhtml/vkspec.html#VkResult
switch (code)
{
case VK_SUCCESS:
return "No error";
case VK_NOT_READY:
return "A fence or query has not yet completed";
case VK_TIMEOUT:
return "A wait operation has not completed in the specified time";
case VK_EVENT_SET:
return "An event is signaled";
case VK_EVENT_RESET:
return "An event is unsignaled";
case VK_INCOMPLETE:
return "A return array was too small for the result";
case VK_ERROR_OUT_OF_HOST_MEMORY:
return "A host memory allocation has failed";
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
return "A device memory allocation has failed";
case VK_ERROR_INITIALIZATION_FAILED:
return "Initialization of an object could not be completed for implementation-specific reasons";
case VK_ERROR_DEVICE_LOST:
return "The logical or physical device has been lost";
case VK_ERROR_MEMORY_MAP_FAILED:
return "Mapping of the memory object has failed";
case VK_ERROR_LAYER_NOT_PRESENT:
return "A requested layer is not present or could not be loaded";
case VK_ERROR_EXTENSION_NOT_PRESENT:
return "A requested extension is not supported";
case VK_ERROR_FEATURE_NOT_PRESENT:
return "A requested feature is not supported";
case VK_ERROR_INCOMPATIBLE_DRIVER:
return "The requested version of OpenGL is not supported by the driver or is otherwise incompatible for implementation-specific reasons";
case VK_ERROR_TOO_MANY_OBJECTS:
return "Too many objects of the type have already been created";
case VK_ERROR_FORMAT_NOT_SUPPORTED:
return "A requested format is not supported on this device";
case VK_ERROR_FRAGMENTED_POOL:
return "A requested pool allocation has failed due to fragmentation of the pools memory";
case VK_ERROR_SURFACE_LOST_KHR:
return "A surface is no longer available";
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
return "The requested window is already connected to a VkSurfaceKHR, or to some other non-OpenGL API";
case VK_SUBOPTIMAL_KHR:
return "A swapchain no longer matches the surface properties exactly, but can still be used to present to the surface successfully";
case VK_ERROR_OUT_OF_DATE_KHR:
return "A surface has changed in such a way that it is no longer compatible with the swapchain, and further presentation requests using the swapchain will fail. Applications must query the new surface properties and recreate their swapchain if they wish to continue presenting to the surface";
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
return "The display used by a swapchain does not use the same presentable image layout, or is incompatible in a way that prevents sharing an image";
case VK_ERROR_VALIDATION_FAILED_EXT:
return "A validation layer found an error";
case VK_ERROR_INVALID_SHADER_NV:
return "One or more shaders failed to compile or link";
case VK_ERROR_OUT_OF_POOL_MEMORY_KHR:
return "A requested pool allocation has failed";
case VK_ERROR_INVALID_EXTERNAL_HANDLE:
return "An external handle is not a valid handle of the specified type";
default:
break;
}
return "Unknown OpenGL error (0x" + String::Number(code, 16).ToStdString() + ')';
}
}
#endif

Some files were not shown because too many files have changed in this diff Show More