mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
[Fix] (DirectGLES): forward an integer border colour through glTexParameterIiv/glSamplerParameterIiv instead of flattening it to float
This commit is contained in:
@@ -4605,12 +4605,36 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
|
||||
// GL_TEXTURE_BORDER_COLOR needs ES 3.2 or EXT/OES_texture_border_clamp; on a driver
|
||||
// without it every such call is INVALID_ENUM, so the parameter is simply not synced.
|
||||
//
|
||||
// The FORM has to be forwarded along with the value. A border colour set through
|
||||
// glTexParameterIiv/Iuiv is an integer one, and an isampler2D/usampler2D fetch of the
|
||||
// border returns whatever the driver's integer border register holds - so pushing it
|
||||
// through glTexParameterfv handed the driver float 255.0 and the shader read back
|
||||
// 1132396544, the bit pattern of that float. glTexParameterIiv/Iuiv are ES 3.2 core
|
||||
// beside GL_TEXTURE_BORDER_COLOR itself, so they sit behind the same capability gate;
|
||||
// the entry-point null check covers a driver that advertises the extension without them.
|
||||
const auto borderColorForm = stateTextureObject->GetBorderColorForm();
|
||||
if (!isMultisampleTarget && g_GLESCapabilities.SupportsTextureBorderClamp &&
|
||||
m_cacheBorderColor != stateTextureObject->GetBorderColor()) {
|
||||
(m_cacheBorderColor != stateTextureObject->GetBorderColor() ||
|
||||
m_cacheBorderColorForm != borderColorForm)) {
|
||||
if (borderColorForm == BorderColorForm::Int && g_GLESFuncs.glTexParameterIiv) {
|
||||
const auto& borderColorI = stateTextureObject->GetBorderColorI();
|
||||
const GLint borderColorArray[4] = {borderColorI.x(), borderColorI.y(), borderColorI.z(),
|
||||
borderColorI.w()};
|
||||
g_GLESFuncs.glTexParameterIiv(target, GL_TEXTURE_BORDER_COLOR, borderColorArray);
|
||||
} else if (borderColorForm == BorderColorForm::Uint && g_GLESFuncs.glTexParameterIuiv) {
|
||||
const auto& borderColorUI = stateTextureObject->GetBorderColorUI();
|
||||
const GLuint borderColorArray[4] = {borderColorUI.x(), borderColorUI.y(), borderColorUI.z(),
|
||||
borderColorUI.w()};
|
||||
g_GLESFuncs.glTexParameterIuiv(target, GL_TEXTURE_BORDER_COLOR, borderColorArray);
|
||||
} else {
|
||||
const auto& borderColor = stateTextureObject->GetBorderColor();
|
||||
GLfloat borderColorArray[4] = {borderColor.x(), borderColor.y(), borderColor.z(), borderColor.w()};
|
||||
const GLfloat borderColorArray[4] = {borderColor.x(), borderColor.y(), borderColor.z(),
|
||||
borderColor.w()};
|
||||
g_GLESFuncs.glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, borderColorArray);
|
||||
m_cacheBorderColor = borderColor;
|
||||
}
|
||||
m_cacheBorderColor = stateTextureObject->GetBorderColor();
|
||||
m_cacheBorderColorForm = borderColorForm;
|
||||
DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
|
||||
MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
|
||||
});
|
||||
@@ -7916,15 +7940,39 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
}
|
||||
m_cacheSamplerParameters.maxAnisotropy = samplerParams.maxAnisotropy;
|
||||
}
|
||||
if (m_cacheSamplerParameters.borderColor != samplerParams.borderColor) {
|
||||
// Same gate as the texture-side border colour above.
|
||||
if (g_GLESCapabilities.SupportsTextureBorderClamp && g_GLESFuncs.glSamplerParameterfv) {
|
||||
if (m_cacheSamplerParameters.borderColor != samplerParams.borderColor ||
|
||||
m_cacheSamplerParameters.borderColorForm != samplerParams.borderColorForm) {
|
||||
// Same gate as the texture-side border colour above, and the same reason for
|
||||
// branching on the form: an integer border colour must reach the driver through
|
||||
// glSamplerParameterIiv/Iuiv or an integer sampler reads the float's bit pattern
|
||||
// back instead of the value.
|
||||
if (g_GLESCapabilities.SupportsTextureBorderClamp) {
|
||||
if (samplerParams.borderColorForm == BorderColorForm::Int &&
|
||||
g_GLESFuncs.glSamplerParameterIiv) {
|
||||
const GLint borderColorArray[4] = {
|
||||
samplerParams.borderColorI.x(), samplerParams.borderColorI.y(),
|
||||
samplerParams.borderColorI.z(), samplerParams.borderColorI.w()};
|
||||
g_GLESFuncs.glSamplerParameterIiv(m_backendSamplerId, GL_TEXTURE_BORDER_COLOR,
|
||||
borderColorArray);
|
||||
} else if (samplerParams.borderColorForm == BorderColorForm::Uint &&
|
||||
g_GLESFuncs.glSamplerParameterIuiv) {
|
||||
const GLuint borderColorArray[4] = {
|
||||
samplerParams.borderColorUI.x(), samplerParams.borderColorUI.y(),
|
||||
samplerParams.borderColorUI.z(), samplerParams.borderColorUI.w()};
|
||||
g_GLESFuncs.glSamplerParameterIuiv(m_backendSamplerId, GL_TEXTURE_BORDER_COLOR,
|
||||
borderColorArray);
|
||||
} else if (g_GLESFuncs.glSamplerParameterfv) {
|
||||
const GLfloat borderColorArray[4] = {
|
||||
samplerParams.borderColor.x(), samplerParams.borderColor.y(),
|
||||
samplerParams.borderColor.z(), samplerParams.borderColor.w()};
|
||||
g_GLESFuncs.glSamplerParameterfv(m_backendSamplerId, GL_TEXTURE_BORDER_COLOR, borderColorArray);
|
||||
g_GLESFuncs.glSamplerParameterfv(m_backendSamplerId, GL_TEXTURE_BORDER_COLOR,
|
||||
borderColorArray);
|
||||
}
|
||||
}
|
||||
m_cacheSamplerParameters.borderColor = samplerParams.borderColor;
|
||||
m_cacheSamplerParameters.borderColorI = samplerParams.borderColorI;
|
||||
m_cacheSamplerParameters.borderColorUI = samplerParams.borderColorUI;
|
||||
m_cacheSamplerParameters.borderColorForm = samplerParams.borderColorForm;
|
||||
}
|
||||
#undef SYNC_SAMPLER_PARAM_IF_CHANGED
|
||||
m_isInitialized = true;
|
||||
|
||||
@@ -1051,6 +1051,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
SamplerParameters m_cacheSamplerParameters;
|
||||
UintVec2 m_cacheLodRange = {0, 1000};
|
||||
FloatVec4 m_cacheBorderColor = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
// Which border-colour entry point the driver texture last received. Cached beside the
|
||||
// value because a Float -> Int transition can leave the numbers unchanged (the derived
|
||||
// representations are kept in step) while still needing a different driver call.
|
||||
BorderColorForm m_cacheBorderColorForm = BorderColorForm::Float;
|
||||
Vec4<TextureSwizzleParam> m_cacheSwizzleParams = {TextureSwizzleParam::Red, TextureSwizzleParam::Green,
|
||||
TextureSwizzleParam::Blue, TextureSwizzleParam::Alpha};
|
||||
// GL_DEPTH_STENCIL_TEXTURE_MODE. GL_DEPTH_COMPONENT is the GL and ES default, so a
|
||||
|
||||
Reference in New Issue
Block a user