mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 14:18:31 +09:00
[Fix] (MG_Backend/DirectGLES): fix Complementary shaders on Mali
- emulate RGBA8 SNORM fallback writes
This commit is contained in:
@@ -184,6 +184,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
|
|
||||||
Flags<PixelFormatNormalizeOptionBit> GetDriverPixelFormatNormalizeOptions() {
|
Flags<PixelFormatNormalizeOptionBit> GetDriverPixelFormatNormalizeOptions() {
|
||||||
Flags<PixelFormatNormalizeOptionBit> options = PixelFormatNormalizeOptionBit::NoDepthComponent32;
|
Flags<PixelFormatNormalizeOptionBit> options = PixelFormatNormalizeOptionBit::NoDepthComponent32;
|
||||||
|
options |= PixelFormatNormalizeOptionBit::NoRGBA8Snorm;
|
||||||
if (!g_GLESCapabilities.SupportsNorm16Texture) {
|
if (!g_GLESCapabilities.SupportsNorm16Texture) {
|
||||||
options |= PixelFormatNormalizeOptionBit::NoNorm16;
|
options |= PixelFormatNormalizeOptionBit::NoNorm16;
|
||||||
}
|
}
|
||||||
@@ -207,6 +208,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
reasons.push_back(forced ? "SNORM8 fallback forced by backend policy"
|
reasons.push_back(forced ? "SNORM8 fallback forced by backend policy"
|
||||||
: "SNORM8 native path is not supported");
|
: "SNORM8 native path is not supported");
|
||||||
}
|
}
|
||||||
|
if (options & PixelFormatNormalizeOptionBit::NoRGBA8Snorm) {
|
||||||
|
reasons.push_back(forced ? "RGBA8_SNORM fallback forced by backend policy"
|
||||||
|
: "RGBA8_SNORM render target path is not supported");
|
||||||
|
}
|
||||||
if (options & PixelFormatNormalizeOptionBit::NoDepthComponent32) {
|
if (options & PixelFormatNormalizeOptionBit::NoDepthComponent32) {
|
||||||
reasons.push_back("GL_DEPTH_COMPONENT32 native probe failed on OpenGL ES");
|
reasons.push_back("GL_DEPTH_COMPONENT32 native probe failed on OpenGL ES");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -711,7 +711,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
backendObj = MakeShared<BackendProgramObjectImpl>();
|
backendObj = MakeShared<BackendProgramObjectImpl>();
|
||||||
backendObj->SyncToBackend(currentProgram);
|
backendObj->SyncToBackend(currentProgram);
|
||||||
} else {
|
} else {
|
||||||
if (!backendObj->GetBackendProgramId()) {
|
if (!backendObj->GetBackendProgramId() ||
|
||||||
|
backendObj->GetRGBA8SnormClampOutputMask() != g_rgba8SnormClampOutputMask) {
|
||||||
backendObj->SyncToBackend(currentProgram);
|
backendObj->SyncToBackend(currentProgram);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1316,6 +1316,22 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Bool IsRGBA8SnormFallbackAttachment(
|
||||||
|
const MG_State::GLState::FramebufferAttachmentObject& attachmentObject) {
|
||||||
|
if (attachmentObject.IsTexture()) {
|
||||||
|
const auto& textureObject = attachmentObject.GetTexture();
|
||||||
|
return textureObject && textureObject->GetFormat() == TextureInternalFormat::RGBA8Snorm &&
|
||||||
|
TextureImpl::ShouldUseCaveatTextureFormat(textureObject->GetFormat(), textureObject->GetTarget());
|
||||||
|
}
|
||||||
|
if (attachmentObject.IsRenderbuffer()) {
|
||||||
|
const auto& renderbufferObject = attachmentObject.GetRenderbuffer();
|
||||||
|
return renderbufferObject &&
|
||||||
|
renderbufferObject->GetInternalFormat() == TextureInternalFormat::RGBA8Snorm &&
|
||||||
|
TextureImpl::ShouldUseCaveatRenderbufferFormat(renderbufferObject->GetInternalFormat());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void BackendFramebufferObject::SyncToBackend(
|
void BackendFramebufferObject::SyncToBackend(
|
||||||
const SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject, FramebufferTarget asTarget) {
|
const SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject, FramebufferTarget asTarget) {
|
||||||
#ifdef TRACY_ENABLE
|
#ifdef TRACY_ENABLE
|
||||||
@@ -1366,6 +1382,22 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
g_GLESFuncs.glDrawBuffers(nEffectiveBuffers, m_backendDrawBuffers);
|
g_GLESFuncs.glDrawBuffers(nEffectiveBuffers, m_backendDrawBuffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (asTarget == FramebufferTarget::Draw) {
|
||||||
|
Uint32 clampOutputMask = 0;
|
||||||
|
for (Uint i = 0; i < FramebufferObject::MAX_DRAW_BUFFERS && i < 32; ++i) {
|
||||||
|
const auto frontendBuf = stateDrawBuffers[i];
|
||||||
|
if (frontendBuf < FramebufferAttachmentType::Color0 ||
|
||||||
|
frontendBuf > FramebufferAttachmentType::Color31) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto& attachmentObject = stateFBOObject->GetAttachment(frontendBuf);
|
||||||
|
if (IsRGBA8SnormFallbackAttachment(attachmentObject)) {
|
||||||
|
clampOutputMask |= (1u << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PrgramImpl::g_rgba8SnormClampOutputMask = clampOutputMask;
|
||||||
|
}
|
||||||
|
|
||||||
// 2. Remap read buffer
|
// 2. Remap read buffer
|
||||||
auto frontendReadBuf = stateFBOObject->GetReadBuffer();
|
auto frontendReadBuf = stateFBOObject->GetReadBuffer();
|
||||||
if (frontendReadBuf != m_frontendReadBuffer) {
|
if (frontendReadBuf != m_frontendReadBuffer) {
|
||||||
@@ -1478,6 +1510,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
} // namespace FramebufferImpl
|
} // namespace FramebufferImpl
|
||||||
|
|
||||||
namespace PrgramImpl {
|
namespace PrgramImpl {
|
||||||
|
Uint32 g_rgba8SnormClampOutputMask = 0;
|
||||||
StateBackendObjectRegistry<MG_State::GLState::ProgramObject, BackendProgramObjectImpl> g_backendProgramObjects;
|
StateBackendObjectRegistry<MG_State::GLState::ProgramObject, BackendProgramObjectImpl> g_backendProgramObjects;
|
||||||
|
|
||||||
BackendProgramObjectImpl::BackendProgramObjectImpl() {
|
BackendProgramObjectImpl::BackendProgramObjectImpl() {
|
||||||
@@ -1522,6 +1555,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
|
|
||||||
MGLOG_D("Syncing program to backend. State program ID: %u, Backend ID: %u",
|
MGLOG_D("Syncing program to backend. State program ID: %u, Backend ID: %u",
|
||||||
stateProgramObject->GetExternalIndex(), m_backendProgramId);
|
stateProgramObject->GetExternalIndex(), m_backendProgramId);
|
||||||
|
m_rgba8SnormClampOutputMask = g_rgba8SnormClampOutputMask;
|
||||||
|
|
||||||
// Detach all existing shaders
|
// Detach all existing shaders
|
||||||
GLint attachedCount = 0;
|
GLint attachedCount = 0;
|
||||||
@@ -1597,6 +1631,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
source = ForceFlatIntegerVaryings(source, glShaderType);
|
source = ForceFlatIntegerVaryings(source, glShaderType);
|
||||||
source = EmulateBaseInstanceInVertexShader(std::move(source), glShaderType);
|
source = EmulateBaseInstanceInVertexShader(std::move(source), glShaderType);
|
||||||
source = ForceSupporterOutput(source);
|
source = ForceSupporterOutput(source);
|
||||||
|
source = ClampRGBA8SnormFallbackOutputs(std::move(source), glShaderType,
|
||||||
|
m_rgba8SnormClampOutputMask);
|
||||||
|
|
||||||
// Patch for Photon compiler precision issue
|
// Patch for Photon compiler precision issue
|
||||||
String findStr = "1000000.0";
|
String findStr = "1000000.0";
|
||||||
|
|||||||
@@ -284,14 +284,17 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
void SetBaseInstance(Uint32 baseInstance) const;
|
void SetBaseInstance(Uint32 baseInstance) const;
|
||||||
Uint GetBackendProgramId() const { return m_backendProgramId; }
|
Uint GetBackendProgramId() const { return m_backendProgramId; }
|
||||||
Uint GetBackendGlobalUBOId() const { return m_backendGlobalUBOId; }
|
Uint GetBackendGlobalUBOId() const { return m_backendGlobalUBOId; }
|
||||||
|
Uint32 GetRGBA8SnormClampOutputMask() const { return m_rgba8SnormClampOutputMask; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Uint m_backendProgramId = 0;
|
Uint m_backendProgramId = 0;
|
||||||
Uint m_backendGlobalUBOId = 0;
|
Uint m_backendGlobalUBOId = 0;
|
||||||
Int m_baseInstanceUniformLocation = -1;
|
Int m_baseInstanceUniformLocation = -1;
|
||||||
|
Uint32 m_rgba8SnormClampOutputMask = 0;
|
||||||
Bool m_isInitialized = false;
|
Bool m_isInitialized = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern Uint32 g_rgba8SnormClampOutputMask;
|
||||||
extern StateBackendObjectRegistry<MG_State::GLState::ProgramObject, BackendProgramObjectImpl>
|
extern StateBackendObjectRegistry<MG_State::GLState::ProgramObject, BackendProgramObjectImpl>
|
||||||
g_backendProgramObjects;
|
g_backendProgramObjects;
|
||||||
} // namespace PrgramImpl
|
} // namespace PrgramImpl
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
|
|
||||||
Flags<PixelFormatNormalizeOptionBit> GetDriverPixelFormatNormalizeOptions() {
|
Flags<PixelFormatNormalizeOptionBit> GetDriverPixelFormatNormalizeOptions() {
|
||||||
Flags<PixelFormatNormalizeOptionBit> options = PixelFormatNormalizeOptionBit::NoDepthComponent32;
|
Flags<PixelFormatNormalizeOptionBit> options = PixelFormatNormalizeOptionBit::NoDepthComponent32;
|
||||||
|
options |= PixelFormatNormalizeOptionBit::NoRGBA8Snorm;
|
||||||
if (!g_GLESCapabilities.SupportsNorm16Texture) {
|
if (!g_GLESCapabilities.SupportsNorm16Texture) {
|
||||||
options |= PixelFormatNormalizeOptionBit::NoNorm16;
|
options |= PixelFormatNormalizeOptionBit::NoNorm16;
|
||||||
}
|
}
|
||||||
@@ -81,10 +82,15 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
|
|
||||||
Bool ShouldUseCaveatFormat(TextureInternalFormat internalFormat, SizeT targetIndex) {
|
Bool ShouldUseCaveatFormat(TextureInternalFormat internalFormat, SizeT targetIndex) {
|
||||||
if (targetIndex < kFormatCapabilityTargetCount) {
|
if (targetIndex < kFormatCapabilityTargetCount) {
|
||||||
if (HasCachedFormatCapability(internalFormat, targetIndex, false, FormatCapability::Creatable)) {
|
const Bool fullCreatable =
|
||||||
return false;
|
HasCachedFormatCapability(internalFormat, targetIndex, false, FormatCapability::Creatable);
|
||||||
}
|
const Bool caveatCreatable =
|
||||||
return HasCachedFormatCapability(internalFormat, targetIndex, true, FormatCapability::Creatable);
|
HasCachedFormatCapability(internalFormat, targetIndex, true, FormatCapability::Creatable);
|
||||||
|
const Bool fullRenderable =
|
||||||
|
HasCachedFormatCapability(internalFormat, targetIndex, false, FormatCapability::FramebufferRenderable);
|
||||||
|
const Bool caveatRenderable =
|
||||||
|
HasCachedFormatCapability(internalFormat, targetIndex, true, FormatCapability::FramebufferRenderable);
|
||||||
|
return (!fullCreatable && caveatCreatable) || (!fullRenderable && caveatRenderable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasAnyCachedFormatCapability(internalFormat, false, FormatCapability::Creatable)) {
|
if (HasAnyCachedFormatCapability(internalFormat, false, FormatCapability::Creatable)) {
|
||||||
@@ -127,6 +133,16 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
GenerateFormatInfo(internalFormat, GetRenderbufferFormatCapabilityTargetIndex(), outInternalFormat,
|
GenerateFormatInfo(internalFormat, GetRenderbufferFormatCapabilityTargetIndex(), outInternalFormat,
|
||||||
outFormat, outType);
|
outFormat, outType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bool ShouldUseCaveatTextureFormat(TextureInternalFormat internalFormat, TextureTarget target) {
|
||||||
|
const SizeT targetIndex =
|
||||||
|
target == TextureTarget::Unknown ? kFormatCapabilityTargetCount : GetFormatCapabilityTargetIndex(target);
|
||||||
|
return ShouldUseCaveatFormat(internalFormat, targetIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool ShouldUseCaveatRenderbufferFormat(TextureInternalFormat internalFormat) {
|
||||||
|
return ShouldUseCaveatFormat(internalFormat, GetRenderbufferFormatCapabilityTargetIndex());
|
||||||
|
}
|
||||||
} // namespace TextureImpl
|
} // namespace TextureImpl
|
||||||
namespace PrgramImpl {
|
namespace PrgramImpl {
|
||||||
String ProcessOutColorLocations(const String& glslCode) {
|
String ProcessOutColorLocations(const String& glslCode) {
|
||||||
@@ -197,6 +213,57 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String ClampRGBA8SnormFallbackOutputs(String glslCode, GLenum shaderType, Uint32 outputMask) {
|
||||||
|
#ifdef TRACY_ENABLE
|
||||||
|
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
|
||||||
|
#endif
|
||||||
|
if (shaderType != GL_FRAGMENT_SHADER || outputMask == 0) {
|
||||||
|
return glslCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::regex outputPattern(
|
||||||
|
R"(layout\s*\(\s*location\s*=\s*([0-9]+)\s*\)\s*out\s+(?:(?:lowp|mediump|highp)\s+)?vec4\s+([A-Za-z_][A-Za-z0-9_]*)\s*;)");
|
||||||
|
std::sregex_iterator outputIt(glslCode.begin(), glslCode.end(), outputPattern);
|
||||||
|
std::sregex_iterator outputEnd;
|
||||||
|
Vector<String> outputNames;
|
||||||
|
for (; outputIt != outputEnd; ++outputIt) {
|
||||||
|
const Uint location = static_cast<Uint>(std::stoul((*outputIt)[1].str()));
|
||||||
|
if (location < 32 && (outputMask & (1u << location))) {
|
||||||
|
outputNames.push_back((*outputIt)[2].str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (outputNames.empty()) {
|
||||||
|
return glslCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::regex mainPattern(R"(void\s+main\s*\([^)]*\)\s*\{)");
|
||||||
|
std::smatch mainMatch;
|
||||||
|
if (!std::regex_search(glslCode, mainMatch, mainPattern)) {
|
||||||
|
return glslCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
SizeT bracePos = static_cast<SizeT>(mainMatch.position(0) + mainMatch.length(0) - 1);
|
||||||
|
Int depth = 0;
|
||||||
|
for (SizeT pos = bracePos; pos < glslCode.size(); ++pos) {
|
||||||
|
if (glslCode[pos] == '{') {
|
||||||
|
++depth;
|
||||||
|
} else if (glslCode[pos] == '}') {
|
||||||
|
--depth;
|
||||||
|
if (depth == 0) {
|
||||||
|
String clampLine;
|
||||||
|
for (const String& outputName : outputNames) {
|
||||||
|
clampLine += "\n " + outputName + " = clamp(" + outputName +
|
||||||
|
", vec4(-1.0), vec4(1.0));";
|
||||||
|
}
|
||||||
|
clampLine += "\n";
|
||||||
|
glslCode.insert(pos, clampLine);
|
||||||
|
return glslCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return glslCode;
|
||||||
|
}
|
||||||
|
|
||||||
String ForceFlatIntegerVaryings(const String& glslCode, GLenum shaderType) {
|
String ForceFlatIntegerVaryings(const String& glslCode, GLenum shaderType) {
|
||||||
#ifdef TRACY_ENABLE
|
#ifdef TRACY_ENABLE
|
||||||
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
|
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
TextureTarget target = TextureTarget::Unknown);
|
TextureTarget target = TextureTarget::Unknown);
|
||||||
void GenerateRenderbufferFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat,
|
void GenerateRenderbufferFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat,
|
||||||
GLenum* outFormat, GLenum* outType);
|
GLenum* outFormat, GLenum* outType);
|
||||||
|
Bool ShouldUseCaveatTextureFormat(TextureInternalFormat internalFormat, TextureTarget target);
|
||||||
|
Bool ShouldUseCaveatRenderbufferFormat(TextureInternalFormat internalFormat);
|
||||||
} // namespace TextureImpl
|
} // namespace TextureImpl
|
||||||
|
|
||||||
namespace FramebufferImpl {} // namespace FramebufferImpl
|
namespace FramebufferImpl {} // namespace FramebufferImpl
|
||||||
@@ -46,6 +48,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
namespace PrgramImpl {
|
namespace PrgramImpl {
|
||||||
String ProcessOutColorLocations(const String& glslCode);
|
String ProcessOutColorLocations(const String& glslCode);
|
||||||
String ForceSupporterOutput(const String& glslCode);
|
String ForceSupporterOutput(const String& glslCode);
|
||||||
|
String ClampRGBA8SnormFallbackOutputs(String glslCode, GLenum shaderType, Uint32 outputMask);
|
||||||
String ForceFlatIntegerVaryings(const String& glslCode, GLenum shaderType);
|
String ForceFlatIntegerVaryings(const String& glslCode, GLenum shaderType);
|
||||||
String RemoveLayoutBinding(const String& glslCode);
|
String RemoveLayoutBinding(const String& glslCode);
|
||||||
} // namespace PrgramImpl
|
} // namespace PrgramImpl
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ namespace MobileGL::MG_Util::TextureFormatProcessor {
|
|||||||
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoSnorm16;
|
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoSnorm16;
|
||||||
break;
|
break;
|
||||||
case GL_RGBA8_SNORM:
|
case GL_RGBA8_SNORM:
|
||||||
|
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoSnorm8;
|
||||||
|
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoRGBA8Snorm;
|
||||||
|
break;
|
||||||
case GL_RGB8_SNORM:
|
case GL_RGB8_SNORM:
|
||||||
case GL_RG8_SNORM:
|
case GL_RG8_SNORM:
|
||||||
case GL_R8_SNORM:
|
case GL_R8_SNORM:
|
||||||
@@ -123,7 +126,8 @@ namespace MobileGL::MG_Util::TextureFormatProcessor {
|
|||||||
*outInternalFormat = internalFormat;
|
*outInternalFormat = internalFormat;
|
||||||
break;
|
break;
|
||||||
case GL_RGBA8_SNORM:
|
case GL_RGBA8_SNORM:
|
||||||
if (options & PixelFormatNormalizeOptionBit::NoSnorm8) {
|
if ((options & PixelFormatNormalizeOptionBit::NoSnorm8) ||
|
||||||
|
(options & PixelFormatNormalizeOptionBit::NoRGBA8Snorm)) {
|
||||||
*outInternalFormat = GL_RGBA16F;
|
*outInternalFormat = GL_RGBA16F;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -360,7 +364,6 @@ namespace MobileGL::MG_Util::TextureFormatProcessor {
|
|||||||
*outType = GL_SHORT;
|
*outType = GL_SHORT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GL_RGBA8_SNORM:
|
|
||||||
case GL_RGB8_SNORM:
|
case GL_RGB8_SNORM:
|
||||||
case GL_RG8_SNORM:
|
case GL_RG8_SNORM:
|
||||||
case GL_R8_SNORM:
|
case GL_R8_SNORM:
|
||||||
@@ -370,6 +373,14 @@ namespace MobileGL::MG_Util::TextureFormatProcessor {
|
|||||||
}
|
}
|
||||||
*outType = GL_BYTE;
|
*outType = GL_BYTE;
|
||||||
break;
|
break;
|
||||||
|
case GL_RGBA8_SNORM:
|
||||||
|
if ((options & PixelFormatNormalizeOptionBit::NoSnorm8) ||
|
||||||
|
(options & PixelFormatNormalizeOptionBit::NoRGBA8Snorm)) {
|
||||||
|
*outType = GL_FLOAT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*outType = GL_BYTE;
|
||||||
|
break;
|
||||||
|
|
||||||
// Color Unsigned Integer
|
// Color Unsigned Integer
|
||||||
case GL_RGBA32UI:
|
case GL_RGBA32UI:
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ namespace MobileGL {
|
|||||||
NoRgb16 = 1 << 2,
|
NoRgb16 = 1 << 2,
|
||||||
NoSnorm8 = 1 << 3,
|
NoSnorm8 = 1 << 3,
|
||||||
NoDepthComponent32 = 1 << 4,
|
NoDepthComponent32 = 1 << 4,
|
||||||
|
NoRGBA8Snorm = 1 << 5,
|
||||||
None = 0,
|
None = 0,
|
||||||
};
|
};
|
||||||
namespace MG_Util::TextureFormatProcessor {
|
namespace MG_Util::TextureFormatProcessor {
|
||||||
|
|||||||
Reference in New Issue
Block a user