Improve texture view support

This commit is contained in:
SirLynix
2022-12-01 18:06:20 +01:00
committed by Jérôme Leclercq
parent 42f8cdb151
commit 08ea4c87a7
17 changed files with 128 additions and 75 deletions

View File

@@ -11,6 +11,7 @@
#include <Nazara/OpenGLRenderer/OpenGLTexture.hpp>
#include <Nazara/OpenGLRenderer/OpenGLUploadPool.hpp>
#include <Nazara/Utils/StackArray.hpp>
#include <stdexcept>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
@@ -66,7 +67,7 @@ namespace Nz
const OpenGLTexture& sourceTexture = static_cast<const OpenGLTexture&>(fromTexture);
const OpenGLTexture& targetTexture = static_cast<const OpenGLTexture&>(toTexture);
m_commandBuffer.BlitTexture(sourceTexture.GetTexture(), fromBox, targetTexture.GetTexture(), toBox, filter);
m_commandBuffer.BlitTexture(sourceTexture, fromBox, targetTexture, toBox, filter);
}
void OpenGLCommandBufferBuilder::CopyBuffer(const RenderBufferView& source, const RenderBufferView& target, UInt64 size, UInt64 sourceOffset, UInt64 targetOffset)
@@ -89,7 +90,7 @@ namespace Nz
const OpenGLTexture& sourceTexture = static_cast<const OpenGLTexture&>(fromTexture);
const OpenGLTexture& targetTexture = static_cast<const OpenGLTexture&>(toTexture);
m_commandBuffer.CopyTexture(sourceTexture.GetTexture(), fromBox, targetTexture.GetTexture(), toPos);
m_commandBuffer.CopyTexture(sourceTexture, fromBox, targetTexture, toPos);
}
void OpenGLCommandBufferBuilder::Draw(UInt32 vertexCount, UInt32 instanceCount, UInt32 firstVertex, UInt32 firstInstance)

View File

@@ -71,6 +71,9 @@ namespace Nz
if (m_referenceContext->glPolygonMode) //< not supported in core OpenGL ES, but supported in OpenGL or with GL_NV_polygon_mode extension
m_deviceInfo.features.nonSolidFaceFilling = true;
if (m_referenceContext->IsExtensionSupported(GL::Extension::TextureView))
m_deviceInfo.features.unrestrictedTextureViews = true;
// Limits
GLint minUboOffsetAlignment;
m_referenceContext->glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &minUboOffsetAlignment);

View File

@@ -139,6 +139,8 @@ namespace Nz
if (const OpenGLTexture* glTexture = static_cast<const OpenGLTexture*>(textureBinding.texture))
{
// TODO: Add texture view emulation
textureDescriptor.texture = glTexture->GetTexture().GetObjectId();
if (const OpenGLTextureSampler* glSampler = static_cast<const OpenGLTextureSampler*>(textureBinding.sampler))

View File

@@ -96,7 +96,7 @@ namespace Nz
const OpenGLTexture& glTexture = static_cast<const OpenGLTexture&>(source);
const GL::Context& context = m_texture.EnsureDeviceContext();
return context.CopyTexture(glTexture.GetTexture(), m_texture, srcBox, dstPos);
return context.CopyTexture(glTexture, *this, srcBox, dstPos);
}
std::shared_ptr<Texture> OpenGLTexture::CreateView(const TextureViewInfo& viewInfo)

View File

@@ -280,28 +280,58 @@ namespace Nz::GL
}
}
bool Context::BlitTexture(const Texture& source, const Texture& destination, const Boxui& srcBox, const Boxui& dstBox, SamplerFilter filter) const
bool Context::BlitTexture(const OpenGLTexture& texture, const OpenGLTexture& destination, const Boxui& srcBox, const Boxui& dstBox, SamplerFilter filter) const
{
if (!m_blitFramebuffers && !InitializeBlitFramebuffers())
return false;
//TODO: handle other textures types
assert(source.GetTarget() == TextureTarget::Target2D);
assert(destination.GetTarget() == TextureTarget::Target2D);
// Bind framebuffers before configuring them (so they won't override each other)
BindFramebuffer(FramebufferTarget::Draw, m_blitFramebuffers->drawFBO.GetObjectId());
BindFramebuffer(FramebufferTarget::Read, m_blitFramebuffers->readFBO.GetObjectId());
auto BindTexture = [](GL::Framebuffer& framebuffer, const OpenGLTexture& texture)
{
if (texture.RequiresTextureViewEmulation())
{
const TextureViewInfo& texViewInfo = texture.GetTextureViewInfo();
GLenum texTarget;
if (texture.GetType() == ImageType::Cubemap)
{
constexpr std::array<GLenum, 6> faceTargets = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
assert(texViewInfo.baseArrayLayer < faceTargets.size());
texTarget = faceTargets[texViewInfo.baseArrayLayer];
}
else if (texture.GetType() == ImageType::E2D)
texTarget = GL_TEXTURE_2D;
else
throw std::runtime_error("unrestricted texture views are not supported on this device, blit is only permitted from/to a cubemap face or a 2D texture");
//TODO: Support texture arrays (one slice at a time)
framebuffer.Texture2D(GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.GetParentTexture()->GetTexture().GetObjectId(), texture.GetTextureViewInfo().baseMipLevel);
}
else
{
if (texture.GetTexture().GetTarget() != TextureTarget::Target2D)
throw std::runtime_error("blit is not yet supported from other texture type than 2D textures");
framebuffer.Texture2D(GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.GetTexture().GetObjectId(), 0);
}
};
// Attach textures to color attachment
m_blitFramebuffers->drawFBO.Texture2D(GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destination.GetObjectId());
BindTexture(m_blitFramebuffers->readFBO, texture);
BindTexture(m_blitFramebuffers->drawFBO, destination);
// Validate framebuffer completeness
if (GLenum checkResult = m_blitFramebuffers->drawFBO.Check(); checkResult != GL_FRAMEBUFFER_COMPLETE)
{
NazaraError("Blit draw FBO is incomplete: " + TranslateOpenGLError(checkResult));
return false;
}
m_blitFramebuffers->readFBO.Texture2D(GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, source.GetObjectId());
if (GLenum checkResult = m_blitFramebuffers->readFBO.Check(); checkResult != GL_FRAMEBUFFER_COMPLETE)
{
NazaraError("Blit read FBO is incomplete: " + TranslateOpenGLError(checkResult));
@@ -324,18 +354,20 @@ namespace Nz::GL
return true;
}
bool Context::CopyTexture(const Texture& source, const Texture& destination, const Boxui& srcBox, const Vector3ui& dstPos) const
bool Context::CopyTexture(const OpenGLTexture& source, const OpenGLTexture& destination, const Boxui& srcBox, const Vector3ui& dstPos) const
{
// Use glCopyImageSubData if available
if (glCopyImageSubData)
// TODO: Emulate texture views (which aren't available on GL ES, even though glCopyImageSubData is)
if (glCopyImageSubData && !source.RequiresTextureViewEmulation() && !destination.RequiresTextureViewEmulation())
{
GLuint srcImage = source.GetObjectId();
GLenum srcTarget = ToOpenGL(source.GetTarget());
GLuint srcImage = source.GetTexture().GetObjectId();
GLenum srcTarget = ToOpenGL(source.GetTexture().GetTarget());
GLuint dstImage = destination.GetObjectId();
GLenum dstTarget = ToOpenGL(destination.GetTarget());
GLuint dstImage = destination.GetTexture().GetObjectId();
GLenum dstTarget = ToOpenGL(destination.GetTexture().GetTarget());
glCopyImageSubData(srcImage, srcTarget, 0, GLint(srcBox.x), GLint(srcBox.y), GLint(srcBox.z), dstImage, dstTarget, 0, GLint(dstPos.x), GLint(dstPos.y), GLint(dstPos.z), GLsizei(srcBox.width), GLsizei(srcBox.height), GLsizei(srcBox.depth));
return true;
}
else