mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Fix] (MG_Backend/DirectGLES): make format caveats probe-driven
This commit is contained in:
@@ -136,6 +136,122 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
FormatCapability::MultisampleRenderbuffer;
|
FormatCapability::MultisampleRenderbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct GLESProbeFormatInfo {
|
||||||
|
GLenum InternalFormat = GL_UNKNOWN_MGL;
|
||||||
|
GLenum ImageFormat = GL_RGBA;
|
||||||
|
GLenum ImageType = GL_UNSIGNED_BYTE;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr FormatCapability kGLESProbeCapabilities[] = {
|
||||||
|
FormatCapability::Creatable,
|
||||||
|
FormatCapability::Sampled,
|
||||||
|
FormatCapability::LinearFilter,
|
||||||
|
FormatCapability::GenerateMipmap,
|
||||||
|
FormatCapability::TextureGather,
|
||||||
|
FormatCapability::TextureShadow,
|
||||||
|
FormatCapability::FramebufferRenderable,
|
||||||
|
FormatCapability::FramebufferLayered,
|
||||||
|
FormatCapability::MultisampleTexture,
|
||||||
|
FormatCapability::MultisampleRenderbuffer,
|
||||||
|
FormatCapability::ColorAttachment,
|
||||||
|
FormatCapability::DepthAttachment,
|
||||||
|
FormatCapability::StencilAttachment,
|
||||||
|
FormatCapability::TextureBuffer,
|
||||||
|
};
|
||||||
|
|
||||||
|
GLESProbeFormatInfo BuildNativeProbeFormatInfo(GLenum requestedInternalFormat) {
|
||||||
|
GLESProbeFormatInfo info;
|
||||||
|
info.InternalFormat = requestedInternalFormat;
|
||||||
|
MG_Util::TextureFormatProcessor::NormalizePixelFormat(
|
||||||
|
requestedInternalFormat, PixelFormatNormalizeOptionBit::None, nullptr, &info.ImageFormat,
|
||||||
|
&info.ImageType);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
Flags<PixelFormatNormalizeOptionBit> GetForcedPixelFormatNormalizeOptions() {
|
||||||
|
Flags<PixelFormatNormalizeOptionBit> options;
|
||||||
|
if (g_GLESCapabilities.GLESRendererString.find("ANGLE") != String::npos) {
|
||||||
|
options |= PixelFormatNormalizeOptionBit::NoRgb16;
|
||||||
|
options |= PixelFormatNormalizeOptionBit::NoSnorm16;
|
||||||
|
options |= PixelFormatNormalizeOptionBit::NoSnorm8;
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
Flags<PixelFormatNormalizeOptionBit> GetDriverPixelFormatNormalizeOptions() {
|
||||||
|
Flags<PixelFormatNormalizeOptionBit> options = PixelFormatNormalizeOptionBit::NoDepthComponent32;
|
||||||
|
if (!g_GLESCapabilities.SupportsNorm16Texture) {
|
||||||
|
options |= PixelFormatNormalizeOptionBit::NoNorm16;
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool BuildFallbackProbeFormatInfo(GLenum requestedInternalFormat,
|
||||||
|
Flags<PixelFormatNormalizeOptionBit> options,
|
||||||
|
GLESProbeFormatInfo& outInfo) {
|
||||||
|
const Flags<PixelFormatNormalizeOptionBit> applicableOptions =
|
||||||
|
MG_Util::TextureFormatProcessor::GetApplicablePixelFormatNormalizeOptions(requestedInternalFormat,
|
||||||
|
options);
|
||||||
|
if (!applicableOptions) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MG_Util::TextureFormatProcessor::NormalizePixelFormat(requestedInternalFormat, applicableOptions,
|
||||||
|
&outInfo.InternalFormat, &outInfo.ImageFormat,
|
||||||
|
&outInfo.ImageType);
|
||||||
|
return outInfo.InternalFormat != GL_UNKNOWN_MGL;
|
||||||
|
}
|
||||||
|
|
||||||
|
FormatCapabilityFlags BuildTextureCapsFromProbe(TextureInternalFormat logicalFormat,
|
||||||
|
TextureTarget target,
|
||||||
|
Bool renderable) {
|
||||||
|
FormatCapabilityFlags caps = GetTextureFeatureCaps(logicalFormat, target);
|
||||||
|
if (renderable) {
|
||||||
|
caps |= GetAttachmentCaps(logicalFormat);
|
||||||
|
if (target == TextureTarget::Texture3D || target == TextureTarget::Texture2DArray ||
|
||||||
|
target == TextureTarget::TextureCubeMapArray ||
|
||||||
|
target == TextureTarget::Texture2DMultisampleArray) {
|
||||||
|
caps |= FormatCapability::FramebufferLayered;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return caps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddFullFormatCaps(FormatCapabilityCache& cache,
|
||||||
|
SizeT targetIndex,
|
||||||
|
SizeT formatIndex,
|
||||||
|
FormatCapabilityFlags caps) {
|
||||||
|
cache.FullCaps[targetIndex][formatIndex] |= caps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddCaveatFormatCaps(FormatCapabilityCache& cache,
|
||||||
|
SizeT targetIndex,
|
||||||
|
SizeT formatIndex,
|
||||||
|
FormatCapabilityFlags caps) {
|
||||||
|
for (FormatCapability capability : kGLESProbeCapabilities) {
|
||||||
|
if (HasFormatCapability(caps, capability) &&
|
||||||
|
!HasFormatCapability(cache.FullCaps[targetIndex][formatIndex], capability)) {
|
||||||
|
cache.CaveatCaps[targetIndex][formatIndex] |= capability;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Int GetGLESFormatMaxSamples(const DynamicBackendParameters& dynamicParameters,
|
||||||
|
TextureInternalFormat logicalFormat,
|
||||||
|
GLenum imageFormat) {
|
||||||
|
const Bool isDepth = MG_Util::IsDepthFormatInternalFormat(logicalFormat);
|
||||||
|
const Bool isStencil = MG_Util::IsStencilFormatInternalFormat(logicalFormat);
|
||||||
|
const Bool isInteger = imageFormat == GL_RED_INTEGER || imageFormat == GL_RG_INTEGER ||
|
||||||
|
imageFormat == GL_RGB_INTEGER || imageFormat == GL_RGBA_INTEGER;
|
||||||
|
if (isDepth || isStencil) {
|
||||||
|
return dynamicParameters.MaxDepthTextureSamples;
|
||||||
|
}
|
||||||
|
if (isInteger) {
|
||||||
|
return dynamicParameters.MaxIntegerSamples;
|
||||||
|
}
|
||||||
|
return dynamicParameters.MaxColorTextureSamples;
|
||||||
|
}
|
||||||
|
|
||||||
Bool ProbeFramebufferCompletenessForTexture(const MG_External::GLESFunctionsTable& gl,
|
Bool ProbeFramebufferCompletenessForTexture(const MG_External::GLESFunctionsTable& gl,
|
||||||
TextureTarget target,
|
TextureTarget target,
|
||||||
GLuint texture,
|
GLuint texture,
|
||||||
@@ -335,6 +451,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
FormatCapabilityCache& cache,
|
FormatCapabilityCache& cache,
|
||||||
const DynamicBackendParameters& dynamicParameters) {
|
const DynamicBackendParameters& dynamicParameters) {
|
||||||
cache.Clear();
|
cache.Clear();
|
||||||
|
const Flags<PixelFormatNormalizeOptionBit> forcedOptions = GetForcedPixelFormatNormalizeOptions();
|
||||||
|
const Flags<PixelFormatNormalizeOptionBit> driverOptions = GetDriverPixelFormatNormalizeOptions();
|
||||||
|
|
||||||
for (SizeT formatIndex = 0; formatIndex < kFormatCapabilityFormatCount; ++formatIndex) {
|
for (SizeT formatIndex = 0; formatIndex < kFormatCapabilityFormatCount; ++formatIndex) {
|
||||||
const auto logicalFormat = static_cast<TextureInternalFormat>(formatIndex);
|
const auto logicalFormat = static_cast<TextureInternalFormat>(formatIndex);
|
||||||
GLenum requestedInternalFormat = MG_Util::ConvertTextureInternalFormatToGLEnum(logicalFormat);
|
GLenum requestedInternalFormat = MG_Util::ConvertTextureInternalFormatToGLEnum(logicalFormat);
|
||||||
@@ -342,55 +461,71 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum backendInternalFormat = requestedInternalFormat;
|
const GLESProbeFormatInfo nativeInfo = BuildNativeProbeFormatInfo(requestedInternalFormat);
|
||||||
GLenum imageFormat = GL_RGBA;
|
GLESProbeFormatInfo fallbackInfo;
|
||||||
GLenum imageType = GL_UNSIGNED_BYTE;
|
const Bool hasForcedFallback =
|
||||||
TextureImpl::GenerateTextureFormatInfo(logicalFormat, &backendInternalFormat, &imageFormat,
|
BuildFallbackProbeFormatInfo(requestedInternalFormat, forcedOptions, fallbackInfo);
|
||||||
&imageType);
|
if (!hasForcedFallback) {
|
||||||
const Bool isCaveat = backendInternalFormat != requestedInternalFormat;
|
BuildFallbackProbeFormatInfo(requestedInternalFormat, driverOptions, fallbackInfo);
|
||||||
|
}
|
||||||
|
|
||||||
for (SizeT targetIndex = 0; targetIndex < kFormatCapabilityTextureTargetCount; ++targetIndex) {
|
for (SizeT targetIndex = 0; targetIndex < kFormatCapabilityTextureTargetCount; ++targetIndex) {
|
||||||
const auto target = static_cast<TextureTarget>(targetIndex);
|
const auto target = static_cast<TextureTarget>(targetIndex);
|
||||||
Bool renderable = false;
|
Bool shouldProbeFallback = hasForcedFallback;
|
||||||
if (!ProbeTexture(gl, target, backendInternalFormat, imageFormat, imageType, logicalFormat,
|
if (!hasForcedFallback) {
|
||||||
&renderable)) {
|
Bool nativeRenderable = false;
|
||||||
continue;
|
const Bool nativeCreated =
|
||||||
}
|
ProbeTexture(gl, target, nativeInfo.InternalFormat, nativeInfo.ImageFormat,
|
||||||
|
nativeInfo.ImageType, logicalFormat, &nativeRenderable);
|
||||||
FormatCapabilityFlags caps = GetTextureFeatureCaps(logicalFormat, target);
|
if (nativeCreated) {
|
||||||
if (renderable) {
|
AddFullFormatCaps(cache, targetIndex, formatIndex,
|
||||||
caps |= GetAttachmentCaps(logicalFormat);
|
BuildTextureCapsFromProbe(logicalFormat, target, nativeRenderable));
|
||||||
if (target == TextureTarget::Texture3D || target == TextureTarget::Texture2DArray ||
|
if (IsGLESProbeMultisampleTarget(target)) {
|
||||||
target == TextureTarget::TextureCubeMapArray ||
|
cache.SampleCounts[targetIndex][formatIndex] = {1};
|
||||||
target == TextureTarget::Texture2DMultisampleArray) {
|
}
|
||||||
caps |= FormatCapability::FramebufferLayered;
|
|
||||||
}
|
}
|
||||||
|
shouldProbeFallback = !nativeCreated || !nativeRenderable;
|
||||||
}
|
}
|
||||||
auto& table = isCaveat ? cache.CaveatCaps : cache.FullCaps;
|
|
||||||
table[targetIndex][formatIndex] |= caps;
|
|
||||||
|
|
||||||
if (IsGLESProbeMultisampleTarget(target)) {
|
if (shouldProbeFallback && fallbackInfo.InternalFormat != GL_UNKNOWN_MGL) {
|
||||||
cache.SampleCounts[targetIndex][formatIndex] = {1};
|
Bool fallbackRenderable = false;
|
||||||
|
const Bool fallbackCreated =
|
||||||
|
ProbeTexture(gl, target, fallbackInfo.InternalFormat, fallbackInfo.ImageFormat,
|
||||||
|
fallbackInfo.ImageType, logicalFormat, &fallbackRenderable);
|
||||||
|
if (fallbackCreated) {
|
||||||
|
AddCaveatFormatCaps(cache, targetIndex, formatIndex,
|
||||||
|
BuildTextureCapsFromProbe(logicalFormat, target, fallbackRenderable));
|
||||||
|
if (IsGLESProbeMultisampleTarget(target)) {
|
||||||
|
cache.SampleCounts[targetIndex][formatIndex] = {1};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const SizeT renderbufferTargetIndex = GetRenderbufferFormatCapabilityTargetIndex();
|
const SizeT renderbufferTargetIndex = GetRenderbufferFormatCapabilityTargetIndex();
|
||||||
if (ProbeRenderbuffer(gl, backendInternalFormat, logicalFormat, false, 1)) {
|
Bool shouldProbeFallbackRenderbuffer = hasForcedFallback;
|
||||||
auto& table = isCaveat ? cache.CaveatCaps : cache.FullCaps;
|
if (!hasForcedFallback) {
|
||||||
table[renderbufferTargetIndex][formatIndex] |= GetRenderbufferFeatureCaps(logicalFormat);
|
const Bool nativeRenderbufferComplete =
|
||||||
|
ProbeRenderbuffer(gl, nativeInfo.InternalFormat, logicalFormat, false, 1);
|
||||||
const Bool isDepth = MG_Util::IsDepthFormatInternalFormat(logicalFormat);
|
if (nativeRenderbufferComplete) {
|
||||||
const Bool isStencil = MG_Util::IsStencilFormatInternalFormat(logicalFormat);
|
AddFullFormatCaps(cache, renderbufferTargetIndex, formatIndex,
|
||||||
const Bool isInteger = imageFormat == GL_RED_INTEGER || imageFormat == GL_RG_INTEGER ||
|
GetRenderbufferFeatureCaps(logicalFormat));
|
||||||
imageFormat == GL_RGB_INTEGER || imageFormat == GL_RGBA_INTEGER;
|
const Int maxSamples =
|
||||||
Int maxSamples = dynamicParameters.MaxColorTextureSamples;
|
GetGLESFormatMaxSamples(dynamicParameters, logicalFormat, nativeInfo.ImageFormat);
|
||||||
if (isDepth || isStencil) {
|
cache.SampleCounts[renderbufferTargetIndex][formatIndex] =
|
||||||
maxSamples = dynamicParameters.MaxDepthTextureSamples;
|
ProbeRenderbufferSampleCounts(gl, nativeInfo.InternalFormat, logicalFormat, maxSamples);
|
||||||
} else if (isInteger) {
|
} else {
|
||||||
maxSamples = dynamicParameters.MaxIntegerSamples;
|
shouldProbeFallbackRenderbuffer = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (shouldProbeFallbackRenderbuffer && fallbackInfo.InternalFormat != GL_UNKNOWN_MGL &&
|
||||||
|
ProbeRenderbuffer(gl, fallbackInfo.InternalFormat, logicalFormat, false, 1)) {
|
||||||
|
AddCaveatFormatCaps(cache, renderbufferTargetIndex, formatIndex,
|
||||||
|
GetRenderbufferFeatureCaps(logicalFormat));
|
||||||
|
const Int maxSamples =
|
||||||
|
GetGLESFormatMaxSamples(dynamicParameters, logicalFormat, fallbackInfo.ImageFormat);
|
||||||
cache.SampleCounts[renderbufferTargetIndex][formatIndex] =
|
cache.SampleCounts[renderbufferTargetIndex][formatIndex] =
|
||||||
ProbeRenderbufferSampleCounts(gl, backendInternalFormat, logicalFormat, maxSamples);
|
ProbeRenderbufferSampleCounts(gl, fallbackInfo.InternalFormat, logicalFormat, maxSamples);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2041,7 +2041,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
auto mgInternalFormat = textureObject->GetFormat();
|
auto mgInternalFormat = textureObject->GetFormat();
|
||||||
GLenum format = GL_DEPTH_COMPONENT;
|
GLenum format = GL_DEPTH_COMPONENT;
|
||||||
GLenum type = GL_UNSIGNED_INT;
|
GLenum type = GL_UNSIGNED_INT;
|
||||||
TextureImpl::GenerateTextureFormatInfo(mgInternalFormat, &internalformat, &format, &type);
|
TextureImpl::GenerateTextureFormatInfo(mgInternalFormat, &internalformat, &format, &type,
|
||||||
|
MG_Util::ConvertGLEnumToTextureTarget(target));
|
||||||
MOBILEGL_ASSERT(format != GL_NONE && type != GL_NONE,
|
MOBILEGL_ASSERT(format != GL_NONE && type != GL_NONE,
|
||||||
"%s: cannot GenerateTextureFormatInfo(%s): out internalformat=%s, format=%s, type=%s",
|
"%s: cannot GenerateTextureFormatInfo(%s): out internalformat=%s, format=%s, type=%s",
|
||||||
MG_Util::ConvertTextureInternalFormatToString(mgInternalFormat).c_str(),
|
MG_Util::ConvertTextureInternalFormatToString(mgInternalFormat).c_str(),
|
||||||
@@ -2269,9 +2270,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
if (copyImageError == GL_NO_ERROR) {
|
if (copyImageError == GL_NO_ERROR) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MOBILEGL_ASSERT(copyImageError == GL_INVALID_ENUM,
|
|
||||||
"glCopyImageSubData failed: %s",
|
|
||||||
MG_Util::ConvertGLEnumToString(copyImageError).c_str());
|
|
||||||
MOBILEGL_ASSERT(IsColorOnlyFormat(srcTexture->GetFormat()) && IsColorOnlyFormat(dstTexture->GetFormat()),
|
MOBILEGL_ASSERT(IsColorOnlyFormat(srcTexture->GetFormat()) && IsColorOnlyFormat(dstTexture->GetFormat()),
|
||||||
"DirectGLES CopyImageSubData only supports color-only or depth-only copies.");
|
"DirectGLES CopyImageSubData only supports color-only or depth-only copies.");
|
||||||
MOBILEGL_ASSERT(srcTarget == GL_TEXTURE_2D && dstTarget == GL_TEXTURE_2D,
|
MOBILEGL_ASSERT(srcTarget == GL_TEXTURE_2D && dstTarget == GL_TEXTURE_2D,
|
||||||
|
|||||||
@@ -708,7 +708,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
|
|
||||||
GLenum glInternalFormat, glType, glFormat;
|
GLenum glInternalFormat, glType, glFormat;
|
||||||
TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat,
|
TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat,
|
||||||
&glFormat, &glType);
|
&glFormat, &glType, targetInternal);
|
||||||
|
|
||||||
const auto& uploadTargets = textureMipmapObject->GetUploadTargets();
|
const auto& uploadTargets = textureMipmapObject->GetUploadTargets();
|
||||||
ScopedDefaultUnpackState unpackState;
|
ScopedDefaultUnpackState unpackState;
|
||||||
@@ -771,7 +771,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
// Regenerate all mipmap levels
|
// Regenerate all mipmap levels
|
||||||
GLenum glInternalFormat, glType, glFormat;
|
GLenum glInternalFormat, glType, glFormat;
|
||||||
TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat,
|
TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat,
|
||||||
&glFormat, &glType);
|
&glFormat, &glType, targetInternal);
|
||||||
|
|
||||||
const auto& uploadTargets = textureMipmapObject->GetUploadTargets();
|
const auto& uploadTargets = textureMipmapObject->GetUploadTargets();
|
||||||
if (TextureImpl::IsMultisampleTextureTarget(targetInternal)) {
|
if (TextureImpl::IsMultisampleTextureTarget(targetInternal)) {
|
||||||
@@ -884,7 +884,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
const auto mipmapCount = textureMipmapObject->GetMipmapLevelCount();
|
const auto mipmapCount = textureMipmapObject->GetMipmapLevelCount();
|
||||||
GLenum glInternalFormat, glType, glFormat;
|
GLenum glInternalFormat, glType, glFormat;
|
||||||
TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat,
|
TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat,
|
||||||
&glFormat, &glType);
|
&glFormat, &glType, targetInternal);
|
||||||
const auto& uploadTargets = textureMipmapObject->GetUploadTargets();
|
const auto& uploadTargets = textureMipmapObject->GetUploadTargets();
|
||||||
ScopedDefaultUnpackState unpackState;
|
ScopedDefaultUnpackState unpackState;
|
||||||
for (auto& uploadTarget : uploadTargets) {
|
for (auto& uploadTarget : uploadTargets) {
|
||||||
@@ -980,7 +980,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
|
|
||||||
GLenum glInternalFormat, glType, glFormat;
|
GLenum glInternalFormat, glType, glFormat;
|
||||||
TextureImpl::GenerateTextureFormatInfo(textureBufferObject->GetFormat(), &glInternalFormat, &glFormat,
|
TextureImpl::GenerateTextureFormatInfo(textureBufferObject->GetFormat(), &glInternalFormat, &glFormat,
|
||||||
&glType);
|
&glType, TextureTarget::TextureBuffer);
|
||||||
|
|
||||||
if (needsRegeneration) {
|
if (needsRegeneration) {
|
||||||
MGLOG_D("Texture state changed significantly or not initialized, regenerating texture buffer with "
|
MGLOG_D("Texture state changed significantly or not initialized, regenerating texture buffer with "
|
||||||
@@ -1832,7 +1832,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
Int height = static_cast<Int>(stateRBOObject->GetHeight());
|
Int height = static_cast<Int>(stateRBOObject->GetHeight());
|
||||||
Int samples = static_cast<Int>(stateRBOObject->GetSamples());
|
Int samples = static_cast<Int>(stateRBOObject->GetSamples());
|
||||||
GLenum glInternalFormat, glType, glFormat;
|
GLenum glInternalFormat, glType, glFormat;
|
||||||
TextureImpl::GenerateTextureFormatInfo(internalFormat, &glInternalFormat, &glFormat, &glType);
|
TextureImpl::GenerateRenderbufferFormatInfo(internalFormat, &glInternalFormat, &glFormat, &glType);
|
||||||
|
|
||||||
if (samples > 0) {
|
if (samples > 0) {
|
||||||
g_GLESFuncs.glRenderbufferStorageMultisample(
|
g_GLESFuncs.glRenderbufferStorageMultisample(
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "DirectGLES.h"
|
#include "DirectGLES.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "Managers.h"
|
#include "Managers.h"
|
||||||
|
#include "MG_Backend/BackendObjects.h"
|
||||||
#include "MG_Util/Converters/GLToMG/FramebufferEnumConverter.h"
|
#include "MG_Util/Converters/GLToMG/FramebufferEnumConverter.h"
|
||||||
#include "MG_Util/Texture/TextureFormatProcessor.h"
|
#include "MG_Util/Texture/TextureFormatProcessor.h"
|
||||||
|
|
||||||
@@ -19,23 +20,112 @@
|
|||||||
#include <MG_Util/Converters/MGToGL/FramebufferEnumConverter.h>
|
#include <MG_Util/Converters/MGToGL/FramebufferEnumConverter.h>
|
||||||
|
|
||||||
namespace MobileGL::MG_Backend::DirectGLES {
|
namespace MobileGL::MG_Backend::DirectGLES {
|
||||||
namespace TextureImpl {
|
namespace {
|
||||||
void GenerateTextureFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat,
|
Flags<PixelFormatNormalizeOptionBit> GetForcedPixelFormatNormalizeOptions() {
|
||||||
GLenum* outFormat, GLenum* outType) {
|
Flags<PixelFormatNormalizeOptionBit> options;
|
||||||
#ifdef TRACY_ENABLE
|
|
||||||
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
|
|
||||||
#endif
|
|
||||||
using namespace MobileGL::MG_Util::TextureFormatProcessor;
|
|
||||||
Flags<PixelFormatNormalizeOptionBit> options =
|
|
||||||
(g_GLESCapabilities.SupportsNorm16Texture) ? PixelFormatNormalizeOptionBit::None
|
|
||||||
: PixelFormatNormalizeOptionBit::NoNorm16;
|
|
||||||
if (g_GLESCapabilities.GLESRendererString.find("ANGLE") != String::npos) {
|
if (g_GLESCapabilities.GLESRendererString.find("ANGLE") != String::npos) {
|
||||||
options |= PixelFormatNormalizeOptionBit::NoRgb16;
|
options |= PixelFormatNormalizeOptionBit::NoRgb16;
|
||||||
options |= PixelFormatNormalizeOptionBit::NoSnorm16;
|
options |= PixelFormatNormalizeOptionBit::NoSnorm16;
|
||||||
options |= PixelFormatNormalizeOptionBit::NoSnorm8;
|
options |= PixelFormatNormalizeOptionBit::NoSnorm8;
|
||||||
}
|
}
|
||||||
NormalizePixelFormat(MG_Util::ConvertTextureInternalFormatToGLEnum(internalFormat), options,
|
return options;
|
||||||
outInternalFormat, outFormat, outType);
|
}
|
||||||
|
|
||||||
|
Flags<PixelFormatNormalizeOptionBit> GetDriverPixelFormatNormalizeOptions() {
|
||||||
|
Flags<PixelFormatNormalizeOptionBit> options = PixelFormatNormalizeOptionBit::NoDepthComponent32;
|
||||||
|
if (!g_GLESCapabilities.SupportsNorm16Texture) {
|
||||||
|
options |= PixelFormatNormalizeOptionBit::NoNorm16;
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
Flags<PixelFormatNormalizeOptionBit> GetRuntimeFallbackNormalizeOptions(GLenum requestedInternalFormat) {
|
||||||
|
using namespace MG_Util::TextureFormatProcessor;
|
||||||
|
const Flags<PixelFormatNormalizeOptionBit> forcedOptions =
|
||||||
|
GetApplicablePixelFormatNormalizeOptions(requestedInternalFormat, GetForcedPixelFormatNormalizeOptions());
|
||||||
|
if (forcedOptions) {
|
||||||
|
return forcedOptions;
|
||||||
|
}
|
||||||
|
return GetApplicablePixelFormatNormalizeOptions(requestedInternalFormat,
|
||||||
|
GetDriverPixelFormatNormalizeOptions());
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool HasCachedFormatCapability(TextureInternalFormat internalFormat,
|
||||||
|
SizeT targetIndex,
|
||||||
|
Bool caveat,
|
||||||
|
FormatCapability capability) {
|
||||||
|
if (!pActiveBackendObject || targetIndex >= kFormatCapabilityTargetCount) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const SizeT formatIndex = static_cast<SizeT>(internalFormat);
|
||||||
|
if (formatIndex >= kFormatCapabilityFormatCount) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FormatCapabilityCache& cache = pActiveBackendObject->GetFormatCapabilities();
|
||||||
|
const FormatCapabilityFlags caps =
|
||||||
|
caveat ? cache.CaveatCaps[targetIndex][formatIndex] : cache.FullCaps[targetIndex][formatIndex];
|
||||||
|
return HasFormatCapability(caps, capability);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool HasAnyCachedFormatCapability(TextureInternalFormat internalFormat,
|
||||||
|
Bool caveat,
|
||||||
|
FormatCapability capability) {
|
||||||
|
for (SizeT targetIndex = 0; targetIndex < kFormatCapabilityTargetCount; ++targetIndex) {
|
||||||
|
if (HasCachedFormatCapability(internalFormat, targetIndex, caveat, capability)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool ShouldUseCaveatFormat(TextureInternalFormat internalFormat, SizeT targetIndex) {
|
||||||
|
if (targetIndex < kFormatCapabilityTargetCount) {
|
||||||
|
if (HasCachedFormatCapability(internalFormat, targetIndex, false, FormatCapability::Creatable)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return HasCachedFormatCapability(internalFormat, targetIndex, true, FormatCapability::Creatable);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasAnyCachedFormatCapability(internalFormat, false, FormatCapability::Creatable)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return HasAnyCachedFormatCapability(internalFormat, true, FormatCapability::Creatable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateFormatInfo(TextureInternalFormat internalFormat,
|
||||||
|
SizeT targetIndex,
|
||||||
|
GLenum* outInternalFormat,
|
||||||
|
GLenum* outFormat,
|
||||||
|
GLenum* outType) {
|
||||||
|
using namespace MobileGL::MG_Util::TextureFormatProcessor;
|
||||||
|
const GLenum requestedInternalFormat = MG_Util::ConvertTextureInternalFormatToGLEnum(internalFormat);
|
||||||
|
Flags<PixelFormatNormalizeOptionBit> options;
|
||||||
|
if (!pActiveBackendObject || ShouldUseCaveatFormat(internalFormat, targetIndex)) {
|
||||||
|
options = GetRuntimeFallbackNormalizeOptions(requestedInternalFormat);
|
||||||
|
}
|
||||||
|
NormalizePixelFormat(requestedInternalFormat, options, outInternalFormat, outFormat, outType);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace TextureImpl {
|
||||||
|
void GenerateTextureFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat,
|
||||||
|
GLenum* outFormat, GLenum* outType, TextureTarget target) {
|
||||||
|
#ifdef TRACY_ENABLE
|
||||||
|
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
|
||||||
|
#endif
|
||||||
|
const SizeT targetIndex =
|
||||||
|
target == TextureTarget::Unknown ? kFormatCapabilityTargetCount : GetFormatCapabilityTargetIndex(target);
|
||||||
|
GenerateFormatInfo(internalFormat, targetIndex, outInternalFormat, outFormat, outType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateRenderbufferFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat,
|
||||||
|
GLenum* outFormat, GLenum* outType) {
|
||||||
|
#ifdef TRACY_ENABLE
|
||||||
|
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
|
||||||
|
#endif
|
||||||
|
GenerateFormatInfo(internalFormat, GetRenderbufferFormatCapabilityTargetIndex(), outInternalFormat,
|
||||||
|
outFormat, outType);
|
||||||
}
|
}
|
||||||
} // namespace TextureImpl
|
} // namespace TextureImpl
|
||||||
namespace PrgramImpl {
|
namespace PrgramImpl {
|
||||||
|
|||||||
@@ -35,7 +35,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
|
|
||||||
namespace TextureImpl {
|
namespace TextureImpl {
|
||||||
void GenerateTextureFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat,
|
void GenerateTextureFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat,
|
||||||
GLenum* outFormat, GLenum* outType);
|
GLenum* outFormat, GLenum* outType,
|
||||||
|
TextureTarget target = TextureTarget::Unknown);
|
||||||
|
void GenerateRenderbufferFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat,
|
||||||
|
GLenum* outFormat, GLenum* outType);
|
||||||
} // namespace TextureImpl
|
} // namespace TextureImpl
|
||||||
|
|
||||||
namespace FramebufferImpl {} // namespace FramebufferImpl
|
namespace FramebufferImpl {} // namespace FramebufferImpl
|
||||||
|
|||||||
@@ -10,6 +10,42 @@
|
|||||||
#include "MG_Util/Converters/GLToStr/GLEnumConverter.h"
|
#include "MG_Util/Converters/GLToStr/GLEnumConverter.h"
|
||||||
|
|
||||||
namespace MobileGL::MG_Util::TextureFormatProcessor {
|
namespace MobileGL::MG_Util::TextureFormatProcessor {
|
||||||
|
Flags<PixelFormatNormalizeOptionBit>
|
||||||
|
GetApplicablePixelFormatNormalizeOptions(GLenum internalFormat,
|
||||||
|
Flags<PixelFormatNormalizeOptionBit> options) {
|
||||||
|
Flags<PixelFormatNormalizeOptionBit> applicableOptions;
|
||||||
|
switch (internalFormat) {
|
||||||
|
case GL_DEPTH_COMPONENT32:
|
||||||
|
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoDepthComponent32;
|
||||||
|
break;
|
||||||
|
case GL_RGBA16:
|
||||||
|
case GL_RG16:
|
||||||
|
case GL_R16:
|
||||||
|
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoNorm16;
|
||||||
|
break;
|
||||||
|
case GL_RGB16:
|
||||||
|
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoNorm16;
|
||||||
|
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoRgb16;
|
||||||
|
break;
|
||||||
|
case GL_RGBA16_SNORM:
|
||||||
|
case GL_RGB16_SNORM:
|
||||||
|
case GL_RG16_SNORM:
|
||||||
|
case GL_R16_SNORM:
|
||||||
|
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoNorm16;
|
||||||
|
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoSnorm16;
|
||||||
|
break;
|
||||||
|
case GL_RGBA8_SNORM:
|
||||||
|
case GL_RGB8_SNORM:
|
||||||
|
case GL_RG8_SNORM:
|
||||||
|
case GL_R8_SNORM:
|
||||||
|
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoSnorm8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return applicableOptions;
|
||||||
|
}
|
||||||
|
|
||||||
void NormalizePixelFormat(GLenum internalFormat, Flags<PixelFormatNormalizeOptionBit> options,
|
void NormalizePixelFormat(GLenum internalFormat, Flags<PixelFormatNormalizeOptionBit> options,
|
||||||
GLenum* outInternalFormat, GLenum* outFormat, GLenum* outType) {
|
GLenum* outInternalFormat, GLenum* outFormat, GLenum* outType) {
|
||||||
#ifdef TRACY_ENABLE
|
#ifdef TRACY_ENABLE
|
||||||
@@ -19,7 +55,11 @@ namespace MobileGL::MG_Util::TextureFormatProcessor {
|
|||||||
if (outInternalFormat) {
|
if (outInternalFormat) {
|
||||||
switch (internalFormat) {
|
switch (internalFormat) {
|
||||||
case GL_DEPTH_COMPONENT32:
|
case GL_DEPTH_COMPONENT32:
|
||||||
*outInternalFormat = GL_DEPTH_COMPONENT;
|
if (options & PixelFormatNormalizeOptionBit::NoDepthComponent32) {
|
||||||
|
*outInternalFormat = GL_DEPTH_COMPONENT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*outInternalFormat = internalFormat;
|
||||||
break;
|
break;
|
||||||
case GL_RGBA16:
|
case GL_RGBA16:
|
||||||
if (options & PixelFormatNormalizeOptionBit::NoNorm16) {
|
if (options & PixelFormatNormalizeOptionBit::NoNorm16) {
|
||||||
|
|||||||
@@ -15,9 +15,13 @@ namespace MobileGL {
|
|||||||
NoSnorm16 = 1 << 1,
|
NoSnorm16 = 1 << 1,
|
||||||
NoRgb16 = 1 << 2,
|
NoRgb16 = 1 << 2,
|
||||||
NoSnorm8 = 1 << 3,
|
NoSnorm8 = 1 << 3,
|
||||||
|
NoDepthComponent32 = 1 << 4,
|
||||||
None = 0,
|
None = 0,
|
||||||
};
|
};
|
||||||
namespace MG_Util::TextureFormatProcessor {
|
namespace MG_Util::TextureFormatProcessor {
|
||||||
|
Flags<PixelFormatNormalizeOptionBit>
|
||||||
|
GetApplicablePixelFormatNormalizeOptions(GLenum internalFormat,
|
||||||
|
Flags<PixelFormatNormalizeOptionBit> options);
|
||||||
void NormalizePixelFormat(GLenum internalFormat, Flags<PixelFormatNormalizeOptionBit> options,
|
void NormalizePixelFormat(GLenum internalFormat, Flags<PixelFormatNormalizeOptionBit> options,
|
||||||
GLenum* outInternalFormat, GLenum* outFormat, GLenum* outType);
|
GLenum* outInternalFormat, GLenum* outFormat, GLenum* outType);
|
||||||
} // namespace MG_Util::TextureFormatProcessor
|
} // namespace MG_Util::TextureFormatProcessor
|
||||||
|
|||||||
Reference in New Issue
Block a user