OpenGL: Implement commands buffers
This commit is contained in:
parent
fe5b70ae1c
commit
6a23d51147
|
|
@ -8,22 +8,138 @@
|
||||||
#define NAZARA_OPENGLRENDERER_OPENGLCOMMANDBUFFER_HPP
|
#define NAZARA_OPENGLRENDERER_OPENGLCOMMANDBUFFER_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequisites.hpp>
|
#include <Nazara/Prerequisites.hpp>
|
||||||
|
#include <Nazara/Core/Color.hpp>
|
||||||
|
#include <Nazara/Math/Rect.hpp>
|
||||||
#include <Nazara/Renderer/CommandBuffer.hpp>
|
#include <Nazara/Renderer/CommandBuffer.hpp>
|
||||||
|
#include <Nazara/Renderer/CommandBufferBuilder.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/Config.hpp>
|
#include <Nazara/OpenGLRenderer/Config.hpp>
|
||||||
|
#include <Nazara/OpenGLRenderer/OpenGLBuffer.hpp>
|
||||||
|
#include <Nazara/OpenGLRenderer/OpenGLRenderPipeline.hpp>
|
||||||
|
#include <Nazara/OpenGLRenderer/OpenGLShaderBinding.hpp>
|
||||||
|
#include <optional>
|
||||||
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
class OpenGLFramebuffer;
|
||||||
|
|
||||||
class NAZARA_OPENGLRENDERER_API OpenGLCommandBuffer final : public CommandBuffer
|
class NAZARA_OPENGLRENDERER_API OpenGLCommandBuffer final : public CommandBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline OpenGLCommandBuffer();
|
OpenGLCommandBuffer() = default;
|
||||||
OpenGLCommandBuffer(const OpenGLCommandBuffer&) = delete;
|
OpenGLCommandBuffer(const OpenGLCommandBuffer&) = delete;
|
||||||
OpenGLCommandBuffer(OpenGLCommandBuffer&&) noexcept = default;
|
OpenGLCommandBuffer(OpenGLCommandBuffer&&) noexcept = default;
|
||||||
~OpenGLCommandBuffer() = default;
|
~OpenGLCommandBuffer() = default;
|
||||||
|
|
||||||
|
inline void BeginDebugRegion(const std::string_view& regionName, const Nz::Color& color);
|
||||||
|
|
||||||
|
inline void BindIndexBuffer(GLuint indexBuffer, UInt64 offset = 0);
|
||||||
|
inline void BindPipeline(const OpenGLRenderPipeline* pipeline);
|
||||||
|
inline void BindShaderBinding(const OpenGLShaderBinding* binding);
|
||||||
|
inline void BindVertexBuffer(UInt32 binding, GLuint vertexBuffer, UInt64 offset = 0);
|
||||||
|
|
||||||
|
inline void CopyBuffer(GLuint source, GLuint target, UInt64 size, UInt64 sourceOffset = 0, UInt64 targetOffset = 0);
|
||||||
|
inline void CopyBuffer(const UploadPool::Allocation& allocation, GLuint target, UInt64 size, UInt64 sourceOffset = 0, UInt64 targetOffset = 0);
|
||||||
|
|
||||||
|
inline void Draw(UInt32 vertexCount, UInt32 instanceCount = 1, UInt32 firstVertex = 0, UInt32 firstInstance = 0);
|
||||||
|
inline void DrawIndexed(UInt32 indexCount, UInt32 instanceCount = 1, UInt32 firstVertex = 0, UInt32 firstInstance = 0);
|
||||||
|
|
||||||
|
inline void EndDebugRegion();
|
||||||
|
|
||||||
|
void Execute();
|
||||||
|
|
||||||
|
inline void SetFramebuffer(const OpenGLFramebuffer& framebuffer, const RenderPass& renderPass, std::initializer_list<CommandBufferBuilder::ClearValues> clearValues);
|
||||||
|
inline void SetScissor(Nz::Recti scissorRegion);
|
||||||
|
inline void SetViewport(Nz::Recti viewportRegion);
|
||||||
|
|
||||||
OpenGLCommandBuffer& operator=(const OpenGLCommandBuffer&) = delete;
|
OpenGLCommandBuffer& operator=(const OpenGLCommandBuffer&) = delete;
|
||||||
OpenGLCommandBuffer& operator=(OpenGLCommandBuffer&&) = delete;
|
OpenGLCommandBuffer& operator=(OpenGLCommandBuffer&&) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct DrawStates;
|
||||||
|
|
||||||
|
void ApplyStates(const GL::Context& context, const DrawStates& states);
|
||||||
|
|
||||||
|
struct BeginDebugRegionData
|
||||||
|
{
|
||||||
|
std::string regionName;
|
||||||
|
Nz::Color color;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CopyBufferData
|
||||||
|
{
|
||||||
|
GLuint source;
|
||||||
|
GLuint target;
|
||||||
|
UInt64 size;
|
||||||
|
UInt64 sourceOffset;
|
||||||
|
UInt64 targetOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CopyBufferFromMemoryData
|
||||||
|
{
|
||||||
|
const void* memory;
|
||||||
|
GLuint target;
|
||||||
|
UInt64 size;
|
||||||
|
UInt64 targetOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DrawStates
|
||||||
|
{
|
||||||
|
struct VertexBuffer
|
||||||
|
{
|
||||||
|
GLuint vertexBuffer = 0;
|
||||||
|
UInt64 offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
GLuint indexBuffer = 0;
|
||||||
|
const OpenGLRenderPipeline* pipeline = nullptr;
|
||||||
|
const OpenGLShaderBinding* shaderBindings = nullptr;
|
||||||
|
UInt64 indexBufferOffset;
|
||||||
|
std::optional<Nz::Recti> scissorRegion;
|
||||||
|
std::optional<Nz::Recti> viewportRegion;
|
||||||
|
std::vector<VertexBuffer> vertexBuffers;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DrawData
|
||||||
|
{
|
||||||
|
DrawStates states;
|
||||||
|
UInt32 firstInstance;
|
||||||
|
UInt32 firstVertex;
|
||||||
|
UInt32 instanceCount;
|
||||||
|
UInt32 vertexCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DrawIndexedData
|
||||||
|
{
|
||||||
|
DrawStates states;
|
||||||
|
UInt32 firstInstance;
|
||||||
|
UInt32 firstVertex;
|
||||||
|
UInt32 indexCount;
|
||||||
|
UInt32 instanceCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EndDebugRegionData
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SetFrameBufferData
|
||||||
|
{
|
||||||
|
const OpenGLFramebuffer* framebuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
using CommandData = std::variant<
|
||||||
|
BeginDebugRegionData,
|
||||||
|
CopyBufferData,
|
||||||
|
CopyBufferFromMemoryData,
|
||||||
|
DrawData,
|
||||||
|
DrawIndexedData,
|
||||||
|
EndDebugRegionData,
|
||||||
|
SetFrameBufferData
|
||||||
|
>;
|
||||||
|
|
||||||
|
DrawStates m_currentStates;
|
||||||
|
std::vector<CommandData> m_commands;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,124 @@
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
|
||||||
|
#include <Nazara/OpenGLRenderer/OpenGLFramebuffer.hpp>
|
||||||
|
#include <stdexcept>
|
||||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
inline void OpenGLCommandBuffer::BeginDebugRegion(const std::string_view& regionName, const Nz::Color& color)
|
||||||
|
{
|
||||||
|
BeginDebugRegionData beginDebugRegion;
|
||||||
|
beginDebugRegion.color = color;
|
||||||
|
beginDebugRegion.regionName = regionName;
|
||||||
|
|
||||||
|
m_commands.emplace_back(std::move(beginDebugRegion));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void OpenGLCommandBuffer::BindIndexBuffer(GLuint indexBuffer, UInt64 offset)
|
||||||
|
{
|
||||||
|
m_currentStates.indexBuffer = indexBuffer;
|
||||||
|
m_currentStates.indexBufferOffset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void OpenGLCommandBuffer::BindPipeline(const OpenGLRenderPipeline* pipeline)
|
||||||
|
{
|
||||||
|
m_currentStates.pipeline = pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void OpenGLCommandBuffer::BindShaderBinding(const OpenGLShaderBinding* binding)
|
||||||
|
{
|
||||||
|
m_currentStates.shaderBindings = binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void OpenGLCommandBuffer::BindVertexBuffer(UInt32 binding, GLuint vertexBuffer, UInt64 offset)
|
||||||
|
{
|
||||||
|
if (binding >= m_currentStates.vertexBuffers.size())
|
||||||
|
m_currentStates.vertexBuffers.resize(binding + 1);
|
||||||
|
|
||||||
|
auto& vertexBufferData = m_currentStates.vertexBuffers[binding];
|
||||||
|
vertexBufferData.offset = offset;
|
||||||
|
vertexBufferData.vertexBuffer = vertexBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void OpenGLCommandBuffer::CopyBuffer(GLuint source, GLuint target, UInt64 size, UInt64 sourceOffset, UInt64 targetOffset)
|
||||||
|
{
|
||||||
|
CopyBufferData copyBuffer = {
|
||||||
|
source,
|
||||||
|
target,
|
||||||
|
size,
|
||||||
|
sourceOffset,
|
||||||
|
targetOffset
|
||||||
|
};
|
||||||
|
|
||||||
|
m_commands.emplace_back(std::move(copyBuffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void OpenGLCommandBuffer::CopyBuffer(const UploadPool::Allocation& allocation, GLuint target, UInt64 size, UInt64 sourceOffset, UInt64 targetOffset)
|
||||||
|
{
|
||||||
|
CopyBufferFromMemoryData copyBuffer = {
|
||||||
|
static_cast<const UInt8*>(allocation.mappedPtr) + sourceOffset,
|
||||||
|
target,
|
||||||
|
size,
|
||||||
|
targetOffset
|
||||||
|
};
|
||||||
|
|
||||||
|
m_commands.emplace_back(std::move(copyBuffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void OpenGLCommandBuffer::Draw(UInt32 vertexCount, UInt32 instanceCount, UInt32 firstVertex, UInt32 firstInstance)
|
||||||
|
{
|
||||||
|
if (!m_currentStates.pipeline)
|
||||||
|
throw std::runtime_error("no pipeline bound");
|
||||||
|
|
||||||
|
DrawData draw;
|
||||||
|
draw.states = m_currentStates;
|
||||||
|
draw.firstInstance = firstInstance;
|
||||||
|
draw.firstVertex = firstVertex;
|
||||||
|
draw.instanceCount = instanceCount;
|
||||||
|
draw.vertexCount = vertexCount;
|
||||||
|
|
||||||
|
m_commands.emplace_back(std::move(draw));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void OpenGLCommandBuffer::DrawIndexed(UInt32 indexCount, UInt32 instanceCount, UInt32 firstVertex, UInt32 firstInstance)
|
||||||
|
{
|
||||||
|
if (!m_currentStates.pipeline)
|
||||||
|
throw std::runtime_error("no pipeline bound");
|
||||||
|
|
||||||
|
DrawIndexedData draw;
|
||||||
|
draw.states = m_currentStates;
|
||||||
|
draw.firstInstance = firstInstance;
|
||||||
|
draw.firstVertex = firstVertex;
|
||||||
|
draw.indexCount = indexCount;
|
||||||
|
draw.instanceCount = instanceCount;
|
||||||
|
|
||||||
|
m_commands.emplace_back(std::move(draw));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void OpenGLCommandBuffer::EndDebugRegion()
|
||||||
|
{
|
||||||
|
m_commands.emplace_back(EndDebugRegionData{});
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void OpenGLCommandBuffer::SetFramebuffer(const OpenGLFramebuffer& framebuffer, const RenderPass& /*renderPass*/, std::initializer_list<CommandBufferBuilder::ClearValues> clearValues)
|
||||||
|
{
|
||||||
|
SetFrameBufferData setFramebuffer;
|
||||||
|
setFramebuffer.framebuffer = &framebuffer;
|
||||||
|
|
||||||
|
m_commands.emplace_back(std::move(setFramebuffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void OpenGLCommandBuffer::SetScissor(Nz::Recti scissorRegion)
|
||||||
|
{
|
||||||
|
m_currentStates.scissorRegion = scissorRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void OpenGLCommandBuffer::SetViewport(Nz::Recti viewportRegion)
|
||||||
|
{
|
||||||
|
m_currentStates.viewportRegion = viewportRegion;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Nazara/OpenGLRenderer/DebugOff.hpp>
|
#include <Nazara/OpenGLRenderer/DebugOff.hpp>
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,12 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
class OpenGLRenderPass;
|
class OpenGLCommandBuffer;
|
||||||
|
|
||||||
class NAZARA_OPENGLRENDERER_API OpenGLCommandBufferBuilder final : public CommandBufferBuilder
|
class NAZARA_OPENGLRENDERER_API OpenGLCommandBufferBuilder final : public CommandBufferBuilder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OpenGLCommandBufferBuilder() = default;
|
inline OpenGLCommandBufferBuilder(OpenGLCommandBuffer& commandBuffer);
|
||||||
OpenGLCommandBufferBuilder(const OpenGLCommandBufferBuilder&) = delete;
|
OpenGLCommandBufferBuilder(const OpenGLCommandBufferBuilder&) = delete;
|
||||||
OpenGLCommandBufferBuilder(OpenGLCommandBufferBuilder&&) noexcept = default;
|
OpenGLCommandBufferBuilder(OpenGLCommandBufferBuilder&&) noexcept = default;
|
||||||
~OpenGLCommandBufferBuilder() = default;
|
~OpenGLCommandBufferBuilder() = default;
|
||||||
|
|
@ -48,9 +48,12 @@ namespace Nz
|
||||||
|
|
||||||
OpenGLCommandBufferBuilder& operator=(const OpenGLCommandBufferBuilder&) = delete;
|
OpenGLCommandBufferBuilder& operator=(const OpenGLCommandBufferBuilder&) = delete;
|
||||||
OpenGLCommandBufferBuilder& operator=(OpenGLCommandBufferBuilder&&) = delete;
|
OpenGLCommandBufferBuilder& operator=(OpenGLCommandBufferBuilder&&) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpenGLCommandBuffer& m_commandBuffer;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.inl>
|
#include <Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.inl>
|
||||||
|
|
||||||
#endif // NAZARA_OPENGLRENDERER_OPENGLCOMMANDBUFFERBUILDER_HPP
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
inline OpenGLCommandBufferBuilder::OpenGLCommandBufferBuilder(OpenGLCommandBuffer& commandBuffer) :
|
||||||
|
m_commandBuffer(commandBuffer)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Nazara/OpenGLRenderer/DebugOff.hpp>
|
#include <Nazara/OpenGLRenderer/DebugOff.hpp>
|
||||||
|
|
|
||||||
|
|
@ -10,15 +10,13 @@
|
||||||
#include <Nazara/Prerequisites.hpp>
|
#include <Nazara/Prerequisites.hpp>
|
||||||
#include <Nazara/Renderer/CommandPool.hpp>
|
#include <Nazara/Renderer/CommandPool.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/Config.hpp>
|
#include <Nazara/OpenGLRenderer/Config.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/Wrapper/CommandPool.hpp>
|
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
class NAZARA_OPENGLRENDERER_API OpenGLCommandPool final : public CommandPool
|
class NAZARA_OPENGLRENDERER_API OpenGLCommandPool final : public CommandPool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline OpenGLCommandPool(Vk::Device& device, QueueType queueType);
|
OpenGLCommandPool() = default;
|
||||||
inline OpenGLCommandPool(Vk::Device& device, UInt32 queueFamilyIndex);
|
|
||||||
OpenGLCommandPool(const OpenGLCommandPool&) = delete;
|
OpenGLCommandPool(const OpenGLCommandPool&) = delete;
|
||||||
OpenGLCommandPool(OpenGLCommandPool&&) noexcept = default;
|
OpenGLCommandPool(OpenGLCommandPool&&) noexcept = default;
|
||||||
~OpenGLCommandPool() = default;
|
~OpenGLCommandPool() = default;
|
||||||
|
|
@ -27,9 +25,6 @@ namespace Nz
|
||||||
|
|
||||||
OpenGLCommandPool& operator=(const OpenGLCommandPool&) = delete;
|
OpenGLCommandPool& operator=(const OpenGLCommandPool&) = delete;
|
||||||
OpenGLCommandPool& operator=(OpenGLCommandPool&&) = delete;
|
OpenGLCommandPool& operator=(OpenGLCommandPool&&) = delete;
|
||||||
|
|
||||||
private:
|
|
||||||
Vk::CommandPool m_commandPool;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,21 +8,6 @@
|
||||||
|
|
||||||
namespace Nz
|
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>
|
#include <Nazara/OpenGLRenderer/DebugOff.hpp>
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
class OpenGLCommandBuffer;
|
||||||
class OpenGLRenderWindow;
|
class OpenGLRenderWindow;
|
||||||
|
|
||||||
class NAZARA_OPENGLRENDERER_API OpenGLRenderImage : public RenderImage
|
class NAZARA_OPENGLRENDERER_API OpenGLRenderImage : public RenderImage
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
|
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/Config.hpp>
|
#include <Nazara/OpenGLRenderer/Config.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLShaderBinding.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLShaderBinding.hpp>
|
||||||
|
#include <Nazara/OpenGLRenderer/Wrapper/Context.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/Wrapper/CoreFunctions.hpp>
|
#include <Nazara/OpenGLRenderer/Wrapper/CoreFunctions.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
@ -53,12 +54,15 @@ namespace Nz
|
||||||
|
|
||||||
struct TextureDescriptor
|
struct TextureDescriptor
|
||||||
{
|
{
|
||||||
|
UInt32 bindingIndex;
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
GLuint sampler;
|
GLuint sampler;
|
||||||
|
GL::TextureTarget textureTarget;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UniformBufferDescriptor
|
struct UniformBufferDescriptor
|
||||||
{
|
{
|
||||||
|
UInt32 bindingIndex;
|
||||||
GLuint buffer;
|
GLuint buffer;
|
||||||
GLintptr offset;
|
GLintptr offset;
|
||||||
GLsizeiptr size;
|
GLsizeiptr size;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <Nazara/Prerequisites.hpp>
|
#include <Nazara/Prerequisites.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/Config.hpp>
|
#include <Nazara/OpenGLRenderer/Config.hpp>
|
||||||
|
#include <Nazara/OpenGLRenderer/Wrapper/Context.hpp>
|
||||||
#include <Nazara/Renderer/ShaderBinding.hpp>
|
#include <Nazara/Renderer/ShaderBinding.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
|
|
@ -23,6 +24,8 @@ namespace Nz
|
||||||
OpenGLShaderBinding(OpenGLShaderBinding&&) noexcept = default;
|
OpenGLShaderBinding(OpenGLShaderBinding&&) noexcept = default;
|
||||||
~OpenGLShaderBinding() = default;
|
~OpenGLShaderBinding() = default;
|
||||||
|
|
||||||
|
void Apply(const GL::Context& context) const;
|
||||||
|
|
||||||
inline std::size_t GetBindingIndex() const;
|
inline std::size_t GetBindingIndex() const;
|
||||||
inline std::size_t GetPoolIndex() const;
|
inline std::size_t GetPoolIndex() const;
|
||||||
inline const OpenGLRenderPipelineLayout& GetOwner() const;
|
inline const OpenGLRenderPipelineLayout& GetOwner() const;
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ namespace Nz
|
||||||
OpenGLShaderStage(OpenGLShaderStage&&) noexcept = default;
|
OpenGLShaderStage(OpenGLShaderStage&&) noexcept = default;
|
||||||
~OpenGLShaderStage() = default;
|
~OpenGLShaderStage() = default;
|
||||||
|
|
||||||
|
inline const GL::Shader& GetShader() const;
|
||||||
|
|
||||||
OpenGLShaderStage& operator=(const OpenGLShaderStage&) = delete;
|
OpenGLShaderStage& operator=(const OpenGLShaderStage&) = delete;
|
||||||
OpenGLShaderStage& operator=(OpenGLShaderStage&&) noexcept = default;
|
OpenGLShaderStage& operator=(OpenGLShaderStage&&) noexcept = default;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
inline const GL::Shader& OpenGLShaderStage::GetShader() const
|
||||||
|
{
|
||||||
|
return m_shader;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Nazara/OpenGLRenderer/DebugOff.hpp>
|
#include <Nazara/OpenGLRenderer/DebugOff.hpp>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,9 @@
|
||||||
|
|
||||||
#include <Nazara/Prerequisites.hpp>
|
#include <Nazara/Prerequisites.hpp>
|
||||||
#include <Nazara/Core/Algorithm.hpp>
|
#include <Nazara/Core/Algorithm.hpp>
|
||||||
|
#include <Nazara/OpenGLRenderer/OpenGLVaoCache.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/Wrapper/CoreFunctions.hpp>
|
#include <Nazara/OpenGLRenderer/Wrapper/CoreFunctions.hpp>
|
||||||
|
#include <Nazara/Renderer/RenderStates.hpp>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
@ -94,17 +96,21 @@ namespace Nz::GL
|
||||||
inline Context(const OpenGLDevice* device);
|
inline Context(const OpenGLDevice* device);
|
||||||
virtual ~Context();
|
virtual ~Context();
|
||||||
|
|
||||||
void BindBuffer(BufferTarget target, GLuint buffer) const;
|
void BindBuffer(BufferTarget target, GLuint buffer, bool force = false) const;
|
||||||
void BindFramebuffer(GLuint fbo) const;
|
void BindFramebuffer(GLuint fbo) const;
|
||||||
void BindFramebuffer(FramebufferTarget target, GLuint fbo) const;
|
void BindFramebuffer(FramebufferTarget target, GLuint fbo) const;
|
||||||
|
void BindProgram(GLuint program) const;
|
||||||
void BindSampler(UInt32 textureUnit, GLuint sampler) const;
|
void BindSampler(UInt32 textureUnit, GLuint sampler) const;
|
||||||
void BindTexture(TextureTarget target, GLuint texture) const;
|
void BindTexture(TextureTarget target, GLuint texture) const;
|
||||||
void BindTexture(UInt32 textureUnit, TextureTarget target, GLuint texture) const;
|
void BindTexture(UInt32 textureUnit, TextureTarget target, GLuint texture) const;
|
||||||
|
void BindUniformBuffer(UInt32 uboUnit, GLuint buffer, GLintptr offset, GLsizeiptr size) const;
|
||||||
|
void BindVertexArray(GLuint vertexArray, bool force = false) const;
|
||||||
|
|
||||||
virtual void EnableVerticalSync(bool enabled) = 0;
|
virtual void EnableVerticalSync(bool enabled) = 0;
|
||||||
|
|
||||||
inline const OpenGLDevice* GetDevice() const;
|
inline const OpenGLDevice* GetDevice() const;
|
||||||
inline ExtensionStatus GetExtensionStatus(Extension extension) const;
|
inline ExtensionStatus GetExtensionStatus(Extension extension) const;
|
||||||
|
inline const OpenGLVaoCache& GetVaoCache() const;
|
||||||
inline const ContextParams& GetParams() const;
|
inline const ContextParams& GetParams() const;
|
||||||
|
|
||||||
inline bool IsExtensionSupported(Extension extension) const;
|
inline bool IsExtensionSupported(Extension extension) const;
|
||||||
|
|
@ -116,8 +122,11 @@ namespace Nz::GL
|
||||||
inline void NotifyProgramDestruction(GLuint program) const;
|
inline void NotifyProgramDestruction(GLuint program) const;
|
||||||
inline void NotifySamplerDestruction(GLuint sampler) const;
|
inline void NotifySamplerDestruction(GLuint sampler) const;
|
||||||
inline void NotifyTextureDestruction(GLuint texture) const;
|
inline void NotifyTextureDestruction(GLuint texture) const;
|
||||||
|
inline void NotifyVertexArrayDestruction(GLuint vao) const;
|
||||||
|
|
||||||
inline void SetCurrentTextureUnit(UInt32 textureUnit) const;
|
void SetCurrentTextureUnit(UInt32 textureUnit) const;
|
||||||
|
void SetScissorBox(GLint x, GLint y, GLsizei width, GLsizei height) const;
|
||||||
|
void SetViewport(GLint x, GLint y, GLsizei width, GLsizei height) const;
|
||||||
|
|
||||||
virtual void SwapBuffers() = 0;
|
virtual void SwapBuffers() = 0;
|
||||||
|
|
||||||
|
|
@ -134,6 +143,7 @@ namespace Nz::GL
|
||||||
virtual bool Activate() const = 0;
|
virtual bool Activate() const = 0;
|
||||||
virtual void Desactivate() const = 0;
|
virtual void Desactivate() const = 0;
|
||||||
virtual const Loader& GetLoader() = 0;
|
virtual const Loader& GetLoader() = 0;
|
||||||
|
void OnContextRelease();
|
||||||
|
|
||||||
virtual bool ImplementFallback(const std::string_view& function);
|
virtual bool ImplementFallback(const std::string_view& function);
|
||||||
|
|
||||||
|
|
@ -146,23 +156,41 @@ namespace Nz::GL
|
||||||
|
|
||||||
struct State
|
struct State
|
||||||
{
|
{
|
||||||
|
struct Box
|
||||||
|
{
|
||||||
|
GLint x, y;
|
||||||
|
GLsizei width, height;
|
||||||
|
};
|
||||||
|
|
||||||
struct TextureUnit
|
struct TextureUnit
|
||||||
{
|
{
|
||||||
GLuint sampler = 0;
|
GLuint sampler = 0;
|
||||||
std::array<GLuint, UnderlyingCast(TextureTarget::Max) + 1> textureTargets = { 0 };
|
std::array<GLuint, UnderlyingCast(TextureTarget::Max) + 1> textureTargets = { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UniformBufferUnit
|
||||||
|
{
|
||||||
|
GLuint buffer = 0;
|
||||||
|
GLintptr offset = 0;
|
||||||
|
GLsizeiptr size = 0;
|
||||||
|
};
|
||||||
|
|
||||||
std::array<GLuint, UnderlyingCast(BufferTarget::Max) + 1> bufferTargets = { 0 };
|
std::array<GLuint, UnderlyingCast(BufferTarget::Max) + 1> bufferTargets = { 0 };
|
||||||
std::vector<TextureUnit> textureUnits;
|
std::vector<TextureUnit> textureUnits;
|
||||||
|
std::vector<UniformBufferUnit> uboUnits;
|
||||||
|
Box scissorBox;
|
||||||
|
Box viewport;
|
||||||
GLuint boundProgram = 0;
|
GLuint boundProgram = 0;
|
||||||
GLuint boundDrawFBO = 0;
|
GLuint boundDrawFBO = 0;
|
||||||
GLuint boundReadFBO = 0;
|
GLuint boundReadFBO = 0;
|
||||||
|
GLuint boundVertexArray = 0;
|
||||||
UInt32 currentTextureUnit = 0;
|
UInt32 currentTextureUnit = 0;
|
||||||
RenderStates renderStates;
|
RenderStates renderStates;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::array<ExtensionStatus, UnderlyingCast(Extension::Max) + 1> m_extensionStatus;
|
std::array<ExtensionStatus, UnderlyingCast(Extension::Max) + 1> m_extensionStatus;
|
||||||
std::unordered_set<std::string> m_supportedExtensions;
|
std::unordered_set<std::string> m_supportedExtensions;
|
||||||
|
OpenGLVaoCache m_vaoCache;
|
||||||
const OpenGLDevice* m_device;
|
const OpenGLDevice* m_device;
|
||||||
mutable State m_state;
|
mutable State m_state;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
namespace Nz::GL
|
namespace Nz::GL
|
||||||
{
|
{
|
||||||
inline Context::Context(const OpenGLDevice* device) :
|
inline Context::Context(const OpenGLDevice* device) :
|
||||||
|
m_vaoCache(*this),
|
||||||
m_device(device)
|
m_device(device)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -22,6 +23,11 @@ namespace Nz::GL
|
||||||
return m_extensionStatus[UnderlyingCast(extension)];
|
return m_extensionStatus[UnderlyingCast(extension)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const OpenGLVaoCache& Context::GetVaoCache() const
|
||||||
|
{
|
||||||
|
return m_vaoCache;
|
||||||
|
}
|
||||||
|
|
||||||
inline const ContextParams& Context::GetParams() const
|
inline const ContextParams& Context::GetParams() const
|
||||||
{
|
{
|
||||||
return m_params;
|
return m_params;
|
||||||
|
|
@ -73,13 +79,10 @@ namespace Nz::GL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Context::SetCurrentTextureUnit(UInt32 textureUnit) const
|
inline void Context::NotifyVertexArrayDestruction(GLuint vao) const
|
||||||
{
|
{
|
||||||
if (m_state.currentTextureUnit != textureUnit)
|
if (m_state.boundVertexArray == vao)
|
||||||
{
|
m_state.boundVertexArray = 0;
|
||||||
glActiveTexture(GL_TEXTURE0 + textureUnit);
|
|
||||||
m_state.currentTextureUnit = textureUnit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,141 @@
|
||||||
// This file is part of the "Nazara Engine - OpenGL Renderer"
|
// This file is part of the "Nazara Engine - OpenGL Renderer"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
|
||||||
|
#include <Nazara/OpenGLRenderer/OpenGLVaoCache.hpp>
|
||||||
|
#include <Nazara/OpenGLRenderer/Wrapper/Context.hpp>
|
||||||
|
#include <Nazara/OpenGLRenderer/Wrapper/VertexArray.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
}
|
namespace
|
||||||
|
{
|
||||||
|
void BuildAttrib(GL::OpenGLVaoSetup::Attribs& attrib, ComponentType component)
|
||||||
|
{
|
||||||
|
switch (component)
|
||||||
|
{
|
||||||
|
case ComponentType_Color:
|
||||||
|
attrib.normalized = GL_TRUE;
|
||||||
|
attrib.size = 4;
|
||||||
|
attrib.type = GL_UNSIGNED_BYTE;
|
||||||
|
return;
|
||||||
|
|
||||||
#endif
|
case ComponentType_Float1:
|
||||||
|
case ComponentType_Float2:
|
||||||
|
case ComponentType_Float3:
|
||||||
|
case ComponentType_Float4:
|
||||||
|
attrib.normalized = GL_FALSE;
|
||||||
|
attrib.size = (component - ComponentType_Float1 + 1);
|
||||||
|
attrib.type = GL_FLOAT;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case ComponentType_Int1:
|
||||||
|
case ComponentType_Int2:
|
||||||
|
case ComponentType_Int3:
|
||||||
|
case ComponentType_Int4:
|
||||||
|
attrib.normalized = GL_FALSE;
|
||||||
|
attrib.size = (component - ComponentType_Int1 + 1);
|
||||||
|
attrib.type = GL_INT;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case ComponentType_Double1:
|
||||||
|
case ComponentType_Double2:
|
||||||
|
case ComponentType_Double3:
|
||||||
|
case ComponentType_Double4:
|
||||||
|
case ComponentType_Quaternion:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error(("component type 0x" + String::Number(component, 16) + " is not handled").ToStdString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandBuffer::Execute()
|
||||||
|
{
|
||||||
|
const GL::Context* context = GL::Context::GetCurrentContext();
|
||||||
|
|
||||||
|
for (const auto& command : m_commands)
|
||||||
|
{
|
||||||
|
std::visit([&](auto&& command)
|
||||||
|
{
|
||||||
|
using T = std::decay_t<decltype(command)>;
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<T, BeginDebugRegionData> || std::is_same_v<T, EndDebugRegionData>)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, CopyBufferData>)
|
||||||
|
{
|
||||||
|
context->BindBuffer(GL::BufferTarget::CopyRead, command.source);
|
||||||
|
context->BindBuffer(GL::BufferTarget::CopyWrite, command.target);
|
||||||
|
context->glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, command.sourceOffset, command.targetOffset, command.size);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, CopyBufferFromMemoryData>)
|
||||||
|
{
|
||||||
|
context->BindBuffer(GL::BufferTarget::CopyWrite, command.target);
|
||||||
|
context->glBufferSubData(GL_COPY_WRITE_BUFFER, command.targetOffset, command.size, command.memory);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, DrawData>)
|
||||||
|
{
|
||||||
|
ApplyStates(*context, m_currentStates);
|
||||||
|
context->glDrawArraysInstanced(GL_TRIANGLES, command.firstVertex, command.vertexCount, command.instanceCount);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, DrawIndexedData>)
|
||||||
|
{
|
||||||
|
ApplyStates(*context, m_currentStates);
|
||||||
|
context->glDrawElementsInstanced(GL_TRIANGLES, command.indexCount, GL_UNSIGNED_SHORT, nullptr, command.instanceCount);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, SetFrameBufferData>)
|
||||||
|
{
|
||||||
|
command.framebuffer->Activate();
|
||||||
|
|
||||||
|
context = GL::Context::GetCurrentContext();
|
||||||
|
context->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
static_assert(AlwaysFalse<T>::value, "non-exhaustive visitor");
|
||||||
|
|
||||||
|
}, command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandBuffer::ApplyStates(const GL::Context& context, const DrawStates& states)
|
||||||
|
{
|
||||||
|
states.shaderBindings->Apply(context);
|
||||||
|
states.pipeline->Apply(context);
|
||||||
|
|
||||||
|
if (states.scissorRegion)
|
||||||
|
context.SetScissorBox(states.scissorRegion->x, states.scissorRegion->y, states.scissorRegion->width, states.scissorRegion->height);
|
||||||
|
|
||||||
|
if (states.viewportRegion)
|
||||||
|
context.SetViewport(states.viewportRegion->x, states.viewportRegion->y, states.viewportRegion->width, states.viewportRegion->height);
|
||||||
|
|
||||||
|
GL::OpenGLVaoSetup vaoSetup;
|
||||||
|
vaoSetup.indexBuffer = states.indexBuffer;
|
||||||
|
|
||||||
|
std::uint32_t locationIndex = 0;
|
||||||
|
const std::uint8_t* originPtr = 0;
|
||||||
|
|
||||||
|
for (const auto& bufferData : states.pipeline->GetPipelineInfo().vertexBuffers)
|
||||||
|
{
|
||||||
|
assert(bufferData.binding < states.vertexBuffers.size());
|
||||||
|
const auto& vertexBufferInfo = states.vertexBuffers[bufferData.binding];
|
||||||
|
|
||||||
|
GLsizei stride = GLsizei(bufferData.declaration->GetStride());
|
||||||
|
|
||||||
|
for (const auto& componentInfo : *bufferData.declaration)
|
||||||
|
{
|
||||||
|
auto& bufferAttribute = vaoSetup.vertexAttribs[locationIndex++].emplace();
|
||||||
|
BuildAttrib(bufferAttribute, componentInfo.type);
|
||||||
|
|
||||||
|
bufferAttribute.pointer = originPtr + vertexBufferInfo.offset + componentInfo.offset;
|
||||||
|
bufferAttribute.stride = stride;
|
||||||
|
bufferAttribute.vertexBuffer = vertexBufferInfo.vertexBuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const GL::VertexArray& vao = context.GetVaoCache().Get(vaoSetup);
|
||||||
|
context.BindVertexArray(vao.GetObjectId(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,12 @@
|
||||||
// This file is part of the "Nazara Engine - OpenGL Renderer"
|
// This file is part of the "Nazara Engine - OpenGL Renderer"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.hpp>
|
||||||
#include <Nazara/Core/StackArray.hpp>
|
#include <Nazara/Core/StackArray.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLBuffer.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLMultipleFramebuffer.hpp>
|
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLRenderPass.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLRenderPass.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLRenderPipeline.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLRenderPipeline.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLRenderPipelineLayout.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLRenderPipelineLayout.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLSingleFramebuffer.hpp>
|
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLShaderBinding.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLShaderBinding.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLUploadPool.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLUploadPool.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||||
|
|
@ -20,112 +16,40 @@ namespace Nz
|
||||||
{
|
{
|
||||||
void OpenGLCommandBufferBuilder::BeginDebugRegion(const std::string_view& regionName, const Nz::Color& color)
|
void OpenGLCommandBufferBuilder::BeginDebugRegion(const std::string_view& regionName, const Nz::Color& color)
|
||||||
{
|
{
|
||||||
// Ensure \0 at the end of string
|
m_commandBuffer.BeginDebugRegion(regionName, color);
|
||||||
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)
|
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);
|
m_commandBuffer.SetFramebuffer(static_cast<const OpenGLFramebuffer&>(framebuffer), renderPass, clearValues);
|
||||||
|
|
||||||
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)
|
void OpenGLCommandBufferBuilder::BindIndexBuffer(Nz::AbstractBuffer* indexBuffer, UInt64 offset)
|
||||||
{
|
{
|
||||||
OpenGLBuffer& vkBuffer = *static_cast<OpenGLBuffer*>(indexBuffer);
|
OpenGLBuffer* glBuffer = static_cast<OpenGLBuffer*>(indexBuffer);
|
||||||
|
|
||||||
m_commandBuffer.BindIndexBuffer(vkBuffer.GetBuffer(), offset, VK_INDEX_TYPE_UINT16); //< Fuck me right?
|
m_commandBuffer.BindIndexBuffer(glBuffer->GetBuffer().GetObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandBufferBuilder::BindPipeline(const RenderPipeline& pipeline)
|
void OpenGLCommandBufferBuilder::BindPipeline(const RenderPipeline& pipeline)
|
||||||
{
|
{
|
||||||
if (!m_currentRenderPass)
|
const OpenGLRenderPipeline& glPipeline = static_cast<const OpenGLRenderPipeline&>(pipeline);
|
||||||
throw std::runtime_error("BindPipeline must be called in a RenderPass");
|
|
||||||
|
|
||||||
const OpenGLRenderPipeline& vkBinding = static_cast<const OpenGLRenderPipeline&>(pipeline);
|
m_commandBuffer.BindPipeline(&glPipeline);
|
||||||
|
|
||||||
m_commandBuffer.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, vkBinding.Get(m_currentRenderPass->GetRenderPass()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandBufferBuilder::BindShaderBinding(const ShaderBinding& binding)
|
void OpenGLCommandBufferBuilder::BindShaderBinding(const ShaderBinding& binding)
|
||||||
{
|
{
|
||||||
const OpenGLShaderBinding& vkBinding = static_cast<const OpenGLShaderBinding&>(binding);
|
const OpenGLShaderBinding& glBinding = static_cast<const OpenGLShaderBinding&>(binding);
|
||||||
|
|
||||||
const OpenGLRenderPipelineLayout& pipelineLayout = vkBinding.GetOwner();
|
m_commandBuffer.BindShaderBinding(&glBinding);
|
||||||
|
|
||||||
m_commandBuffer.BindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.GetPipelineLayout(), 0U, vkBinding.GetDescriptorSet());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandBufferBuilder::BindVertexBuffer(UInt32 binding, Nz::AbstractBuffer* vertexBuffer, UInt64 offset)
|
void OpenGLCommandBufferBuilder::BindVertexBuffer(UInt32 binding, Nz::AbstractBuffer* vertexBuffer, UInt64 offset)
|
||||||
{
|
{
|
||||||
OpenGLBuffer& vkBuffer = *static_cast<OpenGLBuffer*>(vertexBuffer);
|
OpenGLBuffer* glBuffer = static_cast<OpenGLBuffer*>(vertexBuffer);
|
||||||
|
|
||||||
m_commandBuffer.BindVertexBuffer(binding, vkBuffer.GetBuffer(), offset);
|
m_commandBuffer.BindVertexBuffer(binding, glBuffer->GetBuffer().GetObjectId(), offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandBufferBuilder::CopyBuffer(const RenderBufferView& source, const RenderBufferView& target, UInt64 size, UInt64 sourceOffset, UInt64 targetOffset)
|
void OpenGLCommandBufferBuilder::CopyBuffer(const RenderBufferView& source, const RenderBufferView& target, UInt64 size, UInt64 sourceOffset, UInt64 targetOffset)
|
||||||
|
|
@ -133,15 +57,14 @@ namespace Nz
|
||||||
OpenGLBuffer& sourceBuffer = *static_cast<OpenGLBuffer*>(source.GetBuffer());
|
OpenGLBuffer& sourceBuffer = *static_cast<OpenGLBuffer*>(source.GetBuffer());
|
||||||
OpenGLBuffer& targetBuffer = *static_cast<OpenGLBuffer*>(target.GetBuffer());
|
OpenGLBuffer& targetBuffer = *static_cast<OpenGLBuffer*>(target.GetBuffer());
|
||||||
|
|
||||||
m_commandBuffer.CopyBuffer(sourceBuffer.GetBuffer(), targetBuffer.GetBuffer(), size, sourceOffset + source.GetOffset(), targetOffset + target.GetOffset());
|
m_commandBuffer.CopyBuffer(sourceBuffer.GetBuffer().GetObjectId(), targetBuffer.GetBuffer().GetObjectId(), size, sourceOffset + source.GetOffset(), targetOffset + target.GetOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandBufferBuilder::CopyBuffer(const UploadPool::Allocation& allocation, const RenderBufferView& target, UInt64 size, UInt64 sourceOffset, UInt64 targetOffset)
|
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());
|
OpenGLBuffer& targetBuffer = *static_cast<OpenGLBuffer*>(target.GetBuffer());
|
||||||
|
|
||||||
m_commandBuffer.CopyBuffer(vkAllocation.buffer, targetBuffer.GetBuffer(), size, vkAllocation.offset + sourceOffset, target.GetOffset() + targetOffset);
|
m_commandBuffer.CopyBuffer(allocation, targetBuffer.GetBuffer().GetObjectId(), size, sourceOffset, target.GetOffset() + targetOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandBufferBuilder::Draw(UInt32 vertexCount, UInt32 instanceCount, UInt32 firstVertex, UInt32 firstInstance)
|
void OpenGLCommandBufferBuilder::Draw(UInt32 vertexCount, UInt32 instanceCount, UInt32 firstVertex, UInt32 firstInstance)
|
||||||
|
|
@ -151,7 +74,7 @@ namespace Nz
|
||||||
|
|
||||||
void OpenGLCommandBufferBuilder::DrawIndexed(UInt32 indexCount, UInt32 instanceCount, UInt32 firstVertex, UInt32 firstInstance)
|
void OpenGLCommandBufferBuilder::DrawIndexed(UInt32 indexCount, UInt32 instanceCount, UInt32 firstVertex, UInt32 firstInstance)
|
||||||
{
|
{
|
||||||
m_commandBuffer.DrawIndexed(indexCount, instanceCount, firstVertex, 0, firstInstance);
|
m_commandBuffer.DrawIndexed(indexCount, instanceCount, firstVertex, firstInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandBufferBuilder::EndDebugRegion()
|
void OpenGLCommandBufferBuilder::EndDebugRegion()
|
||||||
|
|
@ -161,18 +84,14 @@ namespace Nz
|
||||||
|
|
||||||
void OpenGLCommandBufferBuilder::EndRenderPass()
|
void OpenGLCommandBufferBuilder::EndRenderPass()
|
||||||
{
|
{
|
||||||
m_commandBuffer.EndRenderPass();
|
|
||||||
m_currentRenderPass = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandBufferBuilder::PreTransferBarrier()
|
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()
|
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)
|
void OpenGLCommandBufferBuilder::SetScissor(Nz::Recti scissorRegion)
|
||||||
|
|
@ -182,8 +101,6 @@ namespace Nz
|
||||||
|
|
||||||
void OpenGLCommandBufferBuilder::SetViewport(Nz::Recti viewportRegion)
|
void OpenGLCommandBufferBuilder::SetViewport(Nz::Recti viewportRegion)
|
||||||
{
|
{
|
||||||
m_commandBuffer.SetViewport(Nz::Rectf(viewportRegion), 0.f, 1.f);
|
m_commandBuffer.SetViewport(viewportRegion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
|
|
@ -2,41 +2,20 @@
|
||||||
// This file is part of the "Nazara Engine - OpenGL Renderer"
|
// This file is part of the "Nazara Engine - OpenGL Renderer"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLCommandPool.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLCommandPool.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/Wrapper/CommandBuffer.hpp>
|
|
||||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
std::unique_ptr<CommandBuffer> OpenGLCommandPool::BuildCommandBuffer(const std::function<void(CommandBufferBuilder& builder)>& callback)
|
std::unique_ptr<CommandBuffer> OpenGLCommandPool::BuildCommandBuffer(const std::function<void(CommandBufferBuilder& builder)>& callback)
|
||||||
{
|
{
|
||||||
std::vector<Vk::AutoCommandBuffer> commandBuffers;
|
std::unique_ptr<OpenGLCommandBuffer> commandBuffer = std::make_unique<OpenGLCommandBuffer>();
|
||||||
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))
|
OpenGLCommandBufferBuilder builder(*commandBuffer);
|
||||||
throw std::runtime_error("failed to begin command buffer: " + TranslateOpenGLError(commandBuffer->GetLastErrorCode()));
|
callback(builder);
|
||||||
|
|
||||||
OpenGLCommandBufferBuilder builder(commandBuffer.Get(), imageIndex);
|
return commandBuffer;
|
||||||
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
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLRenderImage.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLRenderImage.hpp>
|
||||||
|
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
|
||||||
|
#include <Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLRenderWindow.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLRenderWindow.hpp>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||||
|
|
@ -17,6 +19,11 @@ namespace Nz
|
||||||
|
|
||||||
void OpenGLRenderImage::Execute(const std::function<void(CommandBufferBuilder& builder)>& callback, QueueTypeFlags queueTypeFlags)
|
void OpenGLRenderImage::Execute(const std::function<void(CommandBufferBuilder& builder)>& callback, QueueTypeFlags queueTypeFlags)
|
||||||
{
|
{
|
||||||
|
OpenGLCommandBuffer commandBuffer;
|
||||||
|
OpenGLCommandBufferBuilder builder(commandBuffer);
|
||||||
|
callback(builder);
|
||||||
|
|
||||||
|
commandBuffer.Execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLUploadPool& OpenGLRenderImage::GetUploadPool()
|
OpenGLUploadPool& OpenGLRenderImage::GetUploadPool()
|
||||||
|
|
@ -26,6 +33,8 @@ namespace Nz
|
||||||
|
|
||||||
void OpenGLRenderImage::SubmitCommandBuffer(CommandBuffer* commandBuffer, QueueTypeFlags queueTypeFlags)
|
void OpenGLRenderImage::SubmitCommandBuffer(CommandBuffer* commandBuffer, QueueTypeFlags queueTypeFlags)
|
||||||
{
|
{
|
||||||
|
OpenGLCommandBuffer* oglCommandBuffer = static_cast<OpenGLCommandBuffer*>(commandBuffer);
|
||||||
|
oglCommandBuffer->Execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLRenderImage::Present()
|
void OpenGLRenderImage::Present()
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,29 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
void OpenGLShaderBinding::Apply(const GL::Context& context) const
|
||||||
|
{
|
||||||
|
std::size_t textureDescriptorCount = m_owner.GetTextureDescriptorCount();
|
||||||
|
std::size_t uniformBufferDescriptorCount = m_owner.GetUniformBufferDescriptorCount();
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < textureDescriptorCount; ++i)
|
||||||
|
{
|
||||||
|
const auto& textureDescriptor = m_owner.GetTextureDescriptor(m_poolIndex, m_bindingIndex, i);
|
||||||
|
|
||||||
|
UInt32 textureIndex = textureDescriptor.bindingIndex;
|
||||||
|
|
||||||
|
context.BindSampler(textureIndex, textureDescriptor.sampler);
|
||||||
|
context.BindTexture(textureIndex, textureDescriptor.textureTarget, textureDescriptor.texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < textureDescriptorCount; ++i)
|
||||||
|
{
|
||||||
|
const auto& uboDescriptor = m_owner.GetUniformBufferDescriptor(m_poolIndex, m_bindingIndex, i);
|
||||||
|
|
||||||
|
context.BindUniformBuffer(uboDescriptor.bindingIndex, uboDescriptor.buffer, uboDescriptor.offset, uboDescriptor.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLShaderBinding::Update(std::initializer_list<Binding> bindings)
|
void OpenGLShaderBinding::Update(std::initializer_list<Binding> bindings)
|
||||||
{
|
{
|
||||||
const auto& layoutInfo = m_owner.GetLayoutInfo();
|
const auto& layoutInfo = m_owner.GetLayoutInfo();
|
||||||
|
|
@ -43,8 +66,34 @@ namespace Nz
|
||||||
OpenGLTextureSampler& glSampler = *static_cast<OpenGLTextureSampler*>(texBinding.sampler);
|
OpenGLTextureSampler& glSampler = *static_cast<OpenGLTextureSampler*>(texBinding.sampler);
|
||||||
|
|
||||||
auto& textureDescriptor = m_owner.GetTextureDescriptor(m_poolIndex, m_bindingIndex, resourceIndex);
|
auto& textureDescriptor = m_owner.GetTextureDescriptor(m_poolIndex, m_bindingIndex, resourceIndex);
|
||||||
|
textureDescriptor.bindingIndex = binding.bindingIndex;
|
||||||
|
|
||||||
textureDescriptor.texture = glTexture.GetTexture().GetObjectId();
|
textureDescriptor.texture = glTexture.GetTexture().GetObjectId();
|
||||||
textureDescriptor.sampler = glSampler.GetSampler(glTexture.GetLevelCount() > 1).GetObjectId();
|
textureDescriptor.sampler = glSampler.GetSampler(glTexture.GetLevelCount() > 1).GetObjectId();
|
||||||
|
|
||||||
|
switch (glTexture.GetType())
|
||||||
|
{
|
||||||
|
case ImageType_2D:
|
||||||
|
textureDescriptor.textureTarget = GL::TextureTarget::Target2D;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ImageType_2D_Array:
|
||||||
|
textureDescriptor.textureTarget = GL::TextureTarget::Target2D_Array;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ImageType_3D:
|
||||||
|
textureDescriptor.textureTarget = GL::TextureTarget::Target3D;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ImageType_Cubemap:
|
||||||
|
textureDescriptor.textureTarget = GL::TextureTarget::Cubemap;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ImageType_1D:
|
||||||
|
case ImageType_1D_Array:
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("unsupported texture type");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,6 +109,7 @@ namespace Nz
|
||||||
throw std::runtime_error("expected uniform buffer");
|
throw std::runtime_error("expected uniform buffer");
|
||||||
|
|
||||||
auto& uboDescriptor = m_owner.GetUniformBufferDescriptor(m_poolIndex, m_bindingIndex, resourceIndex);
|
auto& uboDescriptor = m_owner.GetUniformBufferDescriptor(m_poolIndex, m_bindingIndex, resourceIndex);
|
||||||
|
uboDescriptor.bindingIndex = binding.bindingIndex;
|
||||||
uboDescriptor.buffer = glBuffer.GetBuffer().GetObjectId();
|
uboDescriptor.buffer = glBuffer.GetBuffer().GetObjectId();
|
||||||
uboDescriptor.offset = uboBinding.offset;
|
uboDescriptor.offset = uboBinding.offset;
|
||||||
uboDescriptor.size = uboBinding.range;
|
uboDescriptor.size = uboBinding.range;
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@ namespace Nz::GL
|
||||||
m_device->NotifyContextDestruction(*this);
|
m_device->NotifyContextDestruction(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Context::BindBuffer(BufferTarget target, GLuint buffer) const
|
void Context::BindBuffer(BufferTarget target, GLuint buffer, bool force) const
|
||||||
{
|
{
|
||||||
if (m_state.bufferTargets[UnderlyingCast(target)] != buffer)
|
if (m_state.bufferTargets[UnderlyingCast(target)] != buffer || force)
|
||||||
{
|
{
|
||||||
if (!SetCurrentContext(this))
|
if (!SetCurrentContext(this))
|
||||||
throw std::runtime_error("failed to activate context");
|
throw std::runtime_error("failed to activate context");
|
||||||
|
|
@ -62,6 +62,18 @@ namespace Nz::GL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::BindProgram(GLuint program) const
|
||||||
|
{
|
||||||
|
if (m_state.boundProgram != program)
|
||||||
|
{
|
||||||
|
if (!SetCurrentContext(this))
|
||||||
|
throw std::runtime_error("failed to activate context");
|
||||||
|
|
||||||
|
glUseProgram(program);
|
||||||
|
m_state.boundProgram = program;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Context::BindSampler(UInt32 textureUnit, GLuint sampler) const
|
void Context::BindSampler(UInt32 textureUnit, GLuint sampler) const
|
||||||
{
|
{
|
||||||
if (textureUnit >= m_state.textureUnits.size())
|
if (textureUnit >= m_state.textureUnits.size())
|
||||||
|
|
@ -102,6 +114,37 @@ namespace Nz::GL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::BindUniformBuffer(UInt32 uboUnit, GLuint buffer, GLintptr offset, GLsizeiptr size) const
|
||||||
|
{
|
||||||
|
if (uboUnit >= m_state.uboUnits.size())
|
||||||
|
throw std::runtime_error("unsupported uniform buffer unit #" + std::to_string(uboUnit));
|
||||||
|
|
||||||
|
auto& unit = m_state.uboUnits[uboUnit];
|
||||||
|
if (unit.buffer != buffer || unit.offset != offset || unit.size != size)
|
||||||
|
{
|
||||||
|
if (!SetCurrentContext(this))
|
||||||
|
throw std::runtime_error("failed to activate context");
|
||||||
|
|
||||||
|
glBindBufferRange(GL_UNIFORM_BUFFER, uboUnit, buffer, offset, size);
|
||||||
|
|
||||||
|
unit.buffer = buffer;
|
||||||
|
unit.offset = offset;
|
||||||
|
unit.size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::BindVertexArray(GLuint vertexArray, bool force) const
|
||||||
|
{
|
||||||
|
if (m_state.boundVertexArray != vertexArray || force)
|
||||||
|
{
|
||||||
|
if (!SetCurrentContext(this))
|
||||||
|
throw std::runtime_error("failed to activate context");
|
||||||
|
|
||||||
|
glBindVertexArray(vertexArray);
|
||||||
|
m_state.boundVertexArray = vertexArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Context::Initialize(const ContextParams& params)
|
bool Context::Initialize(const ContextParams& params)
|
||||||
{
|
{
|
||||||
if (!Activate())
|
if (!Activate())
|
||||||
|
|
@ -220,9 +263,75 @@ namespace Nz::GL
|
||||||
assert(maxTextureUnits > 0);
|
assert(maxTextureUnits > 0);
|
||||||
m_state.textureUnits.resize(maxTextureUnits);
|
m_state.textureUnits.resize(maxTextureUnits);
|
||||||
|
|
||||||
|
GLint maxUniformBufferUnits = -1;
|
||||||
|
glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferUnits);
|
||||||
|
if (maxUniformBufferUnits < 24) //< OpenGL ES 3.0 requires at least 24 uniform buffers units
|
||||||
|
NazaraWarning("GL_MAX_UNIFORM_BUFFER_BINDINGS is " + std::to_string(maxUniformBufferUnits) + ", >= 24 expected");
|
||||||
|
|
||||||
|
assert(maxUniformBufferUnits > 0);
|
||||||
|
m_state.uboUnits.resize(maxUniformBufferUnits);
|
||||||
|
|
||||||
|
std::array<GLint, 4> res;
|
||||||
|
|
||||||
|
glGetIntegerv(GL_SCISSOR_BOX, res.data());
|
||||||
|
m_state.scissorBox = { res[0], res[1], res[2], res[3] };
|
||||||
|
|
||||||
|
glGetIntegerv(GL_VIEWPORT, res.data());
|
||||||
|
m_state.viewport = { res[0], res[1], res[2], res[3] };
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::SetCurrentTextureUnit(UInt32 textureUnit) const
|
||||||
|
{
|
||||||
|
if (m_state.currentTextureUnit != textureUnit)
|
||||||
|
{
|
||||||
|
if (!SetCurrentContext(this))
|
||||||
|
throw std::runtime_error("failed to activate context");
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0 + textureUnit);
|
||||||
|
m_state.currentTextureUnit = textureUnit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::SetScissorBox(GLint x, GLint y, GLsizei width, GLsizei height) const
|
||||||
|
{
|
||||||
|
if (m_state.scissorBox.x != x ||
|
||||||
|
m_state.scissorBox.y != y ||
|
||||||
|
m_state.scissorBox.width != width ||
|
||||||
|
m_state.scissorBox.height != height)
|
||||||
|
{
|
||||||
|
if (!SetCurrentContext(this))
|
||||||
|
throw std::runtime_error("failed to activate context");
|
||||||
|
|
||||||
|
glScissor(x, y, width, height);
|
||||||
|
|
||||||
|
m_state.scissorBox.x = x;
|
||||||
|
m_state.scissorBox.y = y;
|
||||||
|
m_state.scissorBox.width = width;
|
||||||
|
m_state.scissorBox.height = height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::SetViewport(GLint x, GLint y, GLsizei width, GLsizei height) const
|
||||||
|
{
|
||||||
|
if (m_state.viewport.x != x ||
|
||||||
|
m_state.viewport.y != y ||
|
||||||
|
m_state.viewport.width != width ||
|
||||||
|
m_state.viewport.height != height)
|
||||||
|
{
|
||||||
|
if (!SetCurrentContext(this))
|
||||||
|
throw std::runtime_error("failed to activate context");
|
||||||
|
|
||||||
|
glViewport(x, y, width, height);
|
||||||
|
|
||||||
|
m_state.viewport.x = x;
|
||||||
|
m_state.viewport.y = y;
|
||||||
|
m_state.viewport.width = width;
|
||||||
|
m_state.viewport.height = height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Context::UpdateStates(const RenderStates& renderStates) const
|
void Context::UpdateStates(const RenderStates& renderStates) const
|
||||||
{
|
{
|
||||||
if (!SetCurrentContext(this))
|
if (!SetCurrentContext(this))
|
||||||
|
|
@ -402,6 +511,11 @@ namespace Nz::GL
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::OnContextRelease()
|
||||||
|
{
|
||||||
|
m_vaoCache.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
bool Context::ImplementFallback(const std::string_view& function)
|
bool Context::ImplementFallback(const std::string_view& function)
|
||||||
{
|
{
|
||||||
const Loader& loader = GetLoader();
|
const Loader& loader = GetLoader();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue