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

@@ -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