Renderer: Implement renderpass attachments clear for OpenGL
This commit is contained in:
parent
392a23eeb1
commit
299585a7de
|
|
@ -24,6 +24,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
class OpenGLCommandPool;
|
class OpenGLCommandPool;
|
||||||
class OpenGLFramebuffer;
|
class OpenGLFramebuffer;
|
||||||
|
class OpenGLRenderPass;
|
||||||
|
|
||||||
class NAZARA_OPENGLRENDERER_API OpenGLCommandBuffer final : public CommandBuffer
|
class NAZARA_OPENGLRENDERER_API OpenGLCommandBuffer final : public CommandBuffer
|
||||||
{
|
{
|
||||||
|
|
@ -55,7 +56,7 @@ namespace Nz
|
||||||
inline std::size_t GetPoolIndex() const;
|
inline std::size_t GetPoolIndex() const;
|
||||||
inline const OpenGLCommandPool& GetOwner() const;
|
inline const OpenGLCommandPool& GetOwner() const;
|
||||||
|
|
||||||
inline void SetFramebuffer(const OpenGLFramebuffer& framebuffer, const RenderPass& renderPass, const CommandBufferBuilder::ClearValues* clearValues, std::size_t clearValueCount);
|
inline void SetFramebuffer(const OpenGLFramebuffer& framebuffer, const OpenGLRenderPass& renderPass, const CommandBufferBuilder::ClearValues* clearValues, std::size_t clearValueCount);
|
||||||
inline void SetScissor(Nz::Recti scissorRegion);
|
inline void SetScissor(Nz::Recti scissorRegion);
|
||||||
inline void SetViewport(Nz::Recti viewportRegion);
|
inline void SetViewport(Nz::Recti viewportRegion);
|
||||||
|
|
||||||
|
|
@ -103,8 +104,8 @@ namespace Nz
|
||||||
const OpenGLRenderPipeline* pipeline = nullptr;
|
const OpenGLRenderPipeline* pipeline = nullptr;
|
||||||
const OpenGLShaderBinding* shaderBindings = nullptr;
|
const OpenGLShaderBinding* shaderBindings = nullptr;
|
||||||
UInt64 indexBufferOffset;
|
UInt64 indexBufferOffset;
|
||||||
std::optional<Nz::Recti> scissorRegion;
|
std::optional<Recti> scissorRegion;
|
||||||
std::optional<Nz::Recti> viewportRegion;
|
std::optional<Recti> viewportRegion;
|
||||||
std::vector<VertexBuffer> vertexBuffers;
|
std::vector<VertexBuffer> vertexBuffers;
|
||||||
bool shouldFlipY = false;
|
bool shouldFlipY = false;
|
||||||
};
|
};
|
||||||
|
|
@ -135,6 +136,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
std::array<CommandBufferBuilder::ClearValues, 16> clearValues; //< TODO: Remove hard limit?
|
std::array<CommandBufferBuilder::ClearValues, 16> clearValues; //< TODO: Remove hard limit?
|
||||||
const OpenGLFramebuffer* framebuffer;
|
const OpenGLFramebuffer* framebuffer;
|
||||||
|
const OpenGLRenderPass* renderpass;
|
||||||
};
|
};
|
||||||
|
|
||||||
using CommandData = std::variant<
|
using CommandData = std::variant<
|
||||||
|
|
|
||||||
|
|
@ -135,12 +135,13 @@ namespace Nz
|
||||||
return *m_owner;
|
return *m_owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void OpenGLCommandBuffer::SetFramebuffer(const OpenGLFramebuffer& framebuffer, const RenderPass& /*renderPass*/, const CommandBufferBuilder::ClearValues* clearValues, std::size_t clearValueCount)
|
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());
|
m_maxColorBufferCount = std::max(m_maxColorBufferCount, framebuffer.GetColorBufferCount());
|
||||||
|
|
||||||
SetFrameBufferData setFramebuffer;
|
SetFrameBufferData setFramebuffer;
|
||||||
setFramebuffer.framebuffer = &framebuffer;
|
setFramebuffer.framebuffer = &framebuffer;
|
||||||
|
setFramebuffer.renderpass = &renderPass;
|
||||||
|
|
||||||
assert(clearValueCount < setFramebuffer.clearValues.size());
|
assert(clearValueCount < setFramebuffer.clearValues.size());
|
||||||
std::copy(clearValues, clearValues + clearValueCount, setFramebuffer.clearValues.begin());
|
std::copy(clearValues, clearValues + clearValueCount, setFramebuffer.clearValues.begin());
|
||||||
|
|
|
||||||
|
|
@ -40,10 +40,10 @@ namespace Nz
|
||||||
void Present();
|
void Present();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::optional<OpenGLRenderPass> m_renderPass;
|
||||||
std::size_t m_currentFrame;
|
std::size_t m_currentFrame;
|
||||||
std::vector<std::unique_ptr<OpenGLRenderImage>> m_renderImage;
|
std::vector<std::unique_ptr<OpenGLRenderImage>> m_renderImage;
|
||||||
std::unique_ptr<GL::Context> m_context;
|
std::unique_ptr<GL::Context> m_context;
|
||||||
OpenGLRenderPass m_renderPass;
|
|
||||||
OpenGLWindowFramebuffer m_framebuffer;
|
OpenGLWindowFramebuffer m_framebuffer;
|
||||||
RenderWindow& m_owner;
|
RenderWindow& m_owner;
|
||||||
Vector2ui m_size;
|
Vector2ui m_size;
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,10 @@ namespace Nz::GL
|
||||||
|
|
||||||
bool ProcessErrorStack() const;
|
bool ProcessErrorStack() const;
|
||||||
|
|
||||||
|
inline void ResetColorWriteMasks() const;
|
||||||
|
inline void ResetDepthWriteMasks() const;
|
||||||
|
inline void ResetStencilWriteMasks() const;
|
||||||
|
|
||||||
void SetCurrentTextureUnit(UInt32 textureUnit) const;
|
void SetCurrentTextureUnit(UInt32 textureUnit) const;
|
||||||
void SetScissorBox(GLint x, GLint y, GLsizei width, GLsizei height) const;
|
void SetScissorBox(GLint x, GLint y, GLsizei width, GLsizei height) const;
|
||||||
void SetViewport(GLint x, GLint y, GLsizei width, GLsizei height) const;
|
void SetViewport(GLint x, GLint y, GLsizei width, GLsizei height) const;
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,35 @@ namespace Nz::GL
|
||||||
if (m_state.boundVertexArray == vao)
|
if (m_state.boundVertexArray == vao)
|
||||||
m_state.boundVertexArray = 0;
|
m_state.boundVertexArray = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Context::ResetColorWriteMasks() const
|
||||||
|
{
|
||||||
|
if (!m_state.renderStates.colorWrite)
|
||||||
|
{
|
||||||
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
m_state.renderStates.colorWrite = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Context::ResetDepthWriteMasks() const
|
||||||
|
{
|
||||||
|
if (!m_state.renderStates.depthWrite)
|
||||||
|
{
|
||||||
|
glDepthMask(GL_TRUE);
|
||||||
|
m_state.renderStates.depthWrite = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Context::ResetStencilWriteMasks() const
|
||||||
|
{
|
||||||
|
if (m_state.renderStates.stencilBack.writeMask != 0xFFFFFFFF || m_state.renderStates.stencilFront.writeMask != 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
glStencilMaskSeparate(GL_FRONT_AND_BACK, 0xFFFFFFFF);
|
||||||
|
m_state.renderStates.stencilBack.writeMask = 0xFFFFFFFF;
|
||||||
|
m_state.renderStates.stencilFront.writeMask = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Nazara/OpenGLRenderer/DebugOff.hpp>
|
#include <Nazara/OpenGLRenderer/DebugOff.hpp>
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,7 @@ typedef void (GL_APIENTRYP PFNGLSPECIALIZESHADERARBPROC) (GLuint shader, const G
|
||||||
cb(glStencilFuncSeparate, PFNGLSTENCILFUNCSEPARATEPROC) \
|
cb(glStencilFuncSeparate, PFNGLSTENCILFUNCSEPARATEPROC) \
|
||||||
cb(glStencilOp, PFNGLSTENCILOPPROC) \
|
cb(glStencilOp, PFNGLSTENCILOPPROC) \
|
||||||
cb(glStencilOpSeparate, PFNGLSTENCILOPSEPARATEPROC) \
|
cb(glStencilOpSeparate, PFNGLSTENCILOPSEPARATEPROC) \
|
||||||
|
cb(glStencilMaskSeparate, PFNGLSTENCILMASKSEPARATEPROC) \
|
||||||
cb(glTexImage2D, PFNGLTEXIMAGE2DPROC) \
|
cb(glTexImage2D, PFNGLTEXIMAGE2DPROC) \
|
||||||
cb(glTexImage3D, PFNGLTEXIMAGE3DPROC) \
|
cb(glTexImage3D, PFNGLTEXIMAGE3DPROC) \
|
||||||
cb(glTexParameterf, PFNGLTEXPARAMETERFPROC) \
|
cb(glTexParameterf, PFNGLTEXPARAMETERFPROC) \
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,9 @@
|
||||||
#include <Nazara/Renderer/Config.hpp>
|
#include <Nazara/Renderer/Config.hpp>
|
||||||
#include <Nazara/Renderer/RenderDevice.hpp>
|
#include <Nazara/Renderer/RenderDevice.hpp>
|
||||||
#include <Nazara/Renderer/RenderFrame.hpp>
|
#include <Nazara/Renderer/RenderFrame.hpp>
|
||||||
|
#include <Nazara/Renderer/RenderPass.hpp>
|
||||||
#include <Nazara/Renderer/RenderWindowParameters.hpp>
|
#include <Nazara/Renderer/RenderWindowParameters.hpp>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
|
@ -21,7 +23,6 @@ namespace Nz
|
||||||
class Framebuffer;
|
class Framebuffer;
|
||||||
class RendererImpl;
|
class RendererImpl;
|
||||||
class RenderDevice;
|
class RenderDevice;
|
||||||
class RenderPass;
|
|
||||||
class RenderSurface;
|
class RenderSurface;
|
||||||
|
|
||||||
class NAZARA_RENDERER_API RenderWindowImpl
|
class NAZARA_RENDERER_API RenderWindowImpl
|
||||||
|
|
@ -37,6 +38,9 @@ namespace Nz
|
||||||
|
|
||||||
virtual const Framebuffer& GetFramebuffer() const = 0;
|
virtual const Framebuffer& GetFramebuffer() const = 0;
|
||||||
virtual const RenderPass& GetRenderPass() const = 0;
|
virtual const RenderPass& GetRenderPass() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void BuildRenderPass(PixelFormat colorFormat, PixelFormat depthFormat, std::vector<RenderPass::Attachment>& attachments, std::vector<RenderPass::SubpassDescription>& subpassDescriptions, std::vector<RenderPass::SubpassDependency>& subpassDependencies);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
struct RenderWindowParameters
|
struct RenderWindowParameters
|
||||||
{
|
{
|
||||||
std::vector<PixelFormat> depthFormats = {Nz::PixelFormat::Depth32, Nz::PixelFormat::Depth24}; //< By order of preference
|
std::vector<PixelFormat> depthFormats = {Nz::PixelFormat::Depth24Stencil8, Nz::PixelFormat::Depth32, Nz::PixelFormat::Depth24}; //< By order of preference
|
||||||
bool verticalSync = false;
|
bool verticalSync = false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
|
||||||
#include <Nazara/Core/StackArray.hpp>
|
#include <Nazara/Core/StackArray.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLCommandPool.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLCommandPool.hpp>
|
||||||
|
#include <Nazara/OpenGLRenderer/OpenGLRenderPass.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLVaoCache.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLVaoCache.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/Wrapper/Context.hpp>
|
#include <Nazara/OpenGLRenderer/Wrapper/Context.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/Wrapper/VertexArray.hpp>
|
#include <Nazara/OpenGLRenderer/Wrapper/VertexArray.hpp>
|
||||||
|
|
@ -62,6 +63,8 @@ namespace Nz
|
||||||
for (std::size_t i = 0; i < m_maxColorBufferCount; ++i)
|
for (std::size_t i = 0; i < m_maxColorBufferCount; ++i)
|
||||||
fboDrawBuffers[i] = GLenum(GL_COLOR_ATTACHMENT0 + i);
|
fboDrawBuffers[i] = GLenum(GL_COLOR_ATTACHMENT0 + i);
|
||||||
|
|
||||||
|
StackArray<std::size_t> colorIndexes = NazaraStackArrayNoInit(std::size_t, m_maxColorBufferCount);
|
||||||
|
|
||||||
for (const auto& commandVariant : m_commands)
|
for (const auto& commandVariant : m_commands)
|
||||||
{
|
{
|
||||||
std::visit([&](auto&& command)
|
std::visit([&](auto&& command)
|
||||||
|
|
@ -105,33 +108,128 @@ namespace Nz
|
||||||
|
|
||||||
context = GL::Context::GetCurrentContext();
|
context = GL::Context::GetCurrentContext();
|
||||||
|
|
||||||
|
std::size_t colorBufferCount = command.framebuffer->GetColorBufferCount();
|
||||||
|
assert(colorBufferCount <= fboDrawBuffers.size());
|
||||||
|
|
||||||
|
colorIndexes.fill(0);
|
||||||
|
std::size_t colorIndex = 0;
|
||||||
|
|
||||||
|
GLbitfield clearFields = 0;
|
||||||
|
std::optional<std::size_t> depthStencilIndex;
|
||||||
|
|
||||||
|
std::size_t attachmentCount = command.renderpass->GetAttachmentCount();
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < attachmentCount; ++i)
|
||||||
|
{
|
||||||
|
const auto& attachmentInfo = command.renderpass->GetAttachment(i);
|
||||||
|
switch (PixelFormatInfo::GetContent(attachmentInfo.format))
|
||||||
|
{
|
||||||
|
case PixelFormatContent::ColorRGBA:
|
||||||
|
colorIndexes[colorIndex++] = i;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PixelFormatContent::Depth:
|
||||||
|
if (!depthStencilIndex)
|
||||||
|
depthStencilIndex = i;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PixelFormatContent::DepthStencil:
|
||||||
|
if (!depthStencilIndex)
|
||||||
|
depthStencilIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (command.framebuffer->GetType() == OpenGLFramebuffer::Type::FBO)
|
if (command.framebuffer->GetType() == OpenGLFramebuffer::Type::FBO)
|
||||||
{
|
{
|
||||||
std::size_t colorBufferCount = command.framebuffer->GetColorBufferCount();
|
|
||||||
assert(colorBufferCount <= fboDrawBuffers.size());
|
|
||||||
|
|
||||||
context->glDrawBuffers(GLsizei(colorBufferCount), fboDrawBuffers.data());
|
context->glDrawBuffers(GLsizei(colorBufferCount), fboDrawBuffers.data());
|
||||||
|
|
||||||
//FIXME: Don't clear when not needed
|
|
||||||
for (std::size_t i = 0; i < colorBufferCount; ++i)
|
for (std::size_t i = 0; i < colorBufferCount; ++i)
|
||||||
{
|
{
|
||||||
Nz::Color color = command.clearValues[i].color;
|
std::size_t attachmentIndex = colorIndexes[i];
|
||||||
|
|
||||||
|
Nz::Color color = command.clearValues[attachmentIndex].color;
|
||||||
std::array<GLfloat, 4> clearColor = { color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f };
|
std::array<GLfloat, 4> clearColor = { color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f };
|
||||||
|
|
||||||
context->glClearBufferfv(GL_COLOR, GLint(i), clearColor.data());
|
const auto& attachmentInfo = command.renderpass->GetAttachment(attachmentIndex);
|
||||||
|
if (attachmentInfo.loadOp == AttachmentLoadOp::Clear)
|
||||||
|
{
|
||||||
|
context->ResetColorWriteMasks();
|
||||||
|
context->glClearBufferfv(GL_COLOR, GLint(i), clearColor.data());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context->glClear(GL_DEPTH_BUFFER_BIT);
|
if (depthStencilIndex)
|
||||||
|
{
|
||||||
|
std::size_t attachmentIndex = *depthStencilIndex;
|
||||||
|
const auto& clearValues = command.clearValues[attachmentIndex];
|
||||||
|
|
||||||
|
const auto& depthStencilAttachment = command.renderpass->GetAttachment(attachmentIndex);
|
||||||
|
if (depthStencilAttachment.loadOp == AttachmentLoadOp::Clear && depthStencilAttachment.stencilLoadOp == AttachmentLoadOp::Clear)
|
||||||
|
{
|
||||||
|
context->ResetDepthWriteMasks();
|
||||||
|
context->ResetStencilWriteMasks();
|
||||||
|
context->glClearBufferfi(GL_DEPTH_STENCIL, 0, clearValues.depth, clearValues.stencil);
|
||||||
|
}
|
||||||
|
else if (depthStencilAttachment.loadOp == AttachmentLoadOp::Clear)
|
||||||
|
{
|
||||||
|
context->ResetDepthWriteMasks();
|
||||||
|
context->glClearBufferfv(GL_DEPTH, 0, &clearValues.depth);
|
||||||
|
}
|
||||||
|
else if (depthStencilAttachment.stencilLoadOp == AttachmentLoadOp::Clear)
|
||||||
|
{
|
||||||
|
context->ResetStencilWriteMasks();
|
||||||
|
context->glClearBufferuiv(GL_STENCIL, 0, &clearValues.stencil);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GLenum buffer = GL_BACK;
|
GLenum buffer = GL_BACK;
|
||||||
context->glDrawBuffers(1, &buffer);
|
context->glDrawBuffers(1, &buffer);
|
||||||
|
|
||||||
//FIXME: Don't clear when not needed
|
if (colorIndex > 0)
|
||||||
Nz::Color color = command.clearValues[0].color;
|
{
|
||||||
context->glClearColor(color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f);
|
std::size_t colorBufferCount = command.framebuffer->GetColorBufferCount();
|
||||||
context->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
assert(colorBufferCount <= 1);
|
||||||
|
|
||||||
|
std::size_t colorAttachmentIndex = colorIndexes.front();
|
||||||
|
|
||||||
|
const auto& colorAttachment = command.renderpass->GetAttachment(colorAttachmentIndex);
|
||||||
|
if (colorAttachment.loadOp == AttachmentLoadOp::Clear)
|
||||||
|
{
|
||||||
|
context->ResetColorWriteMasks();
|
||||||
|
|
||||||
|
Nz::Color color = command.clearValues[colorAttachmentIndex].color;
|
||||||
|
context->glClearColor(color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f);
|
||||||
|
|
||||||
|
clearFields |= GL_COLOR_BUFFER_BIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depthStencilIndex)
|
||||||
|
{
|
||||||
|
std::size_t attachmentIndex = *depthStencilIndex;
|
||||||
|
const auto& clearValues = command.clearValues[attachmentIndex];
|
||||||
|
|
||||||
|
const auto& depthStencilAttachment = command.renderpass->GetAttachment(attachmentIndex);
|
||||||
|
if (depthStencilAttachment.loadOp == AttachmentLoadOp::Clear)
|
||||||
|
{
|
||||||
|
context->ResetDepthWriteMasks();
|
||||||
|
context->glClearDepthf(clearValues.depth);
|
||||||
|
clearFields |= GL_DEPTH_BUFFER_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depthStencilAttachment.stencilLoadOp == AttachmentLoadOp::Clear && PixelFormatInfo::GetContent(depthStencilAttachment.format) == PixelFormatContent::DepthStencil)
|
||||||
|
{
|
||||||
|
context->ResetStencilWriteMasks();
|
||||||
|
context->glClearStencil(clearValues.stencil);
|
||||||
|
clearFields |= GL_STENCIL_BUFFER_BIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clearFields)
|
||||||
|
context->glClear(clearFields);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Nz
|
||||||
|
|
||||||
void OpenGLCommandBufferBuilder::BeginRenderPass(const Framebuffer& framebuffer, const RenderPass& renderPass, Nz::Recti /*renderRect*/, const ClearValues* clearValues, std::size_t clearValueCount)
|
void OpenGLCommandBufferBuilder::BeginRenderPass(const Framebuffer& framebuffer, const RenderPass& renderPass, Nz::Recti /*renderRect*/, const ClearValues* clearValues, std::size_t clearValueCount)
|
||||||
{
|
{
|
||||||
m_commandBuffer.SetFramebuffer(static_cast<const OpenGLFramebuffer&>(framebuffer), renderPass, clearValues, clearValueCount);
|
m_commandBuffer.SetFramebuffer(static_cast<const OpenGLFramebuffer&>(framebuffer), static_cast<const OpenGLRenderPass&>(renderPass), clearValues, clearValueCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandBufferBuilder::BindIndexBuffer(Nz::AbstractBuffer* indexBuffer, UInt64 offset)
|
void OpenGLCommandBufferBuilder::BindIndexBuffer(Nz::AbstractBuffer* indexBuffer, UInt64 offset)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ namespace Nz
|
||||||
{
|
{
|
||||||
OpenGLRenderWindow::OpenGLRenderWindow(RenderWindow& owner) :
|
OpenGLRenderWindow::OpenGLRenderWindow(RenderWindow& owner) :
|
||||||
m_currentFrame(0),
|
m_currentFrame(0),
|
||||||
m_renderPass({}, {}, {}),
|
|
||||||
m_framebuffer(*this),
|
m_framebuffer(*this),
|
||||||
m_owner(owner)
|
m_owner(owner)
|
||||||
{
|
{
|
||||||
|
|
@ -51,6 +50,40 @@ namespace Nz
|
||||||
|
|
||||||
m_size = m_owner.GetSize();
|
m_size = m_owner.GetSize();
|
||||||
|
|
||||||
|
// TODO: extract the exact window pixel format
|
||||||
|
PixelFormat colorFormat;
|
||||||
|
switch (contextParams.bitsPerPixel)
|
||||||
|
{
|
||||||
|
case 8: colorFormat = PixelFormat::R8; break;
|
||||||
|
case 16: colorFormat = PixelFormat::RG8; break;
|
||||||
|
case 24: colorFormat = PixelFormat::RGB8; break;
|
||||||
|
|
||||||
|
case 32:
|
||||||
|
default:
|
||||||
|
colorFormat = PixelFormat::RGBA8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: extract the exact depth-stencil format
|
||||||
|
PixelFormat depthFormat;
|
||||||
|
if (contextParams.stencilBits > 0)
|
||||||
|
depthFormat = PixelFormat::Depth24Stencil8;
|
||||||
|
else if (contextParams.depthBits > 24)
|
||||||
|
depthFormat = PixelFormat::Depth32;
|
||||||
|
else if (contextParams.depthBits > 16)
|
||||||
|
depthFormat = PixelFormat::Depth24;
|
||||||
|
else if (contextParams.depthBits > 0)
|
||||||
|
depthFormat = PixelFormat::Depth16;
|
||||||
|
else
|
||||||
|
depthFormat = PixelFormat::Undefined;
|
||||||
|
|
||||||
|
std::vector<RenderPass::Attachment> attachments;
|
||||||
|
std::vector<RenderPass::SubpassDescription> subpassDescriptions;
|
||||||
|
std::vector<RenderPass::SubpassDependency> subpassDependencies;
|
||||||
|
|
||||||
|
BuildRenderPass(colorFormat, depthFormat, attachments, subpassDescriptions, subpassDependencies);
|
||||||
|
m_renderPass.emplace(std::move(attachments), std::move(subpassDescriptions), std::move(subpassDependencies));
|
||||||
|
|
||||||
constexpr std::size_t RenderImageCount = 2;
|
constexpr std::size_t RenderImageCount = 2;
|
||||||
|
|
||||||
m_renderImage.reserve(RenderImageCount);
|
m_renderImage.reserve(RenderImageCount);
|
||||||
|
|
@ -72,7 +105,7 @@ namespace Nz
|
||||||
|
|
||||||
const OpenGLRenderPass& OpenGLRenderWindow::GetRenderPass() const
|
const OpenGLRenderPass& OpenGLRenderWindow::GetRenderPass() const
|
||||||
{
|
{
|
||||||
return m_renderPass;
|
return *m_renderPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLRenderWindow::Present()
|
void OpenGLRenderWindow::Present()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#include <Nazara/Renderer/RenderWindowImpl.hpp>
|
||||||
|
#include <Nazara/Renderer/Debug.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
RenderWindowImpl::~RenderWindowImpl() = default;
|
||||||
|
|
||||||
|
void RenderWindowImpl::BuildRenderPass(PixelFormat colorFormat, PixelFormat depthFormat, std::vector<RenderPass::Attachment>& attachments, std::vector<RenderPass::SubpassDescription>& subpassDescriptions, std::vector<RenderPass::SubpassDependency>& subpassDependencies)
|
||||||
|
{
|
||||||
|
assert(colorFormat != PixelFormat::Undefined);
|
||||||
|
|
||||||
|
attachments.push_back({
|
||||||
|
colorFormat,
|
||||||
|
AttachmentLoadOp::Clear,
|
||||||
|
AttachmentLoadOp::Discard,
|
||||||
|
AttachmentStoreOp::Store,
|
||||||
|
AttachmentStoreOp::Discard,
|
||||||
|
TextureLayout::Undefined,
|
||||||
|
TextureLayout::Present
|
||||||
|
});
|
||||||
|
|
||||||
|
RenderPass::AttachmentReference colorReference = {
|
||||||
|
0,
|
||||||
|
TextureLayout::ColorOutput
|
||||||
|
};
|
||||||
|
|
||||||
|
subpassDescriptions.push_back(
|
||||||
|
{
|
||||||
|
{ colorReference },
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
std::nullopt
|
||||||
|
});
|
||||||
|
|
||||||
|
subpassDependencies.push_back({
|
||||||
|
RenderPass::ExternalSubpassIndex,
|
||||||
|
PipelineStage::ColorOutput,
|
||||||
|
{},
|
||||||
|
|
||||||
|
0,
|
||||||
|
PipelineStage::ColorOutput,
|
||||||
|
MemoryAccess::ColorWrite,
|
||||||
|
|
||||||
|
true //< tilable
|
||||||
|
});
|
||||||
|
|
||||||
|
if (depthFormat != PixelFormat::Undefined)
|
||||||
|
{
|
||||||
|
attachments.push_back({
|
||||||
|
depthFormat,
|
||||||
|
AttachmentLoadOp::Clear,
|
||||||
|
AttachmentLoadOp::Discard,
|
||||||
|
AttachmentStoreOp::Discard,
|
||||||
|
AttachmentStoreOp::Discard,
|
||||||
|
TextureLayout::Undefined,
|
||||||
|
TextureLayout::DepthStencilReadWrite
|
||||||
|
});
|
||||||
|
|
||||||
|
subpassDescriptions.front().depthStencilAttachment = RenderPass::AttachmentReference{
|
||||||
|
1,
|
||||||
|
TextureLayout::DepthStencilReadWrite
|
||||||
|
};
|
||||||
|
|
||||||
|
auto& subpassDependency = subpassDependencies.front();
|
||||||
|
subpassDependency.fromStages |= PipelineStage::FragmentTestsEarly;
|
||||||
|
subpassDependency.toStages |= PipelineStage::FragmentTestsEarly;
|
||||||
|
subpassDependency.toAccessFlags |= MemoryAccess::DepthStencilWrite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
// 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
|
|
||||||
|
|
||||||
#include <Nazara/Renderer/RenderWindowImpl.hpp>
|
|
||||||
#include <Nazara/Renderer/Debug.hpp>
|
|
||||||
|
|
||||||
namespace Nz
|
|
||||||
{
|
|
||||||
RenderWindowImpl::~RenderWindowImpl() = default;
|
|
||||||
}
|
|
||||||
|
|
@ -350,7 +350,7 @@ namespace Nz
|
||||||
VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle .a;
|
VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle .a;
|
||||||
},
|
},
|
||||||
{ // VkImageSubresourceRange subresourceRange;
|
{ // VkImageSubresourceRange subresourceRange;
|
||||||
VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags .aspectMask;
|
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags .aspectMask;
|
||||||
0, // uint32_t .baseMipLevel;
|
0, // uint32_t .baseMipLevel;
|
||||||
1, // uint32_t .levelCount;
|
1, // uint32_t .levelCount;
|
||||||
0, // uint32_t .baseArrayLayer;
|
0, // uint32_t .baseArrayLayer;
|
||||||
|
|
@ -408,78 +408,23 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<RenderPass::Attachment> attachments;
|
std::optional<PixelFormat> depthStencilFormat;
|
||||||
attachments.push_back({
|
|
||||||
*colorFormat,
|
|
||||||
AttachmentLoadOp::Clear,
|
|
||||||
AttachmentLoadOp::Discard,
|
|
||||||
AttachmentStoreOp::Store,
|
|
||||||
AttachmentStoreOp::Discard,
|
|
||||||
TextureLayout::Undefined,
|
|
||||||
TextureLayout::Present
|
|
||||||
});
|
|
||||||
|
|
||||||
RenderPass::AttachmentReference colorReference = {
|
|
||||||
0,
|
|
||||||
TextureLayout::ColorOutput
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<RenderPass::SubpassDescription> subpasses = {
|
|
||||||
{
|
|
||||||
{
|
|
||||||
{ colorReference },
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
std::nullopt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<RenderPass::SubpassDependency> subpassDependencies = {
|
|
||||||
{
|
|
||||||
RenderPass::ExternalSubpassIndex,
|
|
||||||
PipelineStage::ColorOutput,
|
|
||||||
{},
|
|
||||||
|
|
||||||
0,
|
|
||||||
PipelineStage::ColorOutput,
|
|
||||||
MemoryAccess::ColorWrite,
|
|
||||||
|
|
||||||
true //< tilable
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (m_depthStencilFormat != VK_FORMAT_MAX_ENUM)
|
if (m_depthStencilFormat != VK_FORMAT_MAX_ENUM)
|
||||||
{
|
{
|
||||||
std::optional<PixelFormat> depthStencilFormat = FromVulkan(m_depthStencilFormat);
|
depthStencilFormat = FromVulkan(m_depthStencilFormat);
|
||||||
if (!depthStencilFormat)
|
if (!depthStencilFormat)
|
||||||
{
|
{
|
||||||
NazaraError("unhandled vulkan pixel format (0x" + NumberToString(m_depthStencilFormat, 16) + ")");
|
NazaraError("unhandled vulkan pixel format (0x" + NumberToString(m_depthStencilFormat, 16) + ")");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
attachments.push_back({
|
|
||||||
*depthStencilFormat,
|
|
||||||
AttachmentLoadOp::Clear,
|
|
||||||
AttachmentLoadOp::Discard,
|
|
||||||
AttachmentStoreOp::Discard,
|
|
||||||
AttachmentStoreOp::Discard,
|
|
||||||
TextureLayout::Undefined,
|
|
||||||
TextureLayout::DepthStencilReadWrite
|
|
||||||
});
|
|
||||||
|
|
||||||
subpasses.front().depthStencilAttachment = RenderPass::AttachmentReference{
|
|
||||||
1,
|
|
||||||
TextureLayout::DepthStencilReadWrite
|
|
||||||
};
|
|
||||||
|
|
||||||
auto& subpassDependency = subpassDependencies.front();
|
|
||||||
subpassDependency.fromStages |= PipelineStage::FragmentTestsEarly;
|
|
||||||
subpassDependency.toStages |= PipelineStage::FragmentTestsEarly;
|
|
||||||
subpassDependency.toAccessFlags |= MemoryAccess::DepthStencilWrite;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_renderPass.emplace(*m_device, std::move(attachments), std::move(subpasses), std::move(subpassDependencies));
|
std::vector<RenderPass::Attachment> attachments;
|
||||||
|
std::vector<RenderPass::SubpassDescription> subpassDescriptions;
|
||||||
|
std::vector<RenderPass::SubpassDependency> subpassDependencies;
|
||||||
|
|
||||||
|
BuildRenderPass(*colorFormat, depthStencilFormat.value_or(PixelFormat::Undefined), attachments, subpassDescriptions, subpassDependencies);
|
||||||
|
m_renderPass.emplace(*m_device, std::move(attachments), std::move(subpassDescriptions), std::move(subpassDependencies));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue