Improve texture view support
This commit is contained in:
committed by
Jérôme Leclercq
parent
42f8cdb151
commit
08ea4c87a7
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user