mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +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;
|
||||
}
|
||||
|
||||
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,
|
||||
TextureTarget target,
|
||||
GLuint texture,
|
||||
@@ -335,6 +451,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
FormatCapabilityCache& cache,
|
||||
const DynamicBackendParameters& dynamicParameters) {
|
||||
cache.Clear();
|
||||
const Flags<PixelFormatNormalizeOptionBit> forcedOptions = GetForcedPixelFormatNormalizeOptions();
|
||||
const Flags<PixelFormatNormalizeOptionBit> driverOptions = GetDriverPixelFormatNormalizeOptions();
|
||||
|
||||
for (SizeT formatIndex = 0; formatIndex < kFormatCapabilityFormatCount; ++formatIndex) {
|
||||
const auto logicalFormat = static_cast<TextureInternalFormat>(formatIndex);
|
||||
GLenum requestedInternalFormat = MG_Util::ConvertTextureInternalFormatToGLEnum(logicalFormat);
|
||||
@@ -342,55 +461,71 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
continue;
|
||||
}
|
||||
|
||||
GLenum backendInternalFormat = requestedInternalFormat;
|
||||
GLenum imageFormat = GL_RGBA;
|
||||
GLenum imageType = GL_UNSIGNED_BYTE;
|
||||
TextureImpl::GenerateTextureFormatInfo(logicalFormat, &backendInternalFormat, &imageFormat,
|
||||
&imageType);
|
||||
const Bool isCaveat = backendInternalFormat != requestedInternalFormat;
|
||||
const GLESProbeFormatInfo nativeInfo = BuildNativeProbeFormatInfo(requestedInternalFormat);
|
||||
GLESProbeFormatInfo fallbackInfo;
|
||||
const Bool hasForcedFallback =
|
||||
BuildFallbackProbeFormatInfo(requestedInternalFormat, forcedOptions, fallbackInfo);
|
||||
if (!hasForcedFallback) {
|
||||
BuildFallbackProbeFormatInfo(requestedInternalFormat, driverOptions, fallbackInfo);
|
||||
}
|
||||
|
||||
for (SizeT targetIndex = 0; targetIndex < kFormatCapabilityTextureTargetCount; ++targetIndex) {
|
||||
const auto target = static_cast<TextureTarget>(targetIndex);
|
||||
Bool renderable = false;
|
||||
if (!ProbeTexture(gl, target, backendInternalFormat, imageFormat, imageType, logicalFormat,
|
||||
&renderable)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
Bool shouldProbeFallback = hasForcedFallback;
|
||||
if (!hasForcedFallback) {
|
||||
Bool nativeRenderable = false;
|
||||
const Bool nativeCreated =
|
||||
ProbeTexture(gl, target, nativeInfo.InternalFormat, nativeInfo.ImageFormat,
|
||||
nativeInfo.ImageType, logicalFormat, &nativeRenderable);
|
||||
if (nativeCreated) {
|
||||
AddFullFormatCaps(cache, targetIndex, formatIndex,
|
||||
BuildTextureCapsFromProbe(logicalFormat, target, nativeRenderable));
|
||||
if (IsGLESProbeMultisampleTarget(target)) {
|
||||
cache.SampleCounts[targetIndex][formatIndex] = {1};
|
||||
}
|
||||
}
|
||||
shouldProbeFallback = !nativeCreated || !nativeRenderable;
|
||||
}
|
||||
auto& table = isCaveat ? cache.CaveatCaps : cache.FullCaps;
|
||||
table[targetIndex][formatIndex] |= caps;
|
||||
|
||||
if (IsGLESProbeMultisampleTarget(target)) {
|
||||
cache.SampleCounts[targetIndex][formatIndex] = {1};
|
||||
if (shouldProbeFallback && fallbackInfo.InternalFormat != GL_UNKNOWN_MGL) {
|
||||
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();
|
||||
if (ProbeRenderbuffer(gl, backendInternalFormat, logicalFormat, false, 1)) {
|
||||
auto& table = isCaveat ? cache.CaveatCaps : cache.FullCaps;
|
||||
table[renderbufferTargetIndex][formatIndex] |= GetRenderbufferFeatureCaps(logicalFormat);
|
||||
|
||||
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;
|
||||
Int maxSamples = dynamicParameters.MaxColorTextureSamples;
|
||||
if (isDepth || isStencil) {
|
||||
maxSamples = dynamicParameters.MaxDepthTextureSamples;
|
||||
} else if (isInteger) {
|
||||
maxSamples = dynamicParameters.MaxIntegerSamples;
|
||||
Bool shouldProbeFallbackRenderbuffer = hasForcedFallback;
|
||||
if (!hasForcedFallback) {
|
||||
const Bool nativeRenderbufferComplete =
|
||||
ProbeRenderbuffer(gl, nativeInfo.InternalFormat, logicalFormat, false, 1);
|
||||
if (nativeRenderbufferComplete) {
|
||||
AddFullFormatCaps(cache, renderbufferTargetIndex, formatIndex,
|
||||
GetRenderbufferFeatureCaps(logicalFormat));
|
||||
const Int maxSamples =
|
||||
GetGLESFormatMaxSamples(dynamicParameters, logicalFormat, nativeInfo.ImageFormat);
|
||||
cache.SampleCounts[renderbufferTargetIndex][formatIndex] =
|
||||
ProbeRenderbufferSampleCounts(gl, nativeInfo.InternalFormat, logicalFormat, maxSamples);
|
||||
} else {
|
||||
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] =
|
||||
ProbeRenderbufferSampleCounts(gl, backendInternalFormat, logicalFormat, maxSamples);
|
||||
ProbeRenderbufferSampleCounts(gl, fallbackInfo.InternalFormat, logicalFormat, maxSamples);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2041,7 +2041,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
auto mgInternalFormat = textureObject->GetFormat();
|
||||
GLenum format = GL_DEPTH_COMPONENT;
|
||||
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,
|
||||
"%s: cannot GenerateTextureFormatInfo(%s): out internalformat=%s, format=%s, type=%s",
|
||||
MG_Util::ConvertTextureInternalFormatToString(mgInternalFormat).c_str(),
|
||||
@@ -2269,9 +2270,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
if (copyImageError == GL_NO_ERROR) {
|
||||
return;
|
||||
}
|
||||
MOBILEGL_ASSERT(copyImageError == GL_INVALID_ENUM,
|
||||
"glCopyImageSubData failed: %s",
|
||||
MG_Util::ConvertGLEnumToString(copyImageError).c_str());
|
||||
MOBILEGL_ASSERT(IsColorOnlyFormat(srcTexture->GetFormat()) && IsColorOnlyFormat(dstTexture->GetFormat()),
|
||||
"DirectGLES CopyImageSubData only supports color-only or depth-only copies.");
|
||||
MOBILEGL_ASSERT(srcTarget == GL_TEXTURE_2D && dstTarget == GL_TEXTURE_2D,
|
||||
|
||||
@@ -708,7 +708,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
|
||||
GLenum glInternalFormat, glType, glFormat;
|
||||
TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat,
|
||||
&glFormat, &glType);
|
||||
&glFormat, &glType, targetInternal);
|
||||
|
||||
const auto& uploadTargets = textureMipmapObject->GetUploadTargets();
|
||||
ScopedDefaultUnpackState unpackState;
|
||||
@@ -771,7 +771,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// Regenerate all mipmap levels
|
||||
GLenum glInternalFormat, glType, glFormat;
|
||||
TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat,
|
||||
&glFormat, &glType);
|
||||
&glFormat, &glType, targetInternal);
|
||||
|
||||
const auto& uploadTargets = textureMipmapObject->GetUploadTargets();
|
||||
if (TextureImpl::IsMultisampleTextureTarget(targetInternal)) {
|
||||
@@ -884,7 +884,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
const auto mipmapCount = textureMipmapObject->GetMipmapLevelCount();
|
||||
GLenum glInternalFormat, glType, glFormat;
|
||||
TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat,
|
||||
&glFormat, &glType);
|
||||
&glFormat, &glType, targetInternal);
|
||||
const auto& uploadTargets = textureMipmapObject->GetUploadTargets();
|
||||
ScopedDefaultUnpackState unpackState;
|
||||
for (auto& uploadTarget : uploadTargets) {
|
||||
@@ -980,7 +980,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
|
||||
GLenum glInternalFormat, glType, glFormat;
|
||||
TextureImpl::GenerateTextureFormatInfo(textureBufferObject->GetFormat(), &glInternalFormat, &glFormat,
|
||||
&glType);
|
||||
&glType, TextureTarget::TextureBuffer);
|
||||
|
||||
if (needsRegeneration) {
|
||||
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 samples = static_cast<Int>(stateRBOObject->GetSamples());
|
||||
GLenum glInternalFormat, glType, glFormat;
|
||||
TextureImpl::GenerateTextureFormatInfo(internalFormat, &glInternalFormat, &glFormat, &glType);
|
||||
TextureImpl::GenerateRenderbufferFormatInfo(internalFormat, &glInternalFormat, &glFormat, &glType);
|
||||
|
||||
if (samples > 0) {
|
||||
g_GLESFuncs.glRenderbufferStorageMultisample(
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "DirectGLES.h"
|
||||
#include "Utils.h"
|
||||
#include "Managers.h"
|
||||
#include "MG_Backend/BackendObjects.h"
|
||||
#include "MG_Util/Converters/GLToMG/FramebufferEnumConverter.h"
|
||||
#include "MG_Util/Texture/TextureFormatProcessor.h"
|
||||
|
||||
@@ -19,23 +20,112 @@
|
||||
#include <MG_Util/Converters/MGToGL/FramebufferEnumConverter.h>
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectGLES {
|
||||
namespace TextureImpl {
|
||||
void GenerateTextureFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat,
|
||||
GLenum* outFormat, GLenum* outType) {
|
||||
#ifdef TRACY_ENABLE
|
||||
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
|
||||
#endif
|
||||
using namespace MobileGL::MG_Util::TextureFormatProcessor;
|
||||
Flags<PixelFormatNormalizeOptionBit> options =
|
||||
(g_GLESCapabilities.SupportsNorm16Texture) ? PixelFormatNormalizeOptionBit::None
|
||||
: PixelFormatNormalizeOptionBit::NoNorm16;
|
||||
namespace {
|
||||
Flags<PixelFormatNormalizeOptionBit> GetForcedPixelFormatNormalizeOptions() {
|
||||
Flags<PixelFormatNormalizeOptionBit> options;
|
||||
if (g_GLESCapabilities.GLESRendererString.find("ANGLE") != String::npos) {
|
||||
options |= PixelFormatNormalizeOptionBit::NoRgb16;
|
||||
options |= PixelFormatNormalizeOptionBit::NoSnorm16;
|
||||
options |= PixelFormatNormalizeOptionBit::NoSnorm8;
|
||||
}
|
||||
NormalizePixelFormat(MG_Util::ConvertTextureInternalFormatToGLEnum(internalFormat), options,
|
||||
outInternalFormat, outFormat, outType);
|
||||
return options;
|
||||
}
|
||||
|
||||
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 PrgramImpl {
|
||||
|
||||
@@ -35,7 +35,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
|
||||
namespace TextureImpl {
|
||||
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 FramebufferImpl {} // namespace FramebufferImpl
|
||||
|
||||
@@ -10,6 +10,42 @@
|
||||
#include "MG_Util/Converters/GLToStr/GLEnumConverter.h"
|
||||
|
||||
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,
|
||||
GLenum* outInternalFormat, GLenum* outFormat, GLenum* outType) {
|
||||
#ifdef TRACY_ENABLE
|
||||
@@ -19,7 +55,11 @@ namespace MobileGL::MG_Util::TextureFormatProcessor {
|
||||
if (outInternalFormat) {
|
||||
switch (internalFormat) {
|
||||
case GL_DEPTH_COMPONENT32:
|
||||
*outInternalFormat = GL_DEPTH_COMPONENT;
|
||||
if (options & PixelFormatNormalizeOptionBit::NoDepthComponent32) {
|
||||
*outInternalFormat = GL_DEPTH_COMPONENT;
|
||||
break;
|
||||
}
|
||||
*outInternalFormat = internalFormat;
|
||||
break;
|
||||
case GL_RGBA16:
|
||||
if (options & PixelFormatNormalizeOptionBit::NoNorm16) {
|
||||
|
||||
@@ -15,9 +15,13 @@ namespace MobileGL {
|
||||
NoSnorm16 = 1 << 1,
|
||||
NoRgb16 = 1 << 2,
|
||||
NoSnorm8 = 1 << 3,
|
||||
NoDepthComponent32 = 1 << 4,
|
||||
None = 0,
|
||||
};
|
||||
namespace MG_Util::TextureFormatProcessor {
|
||||
Flags<PixelFormatNormalizeOptionBit>
|
||||
GetApplicablePixelFormatNormalizeOptions(GLenum internalFormat,
|
||||
Flags<PixelFormatNormalizeOptionBit> options);
|
||||
void NormalizePixelFormat(GLenum internalFormat, Flags<PixelFormatNormalizeOptionBit> options,
|
||||
GLenum* outInternalFormat, GLenum* outFormat, GLenum* outType);
|
||||
} // namespace MG_Util::TextureFormatProcessor
|
||||
|
||||
Reference in New Issue
Block a user