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
\value NPOTTextureRepeat Indicates that the \l{QRhiSampler::Repeat}{Repeat}
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
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 RGBA8
\value BGRA8
\value R8
\value R16
\value D16
\value D32
\value RGBA8 Four component, unsigned normalized 8 bit per component. Always supported.
\value BGRA8 Four component, unsigned normalized 8 bit per component.
\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 BC2
\value BC3
......@@ -1875,9 +1891,11 @@ QRhiRenderBuffer::QRhiRenderBuffer(QRhiImplementation *rhi, Type type_, const QS
\value BC5
\value BC6H
\value BC7
\value ETC2_RGB8
\value ETC2_RGB8A1
\value ETC2_RGBA8
\value ASTC_4x4
\value ASTC_5x4
\value ASTC_5x5
......
......@@ -643,6 +643,7 @@ public:
BGRA8,
R8,
R16,
RED_OR_ALPHA8,
D16,
D32,
......@@ -1251,7 +1252,8 @@ public:
TessellationShaders,
NonDynamicUniformBuffers,
NonFourAlignedEffectiveIndexBufferOffset,
NPOTTextureRepeat
NPOTTextureRepeat,
RedOrAlpha8IsRed
};
enum BeginFrameFlag {
......
......@@ -181,7 +181,7 @@ public:
{
if (res->m_orphanedWithRsh) {
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 true;
......
......@@ -401,6 +401,8 @@ bool QRhiD3D11::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::NPOTTextureRepeat:
return true;
case QRhi::RedOrAlpha8IsRed:
return true;
default:
Q_UNREACHABLE();
return false;
......@@ -914,6 +916,8 @@ static inline DXGI_FORMAT toD3DTextureFormat(QRhiTexture::Format format, QRhiTex
return DXGI_FORMAT_R8_UNORM;
case QRhiTexture::R16:
return DXGI_FORMAT_R16_UNORM;
case QRhiTexture::RED_OR_ALPHA8:
return DXGI_FORMAT_R8_UNORM;
case QRhiTexture::D16:
return DXGI_FORMAT_R16_TYPELESS;
......
......@@ -157,6 +157,22 @@ QT_BEGIN_NAMESPACE
\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
#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
#endif
......@@ -290,6 +306,8 @@ bool QRhiGles2::create(QRhi::Flags flags)
if (n > 0)
f->glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, supportedCompressedFormats.data());
f->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.maxTextureSize);
caps.msaaRenderBuffer = f->hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)
&& f->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit);
......@@ -297,7 +315,7 @@ bool QRhiGles2::create(QRhi::Flags flags)
caps.npotTextureRepeat = f->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat);
const QSurfaceFormat actualFormat = ctx->format();
if (ctx->isOpenGLES())
if (actualFormat.renderableType() == QSurfaceFormat::OpenGLES)
caps.fixedIndexPrimitiveRestart = actualFormat.version() >= qMakePair(3, 0);
else
caps.fixedIndexPrimitiveRestart = actualFormat.version() >= qMakePair(4, 3);
......@@ -305,7 +323,11 @@ bool QRhiGles2::create(QRhi::Flags flags)
if (caps.fixedIndexPrimitiveRestart)
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;
......@@ -512,11 +534,13 @@ bool QRhiGles2::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture
return false;
case QRhiTexture::BGRA8:
Q_FALLTHROUGH();
return caps.bgraExternalFormat;
case QRhiTexture::R8:
Q_FALLTHROUGH();
return caps.sized8Formats;
case QRhiTexture::R16:
return false; // ###
return caps.sized16Formats;
default:
break;
......@@ -552,6 +576,8 @@ bool QRhiGles2::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::NPOTTextureRepeat:
return caps.npotTextureRepeat;
case QRhi::RedOrAlpha8IsRed:
return false;
default:
Q_UNREACHABLE();
return false;
......@@ -1504,7 +1530,6 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
break;
case QGles2CommandBuffer::Command::ReadPixels:
{
// ### more formats
QRhiReadbackResult *result = cmd.args.readPixels.result;
GLuint tex = cmd.args.readPixels.texture;
GLuint fbo = 0;
......@@ -2113,11 +2138,38 @@ bool QGles2Texture::prepareBuild(QSize *adjustedSize)
target = isCube ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
// ### more formats
glintformat = GL_RGBA;
glformat = GL_RGBA;
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;
if (isCompressed) {
......
......@@ -558,14 +558,29 @@ public:
QSurface *fallbackSurface = nullptr;
mutable bool needsMakeCurrent = false;
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
// the same as multisample textures!
bool msaaRenderBuffer = false;
bool npotTexture = true;
bool npotTextureRepeat = true;
bool fixedIndexPrimitiveRestart = false;
int maxTextureSize = 2048;
uint msaaRenderBuffer : 1;
uint npotTexture : 1;
uint npotTextureRepeat : 1;
uint fixedIndexPrimitiveRestart : 1;
uint bgraExternalFormat : 1;
uint bgraInternalFormat : 1;
uint sized8Formats : 1;
uint sized16Formats : 1;
} caps;
bool inFrame = false;
bool inPass = false;
......
......@@ -517,6 +517,8 @@ bool QRhiMetal::isFeatureSupported(QRhi::Feature feature) const
return false;
case QRhi::NPOTTextureRepeat:
return true;
case QRhi::RedOrAlpha8IsRed:
return true;
default:
Q_UNREACHABLE();
return false;
......@@ -1952,6 +1954,8 @@ static inline MTLPixelFormat toMetalTextureFormat(QRhiTexture::Format format, QR
#endif
case QRhiTexture::R16:
return MTLPixelFormatR16Unorm;
case QRhiTexture::RED_OR_ALPHA8:
return MTLPixelFormatR8Unorm;
case QRhiTexture::D16:
return MTLPixelFormatDepth16Unorm;
......
......@@ -704,6 +704,8 @@ static inline VkFormat toVkTextureFormat(QRhiTexture::Format format, QRhiTexture
return srgb ? VK_FORMAT_R8_SRGB : VK_FORMAT_R8_UNORM;
case QRhiTexture::R16:
return VK_FORMAT_R16_UNORM;
case QRhiTexture::RED_OR_ALPHA8:
return VK_FORMAT_R8_UNORM;
case QRhiTexture::D16:
return VK_FORMAT_D16_UNORM;
......@@ -3044,6 +3046,8 @@ bool QRhiVulkan::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::NPOTTextureRepeat:
return true;
case QRhi::RedOrAlpha8IsRed:
return true;
default:
Q_UNREACHABLE();
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