зеркало из https://github.com/AvaloniaUI/angle.git
GL: Work around drivers that generate mipmaps in linear color space
Mac drivers generate mipmaps in linear color space. To work around this, copy the sRGB texture to a linear texture, generate mipmaps and then copy back. TEST=conformance2/textures/misc/tex-srgb-mipmap.html BUG=angleproject:4646 Change-Id: I8675d0ab004bcd2985f685d64cbb84deff5f1c86 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2211083 Reviewed-by: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
This commit is contained in:
Родитель
9fa671d52b
Коммит
6080383848
|
@ -441,6 +441,13 @@ struct FeaturesGL : FeatureSetBase
|
||||||
Feature disableTimestampQueries = {
|
Feature disableTimestampQueries = {
|
||||||
"disable_timestamp_queries", FeatureCategory::OpenGLWorkarounds,
|
"disable_timestamp_queries", FeatureCategory::OpenGLWorkarounds,
|
||||||
"Disable GL_EXT_disjoint_timer_query extension", &members, "https://crbug.com/811661"};
|
"Disable GL_EXT_disjoint_timer_query extension", &members, "https://crbug.com/811661"};
|
||||||
|
|
||||||
|
// Some drivers use linear blending when generating mipmaps for sRGB textures. Work around this
|
||||||
|
// by generating mipmaps in a linear texture and copying back to sRGB.
|
||||||
|
Feature encodeAndDecodeSRGBForGenerateMipmap = {
|
||||||
|
"decode_encode_srgb_for_generatemipmap", FeatureCategory::OpenGLWorkarounds,
|
||||||
|
"Decode and encode before generateMipmap for srgb format textures.", &members,
|
||||||
|
"http://anglebug.com/4646"};
|
||||||
};
|
};
|
||||||
|
|
||||||
inline FeaturesGL::FeaturesGL() = default;
|
inline FeaturesGL::FeaturesGL() = default;
|
||||||
|
|
|
@ -988,6 +988,85 @@ angle::Result BlitGL::clearRenderableTextureAlphaToOne(const gl::Context *contex
|
||||||
return angle::Result::Continue;
|
return angle::Result::Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
angle::Result BlitGL::generateSRGBMipmap(const gl::Context *context,
|
||||||
|
TextureGL *source,
|
||||||
|
GLuint baseLevel,
|
||||||
|
GLuint levelCount,
|
||||||
|
const gl::Extents &sourceBaseLevelSize)
|
||||||
|
{
|
||||||
|
ANGLE_TRY(initializeResources(context));
|
||||||
|
|
||||||
|
const gl::TextureType sourceType = gl::TextureType::_2D;
|
||||||
|
const gl::TextureTarget sourceTarget = gl::TextureTarget::_2D;
|
||||||
|
|
||||||
|
ScopedGLState scopedState;
|
||||||
|
ANGLE_TRY(scopedState.enter(
|
||||||
|
context, gl::Rectangle(0, 0, sourceBaseLevelSize.width, sourceBaseLevelSize.height)));
|
||||||
|
scopedState.willUseTextureUnit(context, 0);
|
||||||
|
mStateManager->activeTexture(0);
|
||||||
|
|
||||||
|
// Copy source to a linear intermediate texture.
|
||||||
|
GLuint linearTexture = mScratchTextures[0];
|
||||||
|
mStateManager->bindTexture(sourceType, linearTexture);
|
||||||
|
ANGLE_GL_TRY(context, mFunctions->texImage2D(
|
||||||
|
ToGLenum(sourceTarget), 0, mSRGBMipmapGenerationFormat.internalFormat,
|
||||||
|
sourceBaseLevelSize.width, sourceBaseLevelSize.height, 0,
|
||||||
|
mSRGBMipmapGenerationFormat.format, mSRGBMipmapGenerationFormat.type,
|
||||||
|
nullptr));
|
||||||
|
|
||||||
|
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
|
||||||
|
ANGLE_GL_TRY(context,
|
||||||
|
mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
|
ToGLenum(sourceTarget), linearTexture, 0));
|
||||||
|
mStateManager->setFramebufferSRGBEnabled(context, true);
|
||||||
|
|
||||||
|
// Use a shader to do the sRGB to linear conversion. glBlitFramebuffer does not always do this
|
||||||
|
// conversion for us.
|
||||||
|
BlitProgram *blitProgram = nullptr;
|
||||||
|
ANGLE_TRY(getBlitProgram(context, sourceType, GL_FLOAT, GL_FLOAT, &blitProgram));
|
||||||
|
|
||||||
|
mStateManager->useProgram(blitProgram->program);
|
||||||
|
ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->sourceTextureLocation, 0));
|
||||||
|
ANGLE_GL_TRY(context, mFunctions->uniform2f(blitProgram->scaleLocation, 1.0f, 1.0f));
|
||||||
|
ANGLE_GL_TRY(context, mFunctions->uniform2f(blitProgram->offsetLocation, 0.0f, 0.0f));
|
||||||
|
ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->multiplyAlphaLocation, 0));
|
||||||
|
ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->unMultiplyAlphaLocation, 0));
|
||||||
|
|
||||||
|
mStateManager->bindTexture(sourceType, source->getTextureID());
|
||||||
|
ANGLE_TRY(source->setMinFilter(context, GL_NEAREST));
|
||||||
|
|
||||||
|
mStateManager->bindVertexArray(mVAO, 0);
|
||||||
|
ANGLE_GL_TRY(context, mFunctions->drawArrays(GL_TRIANGLES, 0, 3));
|
||||||
|
|
||||||
|
// Generate mipmaps on the linear texture
|
||||||
|
mStateManager->bindTexture(sourceType, linearTexture);
|
||||||
|
ANGLE_GL_TRY_ALWAYS_CHECK(context, mFunctions->generateMipmap(ToGLenum(sourceTarget)));
|
||||||
|
ANGLE_GL_TRY(context, mFunctions->texParameteri(ToGLenum(sourceTarget), GL_TEXTURE_MIN_FILTER,
|
||||||
|
GL_NEAREST));
|
||||||
|
|
||||||
|
// Copy back to the source texture from the mips generated in the linear texture
|
||||||
|
for (GLuint levelIdx = 0; levelIdx < levelCount; levelIdx++)
|
||||||
|
{
|
||||||
|
gl::Extents levelSize(std::max(sourceBaseLevelSize.width >> levelIdx, 1),
|
||||||
|
std::max(sourceBaseLevelSize.height >> levelIdx, 1), 1);
|
||||||
|
|
||||||
|
ANGLE_GL_TRY(context, mFunctions->framebufferTexture2D(
|
||||||
|
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ToGLenum(sourceTarget),
|
||||||
|
source->getTextureID(), baseLevel + levelIdx));
|
||||||
|
mStateManager->setViewport(gl::Rectangle(0, 0, levelSize.width, levelSize.height));
|
||||||
|
|
||||||
|
ANGLE_GL_TRY(context, mFunctions->texParameteri(ToGLenum(sourceTarget),
|
||||||
|
GL_TEXTURE_BASE_LEVEL, levelIdx));
|
||||||
|
|
||||||
|
ANGLE_GL_TRY(context, mFunctions->drawArrays(GL_TRIANGLES, 0, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
ANGLE_TRY(orphanScratchTextures(context));
|
||||||
|
|
||||||
|
ANGLE_TRY(scopedState.exit(context));
|
||||||
|
return angle::Result::Continue;
|
||||||
|
}
|
||||||
|
|
||||||
angle::Result BlitGL::initializeResources(const gl::Context *context)
|
angle::Result BlitGL::initializeResources(const gl::Context *context)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < ArraySize(mScratchTextures); i++)
|
for (size_t i = 0; i < ArraySize(mScratchTextures); i++)
|
||||||
|
@ -1038,6 +1117,27 @@ angle::Result BlitGL::initializeResources(const gl::Context *context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr GLenum potentialSRGBMipmapGenerationFormats[] = {
|
||||||
|
GL_RGBA16, GL_RGBA16F, GL_RGBA32F,
|
||||||
|
GL_RGBA8, // RGBA8 can have precision loss when generating mipmaps of a sRGBA8 texture
|
||||||
|
};
|
||||||
|
for (GLenum internalFormat : potentialSRGBMipmapGenerationFormats)
|
||||||
|
{
|
||||||
|
if (nativegl::SupportsNativeRendering(mFunctions, gl::TextureType::_2D, internalFormat))
|
||||||
|
{
|
||||||
|
const gl::InternalFormat &internalFormatInfo =
|
||||||
|
gl::GetSizedInternalFormatInfo(internalFormat);
|
||||||
|
|
||||||
|
// Pass the 'format' instead of 'internalFormat' to make sure we use unsized formats
|
||||||
|
// when available to increase support.
|
||||||
|
mSRGBMipmapGenerationFormat =
|
||||||
|
nativegl::GetTexImageFormat(mFunctions, mFeatures, internalFormatInfo.format,
|
||||||
|
internalFormatInfo.format, internalFormatInfo.type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ASSERT(mSRGBMipmapGenerationFormat.internalFormat != GL_NONE);
|
||||||
|
|
||||||
return angle::Result::Continue;
|
return angle::Result::Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1049,12 +1149,34 @@ angle::Result BlitGL::orphanScratchTextures(const gl::Context *context)
|
||||||
gl::PixelUnpackState unpack;
|
gl::PixelUnpackState unpack;
|
||||||
mStateManager->setPixelUnpackState(unpack);
|
mStateManager->setPixelUnpackState(unpack);
|
||||||
mStateManager->setPixelUnpackBuffer(nullptr);
|
mStateManager->setPixelUnpackBuffer(nullptr);
|
||||||
GLint swizzle[4] = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA};
|
if (mFunctions->isAtLeastGL(gl::Version(3, 3)))
|
||||||
|
{
|
||||||
|
constexpr GLint swizzle[4] = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA};
|
||||||
|
ANGLE_GL_TRY(context, mFunctions->texParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA,
|
||||||
|
swizzle));
|
||||||
|
}
|
||||||
|
else if (mFunctions->isAtLeastGLES(gl::Version(3, 0)))
|
||||||
|
{
|
||||||
|
ANGLE_GL_TRY(context,
|
||||||
|
mFunctions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED));
|
||||||
|
ANGLE_GL_TRY(context,
|
||||||
|
mFunctions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN));
|
||||||
|
ANGLE_GL_TRY(context,
|
||||||
|
mFunctions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE));
|
||||||
|
ANGLE_GL_TRY(context,
|
||||||
|
mFunctions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA));
|
||||||
|
}
|
||||||
|
|
||||||
|
ANGLE_GL_TRY(context, mFunctions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0));
|
||||||
|
ANGLE_GL_TRY(context, mFunctions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1000));
|
||||||
|
ANGLE_GL_TRY(context, mFunctions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||||
|
GL_NEAREST_MIPMAP_LINEAR));
|
||||||
ANGLE_GL_TRY(context,
|
ANGLE_GL_TRY(context,
|
||||||
mFunctions->texParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle));
|
mFunctions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||||
ANGLE_GL_TRY(context, mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA,
|
ANGLE_GL_TRY(context, mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA,
|
||||||
GL_UNSIGNED_BYTE, nullptr));
|
GL_UNSIGNED_BYTE, nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
return angle::Result::Continue;
|
return angle::Result::Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "common/angleutils.h"
|
#include "common/angleutils.h"
|
||||||
#include "libANGLE/Error.h"
|
#include "libANGLE/Error.h"
|
||||||
#include "libANGLE/angletypes.h"
|
#include "libANGLE/angletypes.h"
|
||||||
|
#include "libANGLE/renderer/gl/formatutilsgl.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
@ -136,6 +137,12 @@ class BlitGL : angle::NonCopyable
|
||||||
gl::TextureTarget target,
|
gl::TextureTarget target,
|
||||||
size_t level);
|
size_t level);
|
||||||
|
|
||||||
|
angle::Result generateSRGBMipmap(const gl::Context *context,
|
||||||
|
TextureGL *source,
|
||||||
|
GLuint baseLevel,
|
||||||
|
GLuint levelCount,
|
||||||
|
const gl::Extents &sourceBaseLevelSize);
|
||||||
|
|
||||||
angle::Result initializeResources(const gl::Context *context);
|
angle::Result initializeResources(const gl::Context *context);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -173,6 +180,8 @@ class BlitGL : angle::NonCopyable
|
||||||
|
|
||||||
GLuint mVAO;
|
GLuint mVAO;
|
||||||
GLuint mVertexBuffer;
|
GLuint mVertexBuffer;
|
||||||
|
|
||||||
|
nativegl::TexImageFormat mSRGBMipmapGenerationFormat;
|
||||||
};
|
};
|
||||||
} // namespace rx
|
} // namespace rx
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,7 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions,
|
||||||
mClearColor(0.0f, 0.0f, 0.0f, 0.0f),
|
mClearColor(0.0f, 0.0f, 0.0f, 0.0f),
|
||||||
mClearDepth(1.0f),
|
mClearDepth(1.0f),
|
||||||
mClearStencil(0),
|
mClearStencil(0),
|
||||||
|
mFramebufferSRGBAvailable(extensions.sRGBWriteControl),
|
||||||
mFramebufferSRGBEnabled(false),
|
mFramebufferSRGBEnabled(false),
|
||||||
mDitherEnabled(true),
|
mDitherEnabled(true),
|
||||||
mTextureCubemapSeamlessEnabled(false),
|
mTextureCubemapSeamlessEnabled(false),
|
||||||
|
@ -2071,7 +2072,7 @@ angle::Result StateManagerGL::syncState(const gl::Context *context,
|
||||||
|
|
||||||
void StateManagerGL::setFramebufferSRGBEnabled(const gl::Context *context, bool enabled)
|
void StateManagerGL::setFramebufferSRGBEnabled(const gl::Context *context, bool enabled)
|
||||||
{
|
{
|
||||||
if (!context->getExtensions().sRGBWriteControl)
|
if (!mFramebufferSRGBAvailable)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,7 +320,9 @@ class StateManagerGL final : angle::NonCopyable
|
||||||
float mClearDepth;
|
float mClearDepth;
|
||||||
GLint mClearStencil;
|
GLint mClearStencil;
|
||||||
|
|
||||||
|
bool mFramebufferSRGBAvailable;
|
||||||
bool mFramebufferSRGBEnabled;
|
bool mFramebufferSRGBEnabled;
|
||||||
|
|
||||||
bool mDitherEnabled;
|
bool mDitherEnabled;
|
||||||
bool mTextureCubemapSeamlessEnabled;
|
bool mTextureCubemapSeamlessEnabled;
|
||||||
|
|
||||||
|
|
|
@ -1240,15 +1240,57 @@ angle::Result TextureGL::setImageExternal(const gl::Context *context,
|
||||||
|
|
||||||
angle::Result TextureGL::generateMipmap(const gl::Context *context)
|
angle::Result TextureGL::generateMipmap(const gl::Context *context)
|
||||||
{
|
{
|
||||||
const FunctionsGL *functions = GetFunctionsGL(context);
|
const FunctionsGL *functions = GetFunctionsGL(context);
|
||||||
StateManagerGL *stateManager = GetStateManagerGL(context);
|
StateManagerGL *stateManager = GetStateManagerGL(context);
|
||||||
|
const angle::FeaturesGL &features = GetFeaturesGL(context);
|
||||||
stateManager->bindTexture(getType(), mTextureID);
|
|
||||||
ANGLE_GL_TRY_ALWAYS_CHECK(context, functions->generateMipmap(ToGLenum(getType())));
|
|
||||||
|
|
||||||
const GLuint effectiveBaseLevel = mState.getEffectiveBaseLevel();
|
const GLuint effectiveBaseLevel = mState.getEffectiveBaseLevel();
|
||||||
const GLuint maxLevel = mState.getMipmapMaxLevel();
|
const GLuint maxLevel = mState.getMipmapMaxLevel();
|
||||||
|
|
||||||
|
const gl::ImageDesc &baseLevelDesc = mState.getBaseLevelDesc();
|
||||||
|
const gl::InternalFormat &baseLevelInternalFormat = *baseLevelDesc.format.info;
|
||||||
|
|
||||||
|
stateManager->bindTexture(getType(), mTextureID);
|
||||||
|
if (baseLevelInternalFormat.colorEncoding == GL_SRGB &&
|
||||||
|
features.encodeAndDecodeSRGBForGenerateMipmap.enabled && getType() == gl::TextureType::_2D)
|
||||||
|
{
|
||||||
|
nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat(
|
||||||
|
functions, features, baseLevelInternalFormat.internalFormat,
|
||||||
|
baseLevelInternalFormat.format, baseLevelInternalFormat.type);
|
||||||
|
|
||||||
|
// Manually allocate the mip levels of this texture if they don't exist
|
||||||
|
GLuint levelCount = maxLevel - effectiveBaseLevel + 1;
|
||||||
|
for (GLuint levelIdx = 1; levelIdx < levelCount; levelIdx++)
|
||||||
|
{
|
||||||
|
gl::Extents levelSize(std::max(baseLevelDesc.size.width >> levelIdx, 1),
|
||||||
|
std::max(baseLevelDesc.size.height >> levelIdx, 1), 1);
|
||||||
|
|
||||||
|
const gl::ImageDesc &levelDesc =
|
||||||
|
mState.getImageDesc(gl::TextureTarget::_2D, effectiveBaseLevel + levelIdx);
|
||||||
|
|
||||||
|
// Make sure no pixel unpack buffer is bound
|
||||||
|
stateManager->bindBuffer(gl::BufferBinding::PixelUnpack, 0);
|
||||||
|
|
||||||
|
if (levelDesc.size != levelSize || *levelDesc.format.info != baseLevelInternalFormat)
|
||||||
|
{
|
||||||
|
ANGLE_GL_TRY_ALWAYS_CHECK(
|
||||||
|
context, functions->texImage2D(
|
||||||
|
ToGLenum(getType()), effectiveBaseLevel + levelIdx,
|
||||||
|
texImageFormat.internalFormat, levelSize.width, levelSize.height,
|
||||||
|
0, texImageFormat.format, texImageFormat.type, nullptr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the blitter to generate the mips
|
||||||
|
BlitGL *blitter = GetBlitGL(context);
|
||||||
|
ANGLE_TRY(blitter->generateSRGBMipmap(context, this, effectiveBaseLevel, levelCount,
|
||||||
|
baseLevelDesc.size));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ANGLE_GL_TRY_ALWAYS_CHECK(context, functions->generateMipmap(ToGLenum(getType())));
|
||||||
|
}
|
||||||
|
|
||||||
setLevelInfo(context, getType(), effectiveBaseLevel, maxLevel - effectiveBaseLevel,
|
setLevelInfo(context, getType(), effectiveBaseLevel, maxLevel - effectiveBaseLevel,
|
||||||
getBaseLevelInfo());
|
getBaseLevelInfo());
|
||||||
|
|
||||||
|
|
|
@ -63,9 +63,9 @@ const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, StandardGL st
|
||||||
|
|
||||||
struct TexImageFormat
|
struct TexImageFormat
|
||||||
{
|
{
|
||||||
GLenum internalFormat;
|
GLenum internalFormat = GL_NONE;
|
||||||
GLenum format;
|
GLenum format = GL_NONE;
|
||||||
GLenum type;
|
GLenum type = GL_NONE;
|
||||||
};
|
};
|
||||||
TexImageFormat GetTexImageFormat(const FunctionsGL *functions,
|
TexImageFormat GetTexImageFormat(const FunctionsGL *functions,
|
||||||
const angle::FeaturesGL &features,
|
const angle::FeaturesGL &features,
|
||||||
|
@ -75,8 +75,8 @@ TexImageFormat GetTexImageFormat(const FunctionsGL *functions,
|
||||||
|
|
||||||
struct TexSubImageFormat
|
struct TexSubImageFormat
|
||||||
{
|
{
|
||||||
GLenum format;
|
GLenum format = GL_NONE;
|
||||||
GLenum type;
|
GLenum type = GL_NONE;
|
||||||
};
|
};
|
||||||
TexSubImageFormat GetTexSubImageFormat(const FunctionsGL *functions,
|
TexSubImageFormat GetTexSubImageFormat(const FunctionsGL *functions,
|
||||||
const angle::FeaturesGL &features,
|
const angle::FeaturesGL &features,
|
||||||
|
@ -85,7 +85,7 @@ TexSubImageFormat GetTexSubImageFormat(const FunctionsGL *functions,
|
||||||
|
|
||||||
struct CompressedTexImageFormat
|
struct CompressedTexImageFormat
|
||||||
{
|
{
|
||||||
GLenum internalFormat;
|
GLenum internalFormat = GL_NONE;
|
||||||
};
|
};
|
||||||
CompressedTexImageFormat GetCompressedTexImageFormat(const FunctionsGL *functions,
|
CompressedTexImageFormat GetCompressedTexImageFormat(const FunctionsGL *functions,
|
||||||
const angle::FeaturesGL &features,
|
const angle::FeaturesGL &features,
|
||||||
|
@ -93,7 +93,7 @@ CompressedTexImageFormat GetCompressedTexImageFormat(const FunctionsGL *function
|
||||||
|
|
||||||
struct CompressedTexSubImageFormat
|
struct CompressedTexSubImageFormat
|
||||||
{
|
{
|
||||||
GLenum format;
|
GLenum format = GL_NONE;
|
||||||
};
|
};
|
||||||
CompressedTexSubImageFormat GetCompressedSubTexImageFormat(const FunctionsGL *functions,
|
CompressedTexSubImageFormat GetCompressedSubTexImageFormat(const FunctionsGL *functions,
|
||||||
const angle::FeaturesGL &features,
|
const angle::FeaturesGL &features,
|
||||||
|
@ -101,7 +101,7 @@ CompressedTexSubImageFormat GetCompressedSubTexImageFormat(const FunctionsGL *fu
|
||||||
|
|
||||||
struct CopyTexImageImageFormat
|
struct CopyTexImageImageFormat
|
||||||
{
|
{
|
||||||
GLenum internalFormat;
|
GLenum internalFormat = GL_NONE;
|
||||||
};
|
};
|
||||||
CopyTexImageImageFormat GetCopyTexImageImageFormat(const FunctionsGL *functions,
|
CopyTexImageImageFormat GetCopyTexImageImageFormat(const FunctionsGL *functions,
|
||||||
const angle::FeaturesGL &features,
|
const angle::FeaturesGL &features,
|
||||||
|
@ -110,7 +110,7 @@ CopyTexImageImageFormat GetCopyTexImageImageFormat(const FunctionsGL *functions,
|
||||||
|
|
||||||
struct TexStorageFormat
|
struct TexStorageFormat
|
||||||
{
|
{
|
||||||
GLenum internalFormat;
|
GLenum internalFormat = GL_NONE;
|
||||||
};
|
};
|
||||||
TexStorageFormat GetTexStorageFormat(const FunctionsGL *functions,
|
TexStorageFormat GetTexStorageFormat(const FunctionsGL *functions,
|
||||||
const angle::FeaturesGL &features,
|
const angle::FeaturesGL &features,
|
||||||
|
@ -118,7 +118,7 @@ TexStorageFormat GetTexStorageFormat(const FunctionsGL *functions,
|
||||||
|
|
||||||
struct RenderbufferFormat
|
struct RenderbufferFormat
|
||||||
{
|
{
|
||||||
GLenum internalFormat;
|
GLenum internalFormat = GL_NONE;
|
||||||
};
|
};
|
||||||
RenderbufferFormat GetRenderbufferFormat(const FunctionsGL *functions,
|
RenderbufferFormat GetRenderbufferFormat(const FunctionsGL *functions,
|
||||||
const angle::FeaturesGL &features,
|
const angle::FeaturesGL &features,
|
||||||
|
@ -126,8 +126,8 @@ RenderbufferFormat GetRenderbufferFormat(const FunctionsGL *functions,
|
||||||
|
|
||||||
struct ReadPixelsFormat
|
struct ReadPixelsFormat
|
||||||
{
|
{
|
||||||
GLenum format;
|
GLenum format = GL_NONE;
|
||||||
GLenum type;
|
GLenum type = GL_NONE;
|
||||||
};
|
};
|
||||||
ReadPixelsFormat GetReadPixelsFormat(const FunctionsGL *functions,
|
ReadPixelsFormat GetReadPixelsFormat(const FunctionsGL *functions,
|
||||||
const angle::FeaturesGL &features,
|
const angle::FeaturesGL &features,
|
||||||
|
|
|
@ -1743,6 +1743,9 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
|
||||||
IsLinux() && isAMD && isMesa && mesaVersion < (std::array<int, 3>{19, 3, 5}));
|
IsLinux() && isAMD && isMesa && mesaVersion < (std::array<int, 3>{19, 3, 5}));
|
||||||
|
|
||||||
ANGLE_FEATURE_CONDITION(features, disableTimestampQueries, IsLinux() && isVMWare);
|
ANGLE_FEATURE_CONDITION(features, disableTimestampQueries, IsLinux() && isVMWare);
|
||||||
|
|
||||||
|
ANGLE_FEATURE_CONDITION(features, encodeAndDecodeSRGBForGenerateMipmap,
|
||||||
|
IsApple() && functions->standard == STANDARD_GL_DESKTOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
|
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче