Commit a1ad846c authored by Laszlo Agocs's avatar Laszlo Agocs

Implement all texture formats for gl

...and add a semi-format that can be used to port code with the
'if modernGL then GL_R8 else GL_ALPHA' pattern (in order to support GLES
2.0).
parent 896ca1bd
...@@ -404,6 +404,12 @@ QT_BEGIN_NAMESPACE ...@@ -404,6 +404,12 @@ QT_BEGIN_NAMESPACE
\value NPOTTextureRepeat Indicates that the \l{QRhiSampler::Repeat}{Repeat} \value NPOTTextureRepeat Indicates that the \l{QRhiSampler::Repeat}{Repeat}
mode is supported for textures with a non-power-of-two size. mode is supported for textures with a non-power-of-two size.
\value RedOrAlpha8IsRed Indicates that the
\l{QRhiTexture::RED_OR_ALPHA8}{RED_OR_ALPHA8} format maps to a one
component 8-bit \c red format. This is the case for all backends except
OpenGL, where \c{GL_ALPHA}, a one component 8-bit \c alpha format, is used
instead. This is relevant for shader code that samples from the texture.
*/ */
/*! /*!
...@@ -1862,12 +1868,22 @@ QRhiRenderBuffer::QRhiRenderBuffer(QRhiImplementation *rhi, Type type_, const QS ...@@ -1862,12 +1868,22 @@ QRhiRenderBuffer::QRhiRenderBuffer(QRhiImplementation *rhi, Type type_, const QS
note that flags() can modify the format when QRhiTexture::sRGB is set. note that flags() can modify the format when QRhiTexture::sRGB is set.
\value UnknownFormat Not a valid format. This cannot be passed to setFormat(). \value UnknownFormat Not a valid format. This cannot be passed to setFormat().
\value RGBA8
\value BGRA8 \value RGBA8 Four component, unsigned normalized 8 bit per component. Always supported.
\value R8
\value R16 \value BGRA8 Four component, unsigned normalized 8 bit per component.
\value D16
\value D32 \value R8 One component, unsigned normalized 8 bit.
\value R16 One component, unsigned normalized 16 bit.
\value RED_OR_ALPHA8 Either same as R8, or is a similar format with the component swizzled to alpha,
depending on \l{QRhi::RedOrAlpha8IsRed}{RedOrAlpha8IsRed}.
\value D16 16-bit depth (normalized unsigned integer)
\value D32 32-bit depth (32-bit float)
\value BC1 \value BC1
\value BC2 \value BC2
\value BC3 \value BC3
...@@ -1875,9 +1891,11 @@ QRhiRenderBuffer::QRhiRenderBuffer(QRhiImplementation *rhi, Type type_, const QS ...@@ -1875,9 +1891,11 @@ QRhiRenderBuffer::QRhiRenderBuffer(QRhiImplementation *rhi, Type type_, const QS
\value BC5 \value BC5
\value BC6H \value BC6H
\value BC7 \value BC7
\value ETC2_RGB8 \value ETC2_RGB8
\value ETC2_RGB8A1 \value ETC2_RGB8A1
\value ETC2_RGBA8 \value ETC2_RGBA8
\value ASTC_4x4 \value ASTC_4x4
\value ASTC_5x4 \value ASTC_5x4
\value ASTC_5x5 \value ASTC_5x5
......
...@@ -643,6 +643,7 @@ public: ...@@ -643,6 +643,7 @@ public:
BGRA8, BGRA8,
R8, R8,
R16, R16,
RED_OR_ALPHA8,
D16, D16,
D32, D32,
...@@ -1251,7 +1252,8 @@ public: ...@@ -1251,7 +1252,8 @@ public:
TessellationShaders, TessellationShaders,
NonDynamicUniformBuffers, NonDynamicUniformBuffers,
NonFourAlignedEffectiveIndexBufferOffset, NonFourAlignedEffectiveIndexBufferOffset,
NPOTTextureRepeat NPOTTextureRepeat,
RedOrAlpha8IsRed
}; };
enum BeginFrameFlag { enum BeginFrameFlag {
......
...@@ -181,7 +181,7 @@ public: ...@@ -181,7 +181,7 @@ public:
{ {
if (res->m_orphanedWithRsh) { if (res->m_orphanedWithRsh) {
qWarning("Attempted to perform something on an orphaned QRhiResource %p (%s). This is invalid.", qWarning("Attempted to perform something on an orphaned QRhiResource %p (%s). This is invalid.",
res, res->m_objectName.constData()); (void *) res, res->m_objectName.constData());
return false; return false;
} }
return true; return true;
......
...@@ -401,6 +401,8 @@ bool QRhiD3D11::isFeatureSupported(QRhi::Feature feature) const ...@@ -401,6 +401,8 @@ bool QRhiD3D11::isFeatureSupported(QRhi::Feature feature) const
return true; return true;
case QRhi::NPOTTextureRepeat: case QRhi::NPOTTextureRepeat:
return true; return true;
case QRhi::RedOrAlpha8IsRed:
return true;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
return false; return false;
...@@ -914,6 +916,8 @@ static inline DXGI_FORMAT toD3DTextureFormat(QRhiTexture::Format format, QRhiTex ...@@ -914,6 +916,8 @@ static inline DXGI_FORMAT toD3DTextureFormat(QRhiTexture::Format format, QRhiTex
return DXGI_FORMAT_R8_UNORM; return DXGI_FORMAT_R8_UNORM;
case QRhiTexture::R16: case QRhiTexture::R16:
return DXGI_FORMAT_R16_UNORM; return DXGI_FORMAT_R16_UNORM;
case QRhiTexture::RED_OR_ALPHA8:
return DXGI_FORMAT_R8_UNORM;
case QRhiTexture::D16: case QRhiTexture::D16:
return DXGI_FORMAT_R16_TYPELESS; return DXGI_FORMAT_R16_TYPELESS;
......
...@@ -157,6 +157,22 @@ QT_BEGIN_NAMESPACE ...@@ -157,6 +157,22 @@ QT_BEGIN_NAMESPACE
\brief Holds the OpenGL texture object that is backing a QRhiTexture instance. \brief Holds the OpenGL texture object that is backing a QRhiTexture instance.
*/ */
#ifndef GL_BGRA
#define GL_BGRA 0x80E1
#endif
#ifndef GL_R8
#define GL_R8 0x8229
#endif
#ifndef GL_R16
#define GL_R16 0x822A
#endif
#ifndef GL_RED
#define GL_RED 0x1903
#endif
#ifndef GL_PRIMITIVE_RESTART_FIXED_INDEX #ifndef GL_PRIMITIVE_RESTART_FIXED_INDEX
#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 #define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
#endif #endif
...@@ -290,6 +306,8 @@ bool QRhiGles2::create(QRhi::Flags flags) ...@@ -290,6 +306,8 @@ bool QRhiGles2::create(QRhi::Flags flags)
if (n > 0) if (n > 0)
f->glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, supportedCompressedFormats.data()); f->glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, supportedCompressedFormats.data());
f->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.maxTextureSize);
caps.msaaRenderBuffer = f->hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample) caps.msaaRenderBuffer = f->hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)
&& f->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit); && f->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit);
...@@ -297,7 +315,7 @@ bool QRhiGles2::create(QRhi::Flags flags) ...@@ -297,7 +315,7 @@ bool QRhiGles2::create(QRhi::Flags flags)
caps.npotTextureRepeat = f->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat); caps.npotTextureRepeat = f->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat);
const QSurfaceFormat actualFormat = ctx->format(); const QSurfaceFormat actualFormat = ctx->format();
if (ctx->isOpenGLES()) if (actualFormat.renderableType() == QSurfaceFormat::OpenGLES)
caps.fixedIndexPrimitiveRestart = actualFormat.version() >= qMakePair(3, 0); caps.fixedIndexPrimitiveRestart = actualFormat.version() >= qMakePair(3, 0);
else else
caps.fixedIndexPrimitiveRestart = actualFormat.version() >= qMakePair(4, 3); caps.fixedIndexPrimitiveRestart = actualFormat.version() >= qMakePair(4, 3);
...@@ -305,7 +323,11 @@ bool QRhiGles2::create(QRhi::Flags flags) ...@@ -305,7 +323,11 @@ bool QRhiGles2::create(QRhi::Flags flags)
if (caps.fixedIndexPrimitiveRestart) if (caps.fixedIndexPrimitiveRestart)
f->glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX); f->glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
f->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.maxTextureSize); caps.bgraExternalFormat = f->hasOpenGLExtension(QOpenGLExtensions::BGRATextureFormat);
caps.bgraInternalFormat = caps.bgraExternalFormat && actualFormat.renderableType() == QSurfaceFormat::OpenGLES;
caps.sized8Formats = f->hasOpenGLExtension(QOpenGLExtensions::Sized8Formats);
caps.sized16Formats = f->hasOpenGLExtension(QOpenGLExtensions::Sized16Formats);
nativeHandlesStruct.context = ctx; nativeHandlesStruct.context = ctx;
...@@ -512,11 +534,13 @@ bool QRhiGles2::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture ...@@ -512,11 +534,13 @@ bool QRhiGles2::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture
return false; return false;
case QRhiTexture::BGRA8: case QRhiTexture::BGRA8:
Q_FALLTHROUGH(); return caps.bgraExternalFormat;
case QRhiTexture::R8: case QRhiTexture::R8:
Q_FALLTHROUGH(); return caps.sized8Formats;
case QRhiTexture::R16: case QRhiTexture::R16:
return false; // ### return caps.sized16Formats;
default: default:
break; break;
...@@ -552,6 +576,8 @@ bool QRhiGles2::isFeatureSupported(QRhi::Feature feature) const ...@@ -552,6 +576,8 @@ bool QRhiGles2::isFeatureSupported(QRhi::Feature feature) const
return true; return true;
case QRhi::NPOTTextureRepeat: case QRhi::NPOTTextureRepeat:
return caps.npotTextureRepeat; return caps.npotTextureRepeat;
case QRhi::RedOrAlpha8IsRed:
return false;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
return false; return false;
...@@ -1504,7 +1530,6 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) ...@@ -1504,7 +1530,6 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
break; break;
case QGles2CommandBuffer::Command::ReadPixels: case QGles2CommandBuffer::Command::ReadPixels:
{ {
// ### more formats
QRhiReadbackResult *result = cmd.args.readPixels.result; QRhiReadbackResult *result = cmd.args.readPixels.result;
GLuint tex = cmd.args.readPixels.texture; GLuint tex = cmd.args.readPixels.texture;
GLuint fbo = 0; GLuint fbo = 0;
...@@ -2113,11 +2138,38 @@ bool QGles2Texture::prepareBuild(QSize *adjustedSize) ...@@ -2113,11 +2138,38 @@ bool QGles2Texture::prepareBuild(QSize *adjustedSize)
target = isCube ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D; target = isCube ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
// ### more formats
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_BYTE; gltype = GL_UNSIGNED_BYTE;
switch (m_format) {
case QRhiTexture::RGBA8:
glintformat = GL_RGBA;
glformat = GL_RGBA;
break;
case QRhiTexture::BGRA8:
glintformat = rhiD->caps.bgraInternalFormat ? GL_BGRA : GL_RGBA;
glformat = GL_BGRA;
break;
case QRhiTexture::R16:
glintformat = GL_R16;
glformat = GL_RED;
gltype = GL_UNSIGNED_SHORT;
break;
case QRhiTexture::R8:
glintformat = GL_R8;
glformat = GL_RED;
break;
case QRhiTexture::RED_OR_ALPHA8:
// always alpha because we do not support core profile
glintformat = GL_ALPHA;
glformat = GL_ALPHA;
break;
default:
Q_UNREACHABLE();
glintformat = GL_RGBA;
glformat = GL_RGBA;
break;
}
mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1; mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1;
if (isCompressed) { if (isCompressed) {
......
...@@ -558,14 +558,29 @@ public: ...@@ -558,14 +558,29 @@ public:
QSurface *fallbackSurface = nullptr; QSurface *fallbackSurface = nullptr;
mutable bool needsMakeCurrent = false; mutable bool needsMakeCurrent = false;
QOpenGLExtensions *f = nullptr; QOpenGLExtensions *f = nullptr;
struct { struct Caps {
Caps()
: maxTextureSize(2048),
msaaRenderBuffer(false),
npotTexture(true),
npotTextureRepeat(true),
fixedIndexPrimitiveRestart(false),
bgraExternalFormat(false),
bgraInternalFormat(false),
sized8Formats(false),
sized16Formats(false)
{ }
int maxTextureSize;
// Multisample fb and blit are supported (GLES 3.0 or OpenGL 3.x). Not // Multisample fb and blit are supported (GLES 3.0 or OpenGL 3.x). Not
// the same as multisample textures! // the same as multisample textures!
bool msaaRenderBuffer = false; uint msaaRenderBuffer : 1;
bool npotTexture = true; uint npotTexture : 1;
bool npotTextureRepeat = true; uint npotTextureRepeat : 1;
bool fixedIndexPrimitiveRestart = false; uint fixedIndexPrimitiveRestart : 1;
int maxTextureSize = 2048; uint bgraExternalFormat : 1;
uint bgraInternalFormat : 1;
uint sized8Formats : 1;
uint sized16Formats : 1;
} caps; } caps;
bool inFrame = false; bool inFrame = false;
bool inPass = false; bool inPass = false;
......
...@@ -517,6 +517,8 @@ bool QRhiMetal::isFeatureSupported(QRhi::Feature feature) const ...@@ -517,6 +517,8 @@ bool QRhiMetal::isFeatureSupported(QRhi::Feature feature) const
return false; return false;
case QRhi::NPOTTextureRepeat: case QRhi::NPOTTextureRepeat:
return true; return true;
case QRhi::RedOrAlpha8IsRed:
return true;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
return false; return false;
...@@ -1952,6 +1954,8 @@ static inline MTLPixelFormat toMetalTextureFormat(QRhiTexture::Format format, QR ...@@ -1952,6 +1954,8 @@ static inline MTLPixelFormat toMetalTextureFormat(QRhiTexture::Format format, QR
#endif #endif
case QRhiTexture::R16: case QRhiTexture::R16:
return MTLPixelFormatR16Unorm; return MTLPixelFormatR16Unorm;
case QRhiTexture::RED_OR_ALPHA8:
return MTLPixelFormatR8Unorm;
case QRhiTexture::D16: case QRhiTexture::D16:
return MTLPixelFormatDepth16Unorm; return MTLPixelFormatDepth16Unorm;
......
...@@ -704,6 +704,8 @@ static inline VkFormat toVkTextureFormat(QRhiTexture::Format format, QRhiTexture ...@@ -704,6 +704,8 @@ static inline VkFormat toVkTextureFormat(QRhiTexture::Format format, QRhiTexture
return srgb ? VK_FORMAT_R8_SRGB : VK_FORMAT_R8_UNORM; return srgb ? VK_FORMAT_R8_SRGB : VK_FORMAT_R8_UNORM;
case QRhiTexture::R16: case QRhiTexture::R16:
return VK_FORMAT_R16_UNORM; return VK_FORMAT_R16_UNORM;
case QRhiTexture::RED_OR_ALPHA8:
return VK_FORMAT_R8_UNORM;
case QRhiTexture::D16: case QRhiTexture::D16:
return VK_FORMAT_D16_UNORM; return VK_FORMAT_D16_UNORM;
...@@ -3044,6 +3046,8 @@ bool QRhiVulkan::isFeatureSupported(QRhi::Feature feature) const ...@@ -3044,6 +3046,8 @@ bool QRhiVulkan::isFeatureSupported(QRhi::Feature feature) const
return true; return true;
case QRhi::NPOTTextureRepeat: case QRhi::NPOTTextureRepeat:
return true; return true;
case QRhi::RedOrAlpha8IsRed:
return true;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
return false; return false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment