Renderer: Add mipmaps generation support

This commit is contained in:
SirLynix
2023-05-14 18:55:41 +02:00
parent 3712b641f8
commit 1d32af53c5
33 changed files with 488 additions and 183 deletions

View File

@@ -8,7 +8,6 @@
#define NAZARA_OPENGLRENDERER_OPENGLCOMMANDBUFFER_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <NazaraUtils/TypeList.hpp>
#include <Nazara/Core/Color.hpp>
#include <Nazara/Math/Rect.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
@@ -17,6 +16,7 @@
#include <Nazara/OpenGLRenderer/OpenGLShaderBinding.hpp>
#include <Nazara/Renderer/CommandBuffer.hpp>
#include <Nazara/Renderer/CommandBufferBuilder.hpp>
#include <NazaraUtils/TypeList.hpp>
#include <optional>
#include <variant>
#include <vector>
@@ -46,8 +46,11 @@ namespace Nz
inline void BindRenderPipeline(const OpenGLRenderPipeline* pipeline);
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);
inline void BuildMipmaps(OpenGLTexture& texture, UInt8 baseLevel, UInt8 levelCount);
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 CopyTexture(const OpenGLTexture& source, const Boxui& sourceBox, const OpenGLTexture& target, const Vector3ui& targetPoint);
@@ -83,6 +86,7 @@ namespace Nz
#define NAZARA_OPENGL_FOREACH_COMMANDS(cb, lastCb) \
cb(BeginDebugRegionCommand) \
cb(BlitTextureCommand) \
cb(BuildTextureMipmapsCommand) \
cb(CopyBufferCommand) \
cb(CopyBufferFromMemoryCommand) \
cb(CopyTextureCommand) \
@@ -112,6 +116,7 @@ namespace Nz
inline void Execute(const GL::Context* context, const BeginDebugRegionCommand& command);
inline void Execute(const GL::Context* context, const BlitTextureCommand& command);
inline void Execute(const GL::Context* context, const BuildTextureMipmapsCommand& command);
inline void Execute(const GL::Context* context, const CopyBufferCommand& command);
inline void Execute(const GL::Context* context, const CopyBufferFromMemoryCommand& command);
inline void Execute(const GL::Context* context, const CopyTextureCommand& command);
@@ -139,6 +144,13 @@ namespace Nz
SamplerFilter filter;
};
struct BuildTextureMipmapsCommand
{
OpenGLTexture* texture;
UInt8 baseLevel;
UInt8 levelCount;
};
struct ComputeStates
{
const OpenGLComputePipeline* pipeline = nullptr;

View File

@@ -88,6 +88,17 @@ namespace Nz
m_commands.emplace_back(std::move(blitTexture));
}
inline void OpenGLCommandBuffer::BuildMipmaps(OpenGLTexture& texture, UInt8 baseLevel, UInt8 levelCount)
{
BuildTextureMipmapsCommand buildMipmaps = {
&texture,
baseLevel,
levelCount
};
m_commands.emplace_back(std::move(buildMipmaps));
}
inline void OpenGLCommandBuffer::CopyBuffer(GLuint source, GLuint target, UInt64 size, UInt64 sourceOffset, UInt64 targetOffset)
{
CopyBufferCommand copyBuffer = {

View File

@@ -38,6 +38,8 @@ namespace Nz
void BlitTexture(const Texture& fromTexture, const Boxui& fromBox, TextureLayout fromLayout, const Texture& toTexture, const Boxui& toBox, TextureLayout toLayout, SamplerFilter filter) override;
void BuildMipmaps(Texture& texture, UInt8 baseLevel, UInt8 maxLevel) override;
void CopyBuffer(const RenderBufferView& source, const RenderBufferView& target, UInt64 size, UInt64 sourceOffset = 0, UInt64 targetOffset = 0) override;
void CopyBuffer(const UploadPool::Allocation& allocation, const RenderBufferView& target, UInt64 size, UInt64 sourceOffset = 0, UInt64 targetOffset = 0) override;
void CopyTexture(const Texture& fromTexture, const Boxui& fromBox, TextureLayout fromLayout, const Texture& toTexture, const Vector3ui& toPos, TextureLayout toLayout) override;

View File

@@ -47,6 +47,7 @@ namespace Nz
std::shared_ptr<ShaderModule> InstantiateShaderModule(nzsl::ShaderStageTypeFlags shaderStages, ShaderLanguage lang, const void* source, std::size_t sourceSize, const nzsl::ShaderWriter::States& states) override;
std::shared_ptr<Swapchain> InstantiateSwapchain(WindowHandle windowHandle, const Vector2ui& windowSize, const SwapchainParameters& parameters) override;
std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) override;
std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params, const void* initialData, bool buildMipmaps, unsigned int srcWidth = 0, unsigned int srcHeight = 0) override;
std::shared_ptr<TextureSampler> InstantiateTextureSampler(const TextureSamplerInfo& params) override;
bool IsTextureFormatSupported(PixelFormat format, TextureUsage usage) const override;

View File

@@ -20,6 +20,7 @@ namespace Nz
{
public:
OpenGLTexture(OpenGLDevice& device, const TextureInfo& textureInfo);
OpenGLTexture(OpenGLDevice& device, const TextureInfo& textureInfo, const void* initialData, bool buildMipmaps, unsigned int srcWidth = 0, unsigned int srcHeight = 0);
OpenGLTexture(std::shared_ptr<OpenGLTexture> parentTexture, const TextureViewInfo& viewInfo);
OpenGLTexture(const OpenGLTexture&) = delete;
OpenGLTexture(OpenGLTexture&&) = delete;
@@ -28,6 +29,8 @@ namespace Nz
bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos) override;
std::shared_ptr<Texture> CreateView(const TextureViewInfo& viewInfo) override;
inline void GenerateMipmaps(UInt8 baseLevel, UInt8 levelCount);
inline PixelFormat GetFormat() const override;
inline UInt8 GetLevelCount() const override;
inline OpenGLTexture* GetParentTexture() const override;

View File

@@ -2,11 +2,42 @@
// This file is part of the "Nazara Engine - OpenGL renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Error.hpp>
#include <stdexcept>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline void OpenGLTexture::GenerateMipmaps(UInt8 baseLevel, UInt8 levelCount)
{
NazaraAssert(baseLevel + levelCount < m_textureInfo.levelCount, "out of bounds");
GL::Texture* targetTexture;
if (RequiresTextureViewEmulation())
{
baseLevel += m_viewInfo->baseMipLevel;
levelCount += m_viewInfo->baseMipLevel;
targetTexture = &m_parentTexture->m_texture;
}
else
targetTexture = &m_texture;
if (baseLevel != 0)
targetTexture->SetParameteri(GL_TEXTURE_BASE_LEVEL, baseLevel);
if (levelCount != m_textureInfo.levelCount)
targetTexture->SetParameteri(GL_TEXTURE_MAX_LEVEL, levelCount);
targetTexture->GenerateMipmap();
// Reset level config
if (baseLevel != 0)
targetTexture->SetParameteri(GL_TEXTURE_BASE_LEVEL, 0);
if (levelCount != m_textureInfo.levelCount)
targetTexture->SetParameteri(GL_TEXTURE_MAX_LEVEL, m_textureInfo.levelCount);
}
inline PixelFormat OpenGLTexture::GetFormat() const
{
return m_textureInfo.pixelFormat;

View File

@@ -24,6 +24,8 @@ namespace Nz::GL
Texture(Texture&&) noexcept = default;
~Texture() = default;
inline void GenerateMipmap();
inline TextureTarget GetTarget() const;
inline void SetParameterf(GLenum pname, GLfloat param);

View File

@@ -7,6 +7,13 @@
namespace Nz::GL
{
inline void Texture::GenerateMipmap()
{
const Context& context = EnsureDeviceContext();
context.BindTexture(m_target, m_objectId);
context.glGenerateMipmap(ToOpenGL(m_target));
}
inline TextureTarget Texture::GetTarget() const
{
return m_target;