Renderer: Working compute implementation
This commit is contained in:
committed by
Jérôme Leclercq
parent
4605eed0da
commit
fe8715f1fb
@@ -40,9 +40,10 @@ namespace Nz
|
||||
inline void BeginDebugRegion(const std::string_view& regionName, const Color& color);
|
||||
|
||||
inline void BindComputePipeline(const OpenGLComputePipeline* pipeline);
|
||||
inline void BindComputeShaderBinding(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 set, const OpenGLShaderBinding* binding);
|
||||
inline void BindIndexBuffer(GLuint indexBuffer, IndexType indexType, UInt64 offset = 0);
|
||||
inline void BindRenderPipeline(const OpenGLRenderPipeline* pipeline);
|
||||
inline void BindShaderBinding(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 set, const OpenGLShaderBinding* binding);
|
||||
inline void BindRenderShaderBinding(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 set, const OpenGLShaderBinding* binding);
|
||||
inline void BindVertexBuffer(UInt32 binding, GLuint vertexBuffer, UInt64 offset = 0);
|
||||
inline void BlitTexture(const OpenGLTexture& source, const Boxui& sourceBox, const OpenGLTexture& target, const Boxui& targetBox, SamplerFilter filter = SamplerFilter::Nearest);
|
||||
|
||||
@@ -63,6 +64,8 @@ namespace Nz
|
||||
inline std::size_t GetPoolIndex() const;
|
||||
inline const OpenGLCommandPool& GetOwner() const;
|
||||
|
||||
inline void InsertMemoryBarrier(GLbitfield barriers);
|
||||
|
||||
inline void SetFramebuffer(const OpenGLFramebuffer& framebuffer, const OpenGLRenderPass& renderPass, const CommandBufferBuilder::ClearValues* clearValues, std::size_t clearValueCount);
|
||||
inline void SetScissor(const Recti& scissorRegion);
|
||||
inline void SetViewport(const Recti& viewportRegion);
|
||||
@@ -74,7 +77,9 @@ namespace Nz
|
||||
|
||||
private:
|
||||
struct DrawStates;
|
||||
struct ShaderBindings;
|
||||
|
||||
void ApplyBindings(const GL::Context& context, const ShaderBindings& bindings);
|
||||
void ApplyStates(const GL::Context& context, const DrawStates& states);
|
||||
void Release() override;
|
||||
|
||||
@@ -123,9 +128,15 @@ namespace Nz
|
||||
UInt64 targetOffset;
|
||||
};
|
||||
|
||||
struct ShaderBindings
|
||||
{
|
||||
std::vector<std::pair<const OpenGLRenderPipelineLayout*, const OpenGLShaderBinding*>> shaderBindings;
|
||||
};
|
||||
|
||||
struct DispatchData
|
||||
{
|
||||
ComputeStates states;
|
||||
ShaderBindings bindings;
|
||||
UInt32 numGroupsX;
|
||||
UInt32 numGroupsY;
|
||||
UInt32 numGroupsZ;
|
||||
@@ -145,7 +156,6 @@ namespace Nz
|
||||
IndexType indexBufferType;
|
||||
std::optional<Recti> scissorRegion;
|
||||
std::optional<Recti> viewportRegion;
|
||||
std::vector<std::pair<const OpenGLRenderPipelineLayout*, const OpenGLShaderBinding*>> shaderBindings;
|
||||
std::vector<VertexBuffer> vertexBuffers;
|
||||
bool shouldFlipY = false;
|
||||
};
|
||||
@@ -153,6 +163,7 @@ namespace Nz
|
||||
struct DrawData
|
||||
{
|
||||
DrawStates states;
|
||||
ShaderBindings bindings;
|
||||
UInt32 firstInstance;
|
||||
UInt32 firstVertex;
|
||||
UInt32 instanceCount;
|
||||
@@ -162,6 +173,7 @@ namespace Nz
|
||||
struct DrawIndexedData
|
||||
{
|
||||
DrawStates states;
|
||||
ShaderBindings bindings;
|
||||
UInt32 firstIndex;
|
||||
UInt32 firstInstance;
|
||||
UInt32 indexCount;
|
||||
@@ -172,6 +184,11 @@ namespace Nz
|
||||
{
|
||||
};
|
||||
|
||||
struct MemoryBarrier
|
||||
{
|
||||
GLbitfield barriers;
|
||||
};
|
||||
|
||||
struct SetFrameBufferData
|
||||
{
|
||||
std::array<CommandBufferBuilder::ClearValues, 16> clearValues; //< TODO: Remove hard limit?
|
||||
@@ -189,11 +206,15 @@ namespace Nz
|
||||
DrawData,
|
||||
DrawIndexedData,
|
||||
EndDebugRegionData,
|
||||
MemoryBarrier,
|
||||
SetFrameBufferData
|
||||
>;
|
||||
|
||||
ComputeStates m_currentComputeStates;
|
||||
DrawStates m_currentDrawStates;
|
||||
ShaderBindings m_currentComputeShaderBindings;
|
||||
ShaderBindings m_currentGraphicsShaderBindings;
|
||||
std::optional<MemoryBarrier> m_pendingBarrier;
|
||||
std::size_t m_bindingIndex;
|
||||
std::size_t m_maxColorBufferCount;
|
||||
std::size_t m_poolIndex;
|
||||
|
||||
@@ -38,6 +38,14 @@ namespace Nz
|
||||
m_currentComputeStates.pipeline = pipeline;
|
||||
}
|
||||
|
||||
inline void OpenGLCommandBuffer::BindComputeShaderBinding(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 set, const OpenGLShaderBinding* binding)
|
||||
{
|
||||
if (set >= m_currentComputeShaderBindings.shaderBindings.size())
|
||||
m_currentComputeShaderBindings.shaderBindings.resize(set + 1);
|
||||
|
||||
m_currentComputeShaderBindings.shaderBindings[set] = std::make_pair(&pipelineLayout, binding);
|
||||
}
|
||||
|
||||
inline void OpenGLCommandBuffer::BindIndexBuffer(GLuint indexBuffer, IndexType indexType, UInt64 offset)
|
||||
{
|
||||
m_currentDrawStates.indexBuffer = indexBuffer;
|
||||
@@ -50,12 +58,12 @@ namespace Nz
|
||||
m_currentDrawStates.pipeline = pipeline;
|
||||
}
|
||||
|
||||
inline void OpenGLCommandBuffer::BindShaderBinding(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 set, const OpenGLShaderBinding* binding)
|
||||
inline void OpenGLCommandBuffer::BindRenderShaderBinding(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 set, const OpenGLShaderBinding* binding)
|
||||
{
|
||||
if (set >= m_currentDrawStates.shaderBindings.size())
|
||||
m_currentDrawStates.shaderBindings.resize(set + 1);
|
||||
if (set >= m_currentGraphicsShaderBindings.shaderBindings.size())
|
||||
m_currentGraphicsShaderBindings.shaderBindings.resize(set + 1);
|
||||
|
||||
m_currentDrawStates.shaderBindings[set] = std::make_pair(&pipelineLayout, binding);
|
||||
m_currentGraphicsShaderBindings.shaderBindings[set] = std::make_pair(&pipelineLayout, binding);
|
||||
}
|
||||
|
||||
inline void OpenGLCommandBuffer::BindVertexBuffer(UInt32 binding, GLuint vertexBuffer, UInt64 offset)
|
||||
@@ -124,6 +132,7 @@ namespace Nz
|
||||
throw std::runtime_error("no pipeline bound");
|
||||
|
||||
DispatchData dispatch;
|
||||
dispatch.bindings = m_currentComputeShaderBindings;
|
||||
dispatch.states = m_currentComputeStates;
|
||||
dispatch.numGroupsX = numGroupsX;
|
||||
dispatch.numGroupsY = numGroupsY;
|
||||
@@ -138,6 +147,7 @@ namespace Nz
|
||||
throw std::runtime_error("no pipeline bound");
|
||||
|
||||
DrawData draw;
|
||||
draw.bindings = m_currentGraphicsShaderBindings;
|
||||
draw.states = m_currentDrawStates;
|
||||
draw.firstInstance = firstInstance;
|
||||
draw.firstVertex = firstVertex;
|
||||
@@ -153,6 +163,7 @@ namespace Nz
|
||||
throw std::runtime_error("no pipeline bound");
|
||||
|
||||
DrawIndexedData draw;
|
||||
draw.bindings = m_currentGraphicsShaderBindings;
|
||||
draw.states = m_currentDrawStates;
|
||||
draw.firstIndex = firstIndex;
|
||||
draw.firstInstance = firstInstance;
|
||||
@@ -183,6 +194,23 @@ namespace Nz
|
||||
return *m_owner;
|
||||
}
|
||||
|
||||
inline void OpenGLCommandBuffer::InsertMemoryBarrier(GLbitfield barriers)
|
||||
{
|
||||
// Merge with previous barrier, if any (may happen because memory barriers are not relative to a texture with OpenGL)
|
||||
if (!m_commands.empty() && std::holds_alternative<MemoryBarrier>(m_commands.back()))
|
||||
{
|
||||
MemoryBarrier& memBarrier = std::get<MemoryBarrier>(m_commands.back());
|
||||
memBarrier.barriers |= barriers;
|
||||
}
|
||||
else
|
||||
{
|
||||
MemoryBarrier memBarrier;
|
||||
memBarrier.barriers = barriers;
|
||||
|
||||
m_commands.emplace_back(std::move(memBarrier));
|
||||
}
|
||||
}
|
||||
|
||||
inline void OpenGLCommandBuffer::SetFramebuffer(const OpenGLFramebuffer& framebuffer, const OpenGLRenderPass& renderPass, const CommandBufferBuilder::ClearValues* clearValues, std::size_t clearValueCount)
|
||||
{
|
||||
m_maxColorBufferCount = std::max(m_maxColorBufferCount, framebuffer.GetColorBufferCount());
|
||||
|
||||
@@ -28,10 +28,12 @@ namespace Nz
|
||||
void BeginRenderPass(const Framebuffer& framebuffer, const RenderPass& renderPass, const Recti& renderRect, const ClearValues* clearValues, std::size_t clearValueCount) override;
|
||||
|
||||
void BindComputePipeline(const ComputePipeline& pipeline) override;
|
||||
void BindComputeShaderBinding(UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindComputeShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset = 0) override;
|
||||
void BindRenderPipeline(const RenderPipeline& pipeline) override;
|
||||
void BindShaderBinding(UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindRenderShaderBinding(UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindRenderShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindVertexBuffer(UInt32 binding, const RenderBuffer& vertexBuffer, UInt64 offset = 0) override;
|
||||
|
||||
void BlitTexture(const Texture& fromTexture, const Boxui& fromBox, TextureLayout fromLayout, const Texture& toTexture, const Boxui& toBox, TextureLayout toLayout, SamplerFilter filter) override;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_OPENGLRENDERER_API OpenGLTexture : public Texture
|
||||
class NAZARA_OPENGLRENDERER_API OpenGLTexture final : public Texture
|
||||
{
|
||||
public:
|
||||
OpenGLTexture(OpenGLDevice& device, const TextureInfo& textureInfo);
|
||||
@@ -28,13 +28,14 @@ namespace Nz
|
||||
bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos) override;
|
||||
std::shared_ptr<Texture> CreateView(const TextureViewInfo& viewInfo) override;
|
||||
|
||||
PixelFormat GetFormat() const override;
|
||||
UInt8 GetLevelCount() const override;
|
||||
OpenGLTexture* GetParentTexture() const override;
|
||||
Vector3ui GetSize(UInt8 level = 0) const override;
|
||||
inline PixelFormat GetFormat() const override;
|
||||
inline UInt8 GetLevelCount() const override;
|
||||
inline OpenGLTexture* GetParentTexture() const override;
|
||||
inline Vector3ui GetSize(UInt8 level = 0) const override;
|
||||
inline const GL::Texture& GetTexture() const;
|
||||
inline const TextureInfo& GetTextureInfo() const override;
|
||||
inline const TextureViewInfo& GetTextureViewInfo() const;
|
||||
ImageType GetType() const override;
|
||||
inline ImageType GetType() const override;
|
||||
|
||||
inline bool RequiresTextureViewEmulation() const;
|
||||
|
||||
|
||||
@@ -8,17 +8,47 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline PixelFormat OpenGLTexture::GetFormat() const
|
||||
{
|
||||
return m_textureInfo.pixelFormat;
|
||||
}
|
||||
|
||||
inline UInt8 OpenGLTexture::GetLevelCount() const
|
||||
{
|
||||
return m_textureInfo.levelCount;
|
||||
}
|
||||
|
||||
inline OpenGLTexture* OpenGLTexture::GetParentTexture() const
|
||||
{
|
||||
return m_parentTexture.get();
|
||||
}
|
||||
|
||||
inline Vector3ui OpenGLTexture::GetSize(UInt8 level) const
|
||||
{
|
||||
return Vector3ui(GetLevelSize(m_textureInfo.width, level), GetLevelSize(m_textureInfo.height, level), GetLevelSize(m_textureInfo.depth, level));
|
||||
}
|
||||
|
||||
inline const GL::Texture& OpenGLTexture::GetTexture() const
|
||||
{
|
||||
return m_texture;
|
||||
}
|
||||
|
||||
inline const TextureInfo& OpenGLTexture::GetTextureInfo() const
|
||||
{
|
||||
return m_textureInfo;
|
||||
}
|
||||
|
||||
inline const TextureViewInfo& OpenGLTexture::GetTextureViewInfo() const
|
||||
{
|
||||
assert(m_viewInfo);
|
||||
return *m_viewInfo;
|
||||
}
|
||||
|
||||
inline ImageType OpenGLTexture::GetType() const
|
||||
{
|
||||
return m_textureInfo.type;
|
||||
}
|
||||
|
||||
inline bool OpenGLTexture::RequiresTextureViewEmulation() const
|
||||
{
|
||||
return m_viewInfo.has_value() && !m_texture.IsValid();
|
||||
|
||||
Reference in New Issue
Block a user