Renderer: Improve texture view support (and support emulation for OGL)

This commit is contained in:
SirLynix
2022-12-02 22:58:34 +01:00
committed by Jérôme Leclercq
parent 08ea4c87a7
commit 56acbb2694
9 changed files with 99 additions and 24 deletions

View File

@@ -78,7 +78,40 @@ namespace Nz
throw std::runtime_error("unhandled pixel format " + PixelFormatInfo::GetName(textureFormat));
}
m_framebuffer.Texture2D(attachment, ToOpenGL(OpenGLTexture::ToTextureTarget(glTexture.GetType())), glTexture.GetTexture().GetObjectId());
if (glTexture.RequiresTextureViewEmulation())
{
const TextureViewInfo& texViewInfo = glTexture.GetTextureViewInfo();
if (texViewInfo.viewType != ImageType::E2D)
throw std::runtime_error("unrestricted texture views can only be used as 2D texture attachment");
const OpenGLTexture& parentTexture = *glTexture.GetParentTexture();
switch (parentTexture.GetType())
{
case 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());
GLenum texTarget = faceTargets[texViewInfo.baseArrayLayer];
m_framebuffer.Texture2D(GL_COLOR_ATTACHMENT0, texTarget, parentTexture.GetTexture().GetObjectId(), texViewInfo.baseMipLevel);
break;
}
case ImageType::E1D:
case ImageType::E2D:
m_framebuffer.Texture2D(GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, parentTexture.GetTexture().GetObjectId(), texViewInfo.baseMipLevel);
break;
case ImageType::E1D_Array:
case ImageType::E2D_Array:
case ImageType::E3D:
m_framebuffer.TextureLayer(GL_COLOR_ATTACHMENT0, parentTexture.GetTexture().GetObjectId(), texViewInfo.baseArrayLayer, texViewInfo.baseMipLevel);
break;
}
}
else
m_framebuffer.Texture2D(attachment, ToOpenGL(OpenGLTexture::ToTextureTarget(glTexture.GetType())), glTexture.GetTexture().GetObjectId());
}
GLenum status = m_framebuffer.Check();

View File

@@ -69,6 +69,7 @@ namespace Nz
NazaraAssert(viewInfo.layerCount <= m_parentTexture->m_textureInfo.layerCount - viewInfo.baseArrayLayer, "layer count exceeds number of layers");
NazaraAssert(viewInfo.levelCount <= m_parentTexture->m_textureInfo.levelCount - viewInfo.baseMipLevel, "level count exceeds number of levels");
m_textureInfo = ApplyView(m_parentTexture->m_textureInfo, viewInfo);
m_viewInfo = viewInfo;
// Try to use texture views if supported (core in GL 4.3 or extension)
@@ -77,11 +78,10 @@ namespace Nz
if (m_texture.Create(*m_parentTexture->m_texture.GetDevice()))
{
auto format = DescribeTextureFormat(viewInfo.reinterpretFormat);
GLenum target = ToOpenGL(ToTextureTarget(viewInfo.viewType));
context.ClearErrorStack();
m_texture.TextureView(target, m_parentTexture->m_texture.GetObjectId(), format->internalFormat, viewInfo.baseMipLevel, viewInfo.levelCount, viewInfo.baseArrayLayer, viewInfo.layerCount);
m_texture.TextureView(ToTextureTarget(viewInfo.viewType), m_parentTexture->m_texture.GetObjectId(), format->internalFormat, viewInfo.baseMipLevel, viewInfo.levelCount, viewInfo.baseArrayLayer, viewInfo.layerCount);
if (!context.DidLastCallSucceed())
m_texture.Destroy();

View File

@@ -294,28 +294,39 @@ namespace Nz::GL
if (texture.RequiresTextureViewEmulation())
{
const TextureViewInfo& texViewInfo = texture.GetTextureViewInfo();
if (texViewInfo.viewType != ImageType::E2D)
throw std::runtime_error("unrestricted texture views can only be used as 2D texture attachment");
GLenum texTarget;
if (texture.GetType() == ImageType::Cubemap)
const OpenGLTexture& parentTexture = *texture.GetParentTexture();
switch (parentTexture.GetType())
{
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];
case 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());
GLenum texTarget = faceTargets[texViewInfo.baseArrayLayer];
framebuffer.Texture2D(GL_COLOR_ATTACHMENT0, texTarget, parentTexture.GetTexture().GetObjectId(), texViewInfo.baseMipLevel);
break;
}
case ImageType::E1D:
case ImageType::E2D:
framebuffer.Texture2D(GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, parentTexture.GetTexture().GetObjectId(), texViewInfo.baseMipLevel);
break;
case ImageType::E1D_Array:
case ImageType::E2D_Array:
case ImageType::E3D:
framebuffer.TextureLayer(GL_COLOR_ATTACHMENT0, parentTexture.GetTexture().GetObjectId(), texViewInfo.baseArrayLayer, texViewInfo.baseMipLevel);
break;
}
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");
throw std::runtime_error("blit is not yet supported from/to other texture type than 2D textures");
framebuffer.Texture2D(GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.GetTexture().GetObjectId(), 0);
}

View File

@@ -37,13 +37,32 @@ namespace Nz
NazaraAssert(params.IsValid(), "Invalid TextureParams");
Nz::TextureInfo texParams;
texParams.depth = image.GetDepth();
texParams.height = image.GetHeight();
texParams.pixelFormat = image.GetFormat();
texParams.type = image.GetType();
texParams.width = image.GetWidth();
texParams.usageFlags = params.usageFlags;
switch (image.GetType())
{
case ImageType::E1D:
case ImageType::E2D:
case ImageType::E3D:
break;
case ImageType::E1D_Array:
texParams.layerCount = image.GetHeight();
break;
case ImageType::E2D_Array:
texParams.layerCount = image.GetDepth();
break;
case ImageType::Cubemap:
texParams.layerCount = 6;
break;
}
std::shared_ptr<Texture> texture = params.renderDevice->InstantiateTexture(texParams);
if (!texture->Update(image.GetConstPixels()))
{