Commit 83539557 by Le Hoang Quyen Committed by Commit Bot

Metal: Implement texture swizzle

Only enabled on macOS 10.15 and iOS 13.0 for now. Bug: angleproject:2634 Change-Id: Ic44a245198e32f076e429312cae844c510e864d1 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2433333Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Le Hoang Quyen <le.hoang.q@gmail.com>
parent 76ca9f36
...@@ -336,6 +336,9 @@ class TextureMtl : public TextureImpl ...@@ -336,6 +336,9 @@ class TextureMtl : public TextureImpl
// Mipmap views are indexed by native level (ignored base level): // Mipmap views are indexed by native level (ignored base level):
mtl::NativeTexLevelArray mNativeLevelViews; mtl::NativeTexLevelArray mNativeLevelViews;
// The swizzled view used for shader sampling.
mtl::TextureRef mNativeSwizzleSamplingView;
GLuint mCurrentBaseLevel = 0; GLuint mCurrentBaseLevel = 0;
GLuint mCurrentMaxLevel = 1000; GLuint mCurrentMaxLevel = 1000;
......
...@@ -419,6 +419,63 @@ angle::Result UploadTextureContents(const gl::Context *context, ...@@ -419,6 +419,63 @@ angle::Result UploadTextureContents(const gl::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
// This might be unused on platform not supporting swizzle.
ANGLE_MTL_UNUSED
GLenum OverrideSwizzleValue(const gl::Context *context,
GLenum swizzle,
const mtl::Format &format,
const gl::InternalFormat &glInternalFormat)
{
if (format.actualAngleFormat().depthBits)
{
ASSERT(!format.swizzled);
if (context->getState().getClientMajorVersion() >= 3 && glInternalFormat.sized)
{
// ES 3.0 spec: treat depth texture as red texture during sampling.
if (swizzle == GL_GREEN || swizzle == GL_BLUE)
{
return GL_NONE;
}
else if (swizzle == GL_ALPHA)
{
return GL_ONE;
}
}
else
{
// https://www.khronos.org/registry/OpenGL/extensions/OES/OES_depth_texture.txt
// Treat depth texture as luminance texture during sampling.
if (swizzle == GL_GREEN || swizzle == GL_BLUE)
{
return GL_RED;
}
else if (swizzle == GL_ALPHA)
{
return GL_ONE;
}
}
}
else if (format.swizzled)
{
// Combine the swizzles
switch (swizzle)
{
case GL_RED:
return format.swizzle[0];
case GL_GREEN:
return format.swizzle[1];
case GL_BLUE:
return format.swizzle[2];
case GL_ALPHA:
return format.swizzle[3];
default:
break;
}
}
return swizzle;
}
} // namespace } // namespace
// TextureMtl implementation // TextureMtl implementation
...@@ -449,7 +506,8 @@ void TextureMtl::releaseTexture(bool releaseImages, bool releaseTextureObjectsOn ...@@ -449,7 +506,8 @@ void TextureMtl::releaseTexture(bool releaseImages, bool releaseTextureObjectsOn
retainImageDefinitions(); retainImageDefinitions();
} }
mNativeTexture = nullptr; mNativeTexture = nullptr;
mNativeSwizzleSamplingView = nullptr;
// Clear render target cache for each texture's image. We don't erase them because they // Clear render target cache for each texture's image. We don't erase them because they
// might still be referenced by a framebuffer. // might still be referenced by a framebuffer.
...@@ -1210,7 +1268,8 @@ angle::Result TextureMtl::syncState(const gl::Context *context, ...@@ -1210,7 +1268,8 @@ angle::Result TextureMtl::syncState(const gl::Context *context,
case gl::Texture::DIRTY_BIT_SWIZZLE_BLUE: case gl::Texture::DIRTY_BIT_SWIZZLE_BLUE:
case gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA: case gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA:
{ {
UNIMPLEMENTED(); // Recreate swizzle view.
mNativeSwizzleSamplingView = nullptr;
} }
break; break;
default: default:
...@@ -1237,6 +1296,36 @@ angle::Result TextureMtl::bindToShader(const gl::Context *context, ...@@ -1237,6 +1296,36 @@ angle::Result TextureMtl::bindToShader(const gl::Context *context,
float maxLodClamp; float maxLodClamp;
id<MTLSamplerState> samplerState; id<MTLSamplerState> samplerState;
if (!mNativeSwizzleSamplingView)
{
#if ANGLE_MTL_SWIZZLE_AVAILABLE
ContextMtl *contextMtl = mtl::GetImpl(context);
if ((mState.getSwizzleState().swizzleRequired() || mFormat.actualAngleFormat().depthBits ||
mFormat.swizzled) &&
contextMtl->getDisplay()->getFeatures().hasTextureSwizzle.enabled)
{
const gl::InternalFormat &glInternalForamt = *mState.getBaseLevelDesc().format.info;
MTLTextureSwizzleChannels swizzle = MTLTextureSwizzleChannelsMake(
mtl::GetTextureSwizzle(OverrideSwizzleValue(
context, mState.getSwizzleState().swizzleRed, mFormat, glInternalForamt)),
mtl::GetTextureSwizzle(OverrideSwizzleValue(
context, mState.getSwizzleState().swizzleGreen, mFormat, glInternalForamt)),
mtl::GetTextureSwizzle(OverrideSwizzleValue(
context, mState.getSwizzleState().swizzleBlue, mFormat, glInternalForamt)),
mtl::GetTextureSwizzle(OverrideSwizzleValue(
context, mState.getSwizzleState().swizzleAlpha, mFormat, glInternalForamt)));
mNativeSwizzleSamplingView = mNativeTexture->createSwizzleView(swizzle);
}
else
#endif // ANGLE_MTL_SWIZZLE_AVAILABLE
{
mNativeSwizzleSamplingView = mNativeTexture;
}
}
if (!sampler) if (!sampler)
{ {
samplerState = mMetalSamplerState; samplerState = mMetalSamplerState;
...@@ -1253,7 +1342,7 @@ angle::Result TextureMtl::bindToShader(const gl::Context *context, ...@@ -1253,7 +1342,7 @@ angle::Result TextureMtl::bindToShader(const gl::Context *context,
minLodClamp = std::max(minLodClamp, 0.f); minLodClamp = std::max(minLodClamp, 0.f);
cmdEncoder->setTexture(shaderType, mNativeTexture, textureSlotIndex); cmdEncoder->setTexture(shaderType, mNativeSwizzleSamplingView, textureSlotIndex);
cmdEncoder->setSamplerState(shaderType, samplerState, minLodClamp, maxLodClamp, cmdEncoder->setSamplerState(shaderType, samplerState, minLodClamp, maxLodClamp,
samplerSlotIndex); samplerSlotIndex);
......
...@@ -173,10 +173,14 @@ constexpr MTLBlitOption kBlitOptionRowLinearPVRTC = MTLBlitOptionRowLin ...@@ -173,10 +173,14 @@ constexpr MTLBlitOption kBlitOptionRowLinearPVRTC = MTLBlitOptionRowLin
#endif #endif
#if defined(__IPHONE_13_0) || defined(__MAC_10_15) #if defined(__IPHONE_13_0) || defined(__MAC_10_15)
# define ANGLE_MTL_SWIZZLE_AVAILABLE 1
using TextureSwizzleChannels = MTLTextureSwizzleChannels;
using RenderStages = MTLRenderStages; using RenderStages = MTLRenderStages;
constexpr MTLRenderStages kRenderStageVertex = MTLRenderStageVertex; constexpr MTLRenderStages kRenderStageVertex = MTLRenderStageVertex;
constexpr MTLRenderStages kRenderStageFragment = MTLRenderStageFragment; constexpr MTLRenderStages kRenderStageFragment = MTLRenderStageFragment;
#else #else
# define ANGLE_MTL_SWIZZLE_AVAILABLE 0
using TextureSwizzleChannels = int;
using RenderStages = int; using RenderStages = int;
constexpr RenderStages kRenderStageVertex = 1; constexpr RenderStages kRenderStageVertex = 1;
constexpr RenderStages kRenderStageFragment = 2; constexpr RenderStages kRenderStageFragment = 2;
......
...@@ -188,6 +188,8 @@ class Texture final : public Resource, ...@@ -188,6 +188,8 @@ class Texture final : public Resource,
// Same as above but the target format must be compatible, for example sRGB to linear. In this // Same as above but the target format must be compatible, for example sRGB to linear. In this
// case texture doesn't need format view usage flag. // case texture doesn't need format view usage flag.
TextureRef createViewWithCompatibleFormat(MTLPixelFormat format); TextureRef createViewWithCompatibleFormat(MTLPixelFormat format);
// Create a swizzled view
TextureRef createSwizzleView(const TextureSwizzleChannels &swizzle);
MTLTextureType textureType() const; MTLTextureType textureType() const;
MTLPixelFormat pixelFormat() const; MTLPixelFormat pixelFormat() const;
...@@ -249,6 +251,7 @@ class Texture final : public Resource, ...@@ -249,6 +251,7 @@ class Texture final : public Resource,
// Create a texture view // Create a texture view
Texture(Texture *original, MTLPixelFormat format); Texture(Texture *original, MTLPixelFormat format);
Texture(Texture *original, MTLTextureType type, NSRange mipmapLevelRange, NSRange slices); Texture(Texture *original, MTLTextureType type, NSRange mipmapLevelRange, NSRange slices);
Texture(Texture *original, const TextureSwizzleChannels &swizzle);
void syncContentIfNeeded(ContextMtl *context); void syncContentIfNeeded(ContextMtl *context);
......
...@@ -31,21 +31,6 @@ inline NSUInteger GetMipSize(NSUInteger baseSize, const MipmapNativeLevel level) ...@@ -31,21 +31,6 @@ inline NSUInteger GetMipSize(NSUInteger baseSize, const MipmapNativeLevel level)
return std::max<NSUInteger>(1, baseSize >> level.get()); return std::max<NSUInteger>(1, baseSize >> level.get());
} }
void SetTextureSwizzle(ContextMtl *context,
const Format &format,
MTLTextureDescriptor *textureDescOut)
{
// Texture swizzle functions's declarations are only available if macos 10.15 sdk is present
#if defined(__IPHONE_13_0) || defined(__MAC_10_15)
if (context->getDisplay()->getFeatures().hasTextureSwizzle.enabled && format.swizzled)
{
textureDescOut.swizzle = MTLTextureSwizzleChannelsMake(
GetTextureSwizzle(format.swizzle[0]), GetTextureSwizzle(format.swizzle[1]),
GetTextureSwizzle(format.swizzle[2]), GetTextureSwizzle(format.swizzle[3]));
}
#endif
}
// Asynchronously synchronize the content of a resource between GPU memory and its CPU cache. // Asynchronously synchronize the content of a resource between GPU memory and its CPU cache.
// NOTE: This operation doesn't finish immediately upon function's return. // NOTE: This operation doesn't finish immediately upon function's return.
template <class T> template <class T>
...@@ -248,8 +233,6 @@ angle::Result Texture::MakeTexture(ContextMtl *context, ...@@ -248,8 +233,6 @@ angle::Result Texture::MakeTexture(ContextMtl *context,
bool allowFormatView, bool allowFormatView,
TextureRef *refOut) TextureRef *refOut)
{ {
SetTextureSwizzle(context, mtlFormat, desc);
refOut->reset(new Texture(context, desc, mips, renderTargetOnly, allowFormatView)); refOut->reset(new Texture(context, desc, mips, renderTargetOnly, allowFormatView));
if (!(*refOut) || !(*refOut)->get()) if (!(*refOut) || !(*refOut)->get())
...@@ -354,6 +337,27 @@ Texture::Texture(Texture *original, MTLTextureType type, NSRange mipmapLevelRang ...@@ -354,6 +337,27 @@ Texture::Texture(Texture *original, MTLTextureType type, NSRange mipmapLevelRang
} }
} }
Texture::Texture(Texture *original, const TextureSwizzleChannels &swizzle)
: Resource(original),
mColorWritableMask(original->mColorWritableMask) // Share color write mask property
{
#if ANGLE_MTL_SWIZZLE_AVAILABLE
ANGLE_MTL_OBJC_SCOPE
{
auto view = [original->get()
newTextureViewWithPixelFormat:original->pixelFormat()
textureType:original->textureType()
levels:NSMakeRange(0, original->mipmapLevels())
slices:NSMakeRange(0, original->cubeFacesOrArrayLength())
swizzle:swizzle];
set([view ANGLE_MTL_AUTORELEASE]);
}
#else
UNREACHABLE();
#endif
}
void Texture::syncContent(ContextMtl *context, mtl::BlitCommandEncoder *blitEncoder) void Texture::syncContent(ContextMtl *context, mtl::BlitCommandEncoder *blitEncoder)
{ {
InvokeCPUMemSync(context, blitEncoder, this); InvokeCPUMemSync(context, blitEncoder, this);
...@@ -516,6 +520,17 @@ TextureRef Texture::createViewWithCompatibleFormat(MTLPixelFormat format) ...@@ -516,6 +520,17 @@ TextureRef Texture::createViewWithCompatibleFormat(MTLPixelFormat format)
return TextureRef(new Texture(this, format)); return TextureRef(new Texture(this, format));
} }
TextureRef Texture::createSwizzleView(const TextureSwizzleChannels &swizzle)
{
#if ANGLE_MTL_SWIZZLE_AVAILABLE
return TextureRef(new Texture(this, swizzle));
#else
WARN() << "Texture swizzle is not supported on pre iOS 13.0 and macOS 15.0";
UNIMPLEMENTED();
return shared_from_this();
#endif
}
MTLPixelFormat Texture::pixelFormat() const MTLPixelFormat Texture::pixelFormat() const
{ {
return get().pixelFormat; return get().pixelFormat;
......
...@@ -126,7 +126,7 @@ PrimitiveTopologyClass GetPrimitiveTopologyClass(gl::PrimitiveMode mode); ...@@ -126,7 +126,7 @@ PrimitiveTopologyClass GetPrimitiveTopologyClass(gl::PrimitiveMode mode);
MTLPrimitiveType GetPrimitiveType(gl::PrimitiveMode mode); MTLPrimitiveType GetPrimitiveType(gl::PrimitiveMode mode);
MTLIndexType GetIndexType(gl::DrawElementsType type); MTLIndexType GetIndexType(gl::DrawElementsType type);
#if defined(__IPHONE_13_0) || defined(__MAC_10_15) #if ANGLE_MTL_SWIZZLE_AVAILABLE
MTLTextureSwizzle GetTextureSwizzle(GLenum swizzle); MTLTextureSwizzle GetTextureSwizzle(GLenum swizzle);
#endif #endif
......
...@@ -748,7 +748,7 @@ MTLIndexType GetIndexType(gl::DrawElementsType type) ...@@ -748,7 +748,7 @@ MTLIndexType GetIndexType(gl::DrawElementsType type)
} }
} }
#if defined(__IPHONE_13_0) || defined(__MAC_10_15) #if ANGLE_MTL_SWIZZLE_AVAILABLE
MTLTextureSwizzle GetTextureSwizzle(GLenum swizzle) MTLTextureSwizzle GetTextureSwizzle(GLenum swizzle)
{ {
switch (swizzle) switch (swizzle)
......
...@@ -97,6 +97,12 @@ void main() ...@@ -97,6 +97,12 @@ void main()
glDeleteTextures(1, &mTexture); glDeleteTextures(1, &mTexture);
} }
bool isTextureSwizzleAvailable() const
{
// On Metal back-end, texture swizzle is not always supported.
return !IsMetal() || IsMetalTextureSwizzleAvailable();
}
template <typename T> template <typename T>
void init2DTexture(GLenum internalFormat, GLenum dataFormat, GLenum dataType, const T *data) void init2DTexture(GLenum internalFormat, GLenum dataFormat, GLenum dataType, const T *data)
{ {
...@@ -116,8 +122,7 @@ void main() ...@@ -116,8 +122,7 @@ void main()
{ {
glGenTextures(1, &mTexture); glGenTextures(1, &mTexture);
glBindTexture(GL_TEXTURE_2D, mTexture); glBindTexture(GL_TEXTURE_2D, mTexture);
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, width, height, 0, glCompressedTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataSize, data);
dataSize, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
...@@ -245,6 +250,8 @@ class SwizzleIntegerTest : public SwizzleTest ...@@ -245,6 +250,8 @@ class SwizzleIntegerTest : public SwizzleTest
TEST_P(SwizzleTest, RGBA8_2D) TEST_P(SwizzleTest, RGBA8_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
GLubyte data[] = {1, 64, 128, 200}; GLubyte data[] = {1, 64, 128, 200};
init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, data); init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, data);
runTest2D(); runTest2D();
...@@ -252,6 +259,8 @@ TEST_P(SwizzleTest, RGBA8_2D) ...@@ -252,6 +259,8 @@ TEST_P(SwizzleTest, RGBA8_2D)
TEST_P(SwizzleTest, RGB8_2D) TEST_P(SwizzleTest, RGB8_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
GLubyte data[] = {77, 66, 55}; GLubyte data[] = {77, 66, 55};
init2DTexture(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, data); init2DTexture(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, data);
runTest2D(); runTest2D();
...@@ -259,6 +268,8 @@ TEST_P(SwizzleTest, RGB8_2D) ...@@ -259,6 +268,8 @@ TEST_P(SwizzleTest, RGB8_2D)
TEST_P(SwizzleTest, RG8_2D) TEST_P(SwizzleTest, RG8_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
GLubyte data[] = {11, 99}; GLubyte data[] = {11, 99};
init2DTexture(GL_RG8, GL_RG, GL_UNSIGNED_BYTE, data); init2DTexture(GL_RG8, GL_RG, GL_UNSIGNED_BYTE, data);
runTest2D(); runTest2D();
...@@ -266,6 +277,8 @@ TEST_P(SwizzleTest, RG8_2D) ...@@ -266,6 +277,8 @@ TEST_P(SwizzleTest, RG8_2D)
TEST_P(SwizzleTest, R8_2D) TEST_P(SwizzleTest, R8_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
GLubyte data[] = {2}; GLubyte data[] = {2};
init2DTexture(GL_R8, GL_RED, GL_UNSIGNED_BYTE, data); init2DTexture(GL_R8, GL_RED, GL_UNSIGNED_BYTE, data);
runTest2D(); runTest2D();
...@@ -273,6 +286,8 @@ TEST_P(SwizzleTest, R8_2D) ...@@ -273,6 +286,8 @@ TEST_P(SwizzleTest, R8_2D)
TEST_P(SwizzleTest, RGB10_A2_2D) TEST_P(SwizzleTest, RGB10_A2_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
GLuint data[] = {20u | (40u << 10) | (60u << 20) | (2u << 30)}; GLuint data[] = {20u | (40u << 10) | (60u << 20) | (2u << 30)};
init2DTexture(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, data); init2DTexture(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, data);
runTest2D(); runTest2D();
...@@ -280,6 +295,8 @@ TEST_P(SwizzleTest, RGB10_A2_2D) ...@@ -280,6 +295,8 @@ TEST_P(SwizzleTest, RGB10_A2_2D)
TEST_P(SwizzleTest, RGBA32F_2D) TEST_P(SwizzleTest, RGBA32F_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
GLfloat data[] = {0.25f, 0.5f, 0.75f, 0.8f}; GLfloat data[] = {0.25f, 0.5f, 0.75f, 0.8f};
init2DTexture(GL_RGBA32F, GL_RGBA, GL_FLOAT, data); init2DTexture(GL_RGBA32F, GL_RGBA, GL_FLOAT, data);
runTest2D(); runTest2D();
...@@ -287,6 +304,8 @@ TEST_P(SwizzleTest, RGBA32F_2D) ...@@ -287,6 +304,8 @@ TEST_P(SwizzleTest, RGBA32F_2D)
TEST_P(SwizzleTest, RGB32F_2D) TEST_P(SwizzleTest, RGB32F_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
ANGLE_SKIP_TEST_IF(IsVulkan()); // anglebug.com/2898 - float textures ANGLE_SKIP_TEST_IF(IsVulkan()); // anglebug.com/2898 - float textures
GLfloat data[] = {0.1f, 0.2f, 0.3f}; GLfloat data[] = {0.1f, 0.2f, 0.3f};
init2DTexture(GL_RGB32F, GL_RGB, GL_FLOAT, data); init2DTexture(GL_RGB32F, GL_RGB, GL_FLOAT, data);
...@@ -295,6 +314,8 @@ TEST_P(SwizzleTest, RGB32F_2D) ...@@ -295,6 +314,8 @@ TEST_P(SwizzleTest, RGB32F_2D)
TEST_P(SwizzleTest, RG32F_2D) TEST_P(SwizzleTest, RG32F_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
GLfloat data[] = {0.9f, 0.1f}; GLfloat data[] = {0.9f, 0.1f};
init2DTexture(GL_RG32F, GL_RG, GL_FLOAT, data); init2DTexture(GL_RG32F, GL_RG, GL_FLOAT, data);
runTest2D(); runTest2D();
...@@ -302,6 +323,8 @@ TEST_P(SwizzleTest, RG32F_2D) ...@@ -302,6 +323,8 @@ TEST_P(SwizzleTest, RG32F_2D)
TEST_P(SwizzleTest, R32F_2D) TEST_P(SwizzleTest, R32F_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
GLfloat data[] = {0.5f}; GLfloat data[] = {0.5f};
init2DTexture(GL_R32F, GL_RED, GL_FLOAT, data); init2DTexture(GL_R32F, GL_RED, GL_FLOAT, data);
runTest2D(); runTest2D();
...@@ -309,6 +332,8 @@ TEST_P(SwizzleTest, R32F_2D) ...@@ -309,6 +332,8 @@ TEST_P(SwizzleTest, R32F_2D)
TEST_P(SwizzleTest, D32F_2D) TEST_P(SwizzleTest, D32F_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
GLfloat data[] = {0.5f}; GLfloat data[] = {0.5f};
init2DTexture(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, data); init2DTexture(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, data);
runTest2D(); runTest2D();
...@@ -316,6 +341,8 @@ TEST_P(SwizzleTest, D32F_2D) ...@@ -316,6 +341,8 @@ TEST_P(SwizzleTest, D32F_2D)
TEST_P(SwizzleTest, D16_2D) TEST_P(SwizzleTest, D16_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
GLushort data[] = {0xFF}; GLushort data[] = {0xFF};
init2DTexture(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data); init2DTexture(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data);
runTest2D(); runTest2D();
...@@ -323,6 +350,8 @@ TEST_P(SwizzleTest, D16_2D) ...@@ -323,6 +350,8 @@ TEST_P(SwizzleTest, D16_2D)
TEST_P(SwizzleTest, D24_2D) TEST_P(SwizzleTest, D24_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
ANGLE_SKIP_TEST_IF(IsVulkan() && IsAMD() && IsWindows()); // anglebug.com/3545 ANGLE_SKIP_TEST_IF(IsVulkan() && IsAMD() && IsWindows()); // anglebug.com/3545
GLuint data[] = {0xFFFF}; GLuint data[] = {0xFFFF};
init2DTexture(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, data); init2DTexture(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, data);
...@@ -331,6 +360,8 @@ TEST_P(SwizzleTest, D24_2D) ...@@ -331,6 +360,8 @@ TEST_P(SwizzleTest, D24_2D)
TEST_P(SwizzleTest, L8_2D) TEST_P(SwizzleTest, L8_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
GLubyte data[] = {0x77}; GLubyte data[] = {0x77};
init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
runTest2D(); runTest2D();
...@@ -338,6 +369,8 @@ TEST_P(SwizzleTest, L8_2D) ...@@ -338,6 +369,8 @@ TEST_P(SwizzleTest, L8_2D)
TEST_P(SwizzleTest, A8_2D) TEST_P(SwizzleTest, A8_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
GLubyte data[] = {0x55}; GLubyte data[] = {0x55};
init2DTexture(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, data); init2DTexture(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, data);
runTest2D(); runTest2D();
...@@ -345,6 +378,8 @@ TEST_P(SwizzleTest, A8_2D) ...@@ -345,6 +378,8 @@ TEST_P(SwizzleTest, A8_2D)
TEST_P(SwizzleTest, LA8_2D) TEST_P(SwizzleTest, LA8_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
GLubyte data[] = {0x77, 0x66}; GLubyte data[] = {0x77, 0x66};
init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data); init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);
runTest2D(); runTest2D();
...@@ -352,6 +387,8 @@ TEST_P(SwizzleTest, LA8_2D) ...@@ -352,6 +387,8 @@ TEST_P(SwizzleTest, LA8_2D)
TEST_P(SwizzleTest, L32F_2D) TEST_P(SwizzleTest, L32F_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float")); ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
GLfloat data[] = {0.7f}; GLfloat data[] = {0.7f};
...@@ -361,6 +398,8 @@ TEST_P(SwizzleTest, L32F_2D) ...@@ -361,6 +398,8 @@ TEST_P(SwizzleTest, L32F_2D)
TEST_P(SwizzleTest, A32F_2D) TEST_P(SwizzleTest, A32F_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float")); ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
GLfloat data[] = { GLfloat data[] = {
...@@ -372,6 +411,8 @@ TEST_P(SwizzleTest, A32F_2D) ...@@ -372,6 +411,8 @@ TEST_P(SwizzleTest, A32F_2D)
TEST_P(SwizzleTest, LA32F_2D) TEST_P(SwizzleTest, LA32F_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float")); ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_float"));
GLfloat data[] = { GLfloat data[] = {
...@@ -386,6 +427,8 @@ TEST_P(SwizzleTest, LA32F_2D) ...@@ -386,6 +427,8 @@ TEST_P(SwizzleTest, LA32F_2D)
TEST_P(SwizzleTest, CompressedDXT_2D) TEST_P(SwizzleTest, CompressedDXT_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1")); ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
init2DCompressedTexture(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height, init2DCompressedTexture(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height,
...@@ -393,8 +436,21 @@ TEST_P(SwizzleTest, CompressedDXT_2D) ...@@ -393,8 +436,21 @@ TEST_P(SwizzleTest, CompressedDXT_2D)
runTest2D(); runTest2D();
} }
TEST_P(SwizzleTest, CompressedDXT1_RGB_2D)
{
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
init2DCompressedTexture(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height,
pixel_0_size, pixel_0_data);
runTest2D();
}
TEST_P(SwizzleIntegerTest, RGB8UI_2D) TEST_P(SwizzleIntegerTest, RGB8UI_2D)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
ANGLE_SKIP_TEST_IF(IsVulkan()); // anglebug.com/3196 - integer textures ANGLE_SKIP_TEST_IF(IsVulkan()); // anglebug.com/3196 - integer textures
GLubyte data[] = {77, 66, 55}; GLubyte data[] = {77, 66, 55};
init2DTexture(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, data); init2DTexture(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, data);
...@@ -404,6 +460,8 @@ TEST_P(SwizzleIntegerTest, RGB8UI_2D) ...@@ -404,6 +460,8 @@ TEST_P(SwizzleIntegerTest, RGB8UI_2D)
// Test that updating the texture data still generates the correct swizzles // Test that updating the texture data still generates the correct swizzles
TEST_P(SwizzleTest, SubUpdate) TEST_P(SwizzleTest, SubUpdate)
{ {
ANGLE_SKIP_TEST_IF(!isTextureSwizzleAvailable());
GLColor data(1, 64, 128, 200); GLColor data(1, 64, 128, 200);
init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &data); init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &data);
...@@ -432,7 +490,7 @@ TEST_P(SwizzleTest, SubUpdate) ...@@ -432,7 +490,7 @@ TEST_P(SwizzleTest, SubUpdate)
EXPECT_PIXEL_COLOR_EQ(0, 0, expectedUpdateData); EXPECT_PIXEL_COLOR_EQ(0, 0, expectedUpdateData);
} }
ANGLE_INSTANTIATE_TEST_ES3(SwizzleTest); ANGLE_INSTANTIATE_TEST_ES3_AND(SwizzleTest, ES3_METAL());
ANGLE_INSTANTIATE_TEST_ES3(SwizzleIntegerTest); ANGLE_INSTANTIATE_TEST_ES3_AND(SwizzleIntegerTest, ES3_METAL());
} // namespace } // namespace
...@@ -155,6 +155,14 @@ bool IsConfigSelected() ...@@ -155,6 +155,14 @@ bool IsConfigSelected()
return gSelectedConfig[0] != 0; return gSelectedConfig[0] != 0;
} }
#if !defined(ANGLE_PLATFORM_APPLE)
// For Apple platform, see angle_test_instantiate_apple.mm
bool IsMetalTextureSwizzleAvailable()
{
return false;
}
#endif
SystemInfo *GetTestSystemInfo() SystemInfo *GetTestSystemInfo()
{ {
static SystemInfo *sSystemInfo = nullptr; static SystemInfo *sSystemInfo = nullptr;
......
...@@ -263,6 +263,9 @@ std::vector<std::string> GetAvailableTestPlatformNames(); ...@@ -263,6 +263,9 @@ std::vector<std::string> GetAvailableTestPlatformNames();
void SetSelectedConfig(const char *selectedConfig); void SetSelectedConfig(const char *selectedConfig);
bool IsConfigSelected(); bool IsConfigSelected();
// Check whether texture swizzle is natively supported on Metal device.
bool IsMetalTextureSwizzleAvailable();
extern bool gEnableANGLEPerTestCaptureLabel; extern bool gEnableANGLEPerTestCaptureLabel;
// For use with ANGLE_INSTANTIATE_TEST_ARRAY // For use with ANGLE_INSTANTIATE_TEST_ARRAY
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "test_utils/angle_test_instantiate_apple.h" #include "test_utils/angle_test_instantiate_apple.h"
#include "common/apple_platform_utils.h" #include "common/apple_platform_utils.h"
#include "test_utils/angle_test_instantiate.h"
namespace angle namespace angle
{ {
...@@ -24,4 +25,17 @@ bool IsMetalRendererAvailable() ...@@ -24,4 +25,17 @@ bool IsMetalRendererAvailable()
return false; return false;
} }
bool IsMetalTextureSwizzleAvailable()
{
// NOTE(hqle): This might not be accurate, since the capabilities also depend on underlying
// hardwares, however, it is OK for testing.
if (ANGLE_APPLE_AVAILABLE_XCI(10.15, 13.0, 13))
{
// Intel doesn't support swizzle because it is GPU family 1. We don't have a way to detect
// Metal family here, so skip on Intel.
return !IsIntel();
}
return false;
}
} // namespace angle } // namespace angle
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment