Commit 349b661d by Le Hoang Quyen Committed by Commit Bot

Metal: fix max point size and RGB565 renderbuffer bug.

- Max point size is set to 64, since this is the max size observed. It is not 511 as https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf claims. - RGB565 is emulated on macOS by RGBA, needs to disable alpha write for this format. This was already done for TextureMtl, but wasn't for RenderBufferMtl. - Also enable true non-power-of-two textures support (OES_texture_npot). This was technically already supported, just that the extension wasn't advertised yet. - New Test: FramebufferFormatsTest.RGB565Renderbuffer Bug: angleproject:4816 Bug: angleproject:2634 Change-Id: Ie7e3efb4cb29bb9a3fd706c26e2b50b42ff3f6be Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2281797 Commit-Queue: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 08b9ad57
...@@ -435,7 +435,11 @@ void DisplayMtl::ensureCapsInitialized() const ...@@ -435,7 +435,11 @@ void DisplayMtl::ensureCapsInitialized() const
mNativeCaps.maxCubeMapTextureSize = mNativeCaps.max2DTextureSize; mNativeCaps.maxCubeMapTextureSize = mNativeCaps.max2DTextureSize;
mNativeCaps.maxRenderbufferSize = mNativeCaps.max2DTextureSize; mNativeCaps.maxRenderbufferSize = mNativeCaps.max2DTextureSize;
mNativeCaps.minAliasedPointSize = 1; mNativeCaps.minAliasedPointSize = 1;
mNativeCaps.maxAliasedPointSize = 511; // NOTE(hqle): Metal has some problems drawing big point size even though
// Metal-Feature-Set-Tables.pdf says that max supported point size is 511. We limit it to 64 for
// now.
// http://anglebug.com/4816
mNativeCaps.maxAliasedPointSize = 64;
mNativeCaps.minAliasedLineWidth = 1.0f; mNativeCaps.minAliasedLineWidth = 1.0f;
mNativeCaps.maxAliasedLineWidth = 1.0f; mNativeCaps.maxAliasedLineWidth = 1.0f;
...@@ -588,8 +592,7 @@ void DisplayMtl::initializeExtensions() const ...@@ -588,8 +592,7 @@ void DisplayMtl::initializeExtensions() const
mNativeExtensions.textureFilterAnisotropic = true; mNativeExtensions.textureFilterAnisotropic = true;
mNativeExtensions.maxTextureAnisotropy = 16; mNativeExtensions.maxTextureAnisotropy = 16;
// NOTE(hqle): Support true NPOT textures. mNativeExtensions.textureNPOTOES = true;
mNativeExtensions.textureNPOTOES = false;
mNativeExtensions.texture3DOES = false; mNativeExtensions.texture3DOES = false;
......
...@@ -64,6 +64,19 @@ angle::Result RenderbufferMtl::setStorageImpl(const gl::Context *context, ...@@ -64,6 +64,19 @@ angle::Result RenderbufferMtl::setStorageImpl(const gl::Context *context,
&mTexture)); &mTexture));
mRenderTarget.set(mTexture, 0, 0, mFormat); mRenderTarget.set(mTexture, 0, 0, mFormat);
// For emulated channels that GL texture intends to not have,
// we need to initialize their content.
bool emulatedChannels;
mTexture->setColorWritableMask(mtl::GetEmulatedColorWriteMask(mFormat, &emulatedChannels));
if (emulatedChannels)
{
gl::ImageIndex index;
index = gl::ImageIndex::Make2D(0);
ANGLE_TRY(mtl::InitializeTextureContents(context, mTexture, mFormat, index));
}
} }
return angle::Result::Continue; return angle::Result::Continue;
......
...@@ -28,45 +28,6 @@ namespace rx ...@@ -28,45 +28,6 @@ namespace rx
namespace namespace
{ {
MTLColorWriteMask GetColorWriteMask(const mtl::Format &mtlFormat, bool *emulatedChannelsOut)
{
const angle::Format &intendedFormat = mtlFormat.intendedAngleFormat();
const angle::Format &actualFormat = mtlFormat.actualAngleFormat();
bool emulatedChannels = false;
MTLColorWriteMask colorWritableMask = MTLColorWriteMaskAll;
if (intendedFormat.alphaBits == 0 && actualFormat.alphaBits)
{
emulatedChannels = true;
// Disable alpha write to this texture
colorWritableMask = colorWritableMask & (~MTLColorWriteMaskAlpha);
}
if (intendedFormat.luminanceBits == 0)
{
if (intendedFormat.redBits == 0 && actualFormat.redBits)
{
emulatedChannels = true;
// Disable red write to this texture
colorWritableMask = colorWritableMask & (~MTLColorWriteMaskRed);
}
if (intendedFormat.greenBits == 0 && actualFormat.greenBits)
{
emulatedChannels = true;
// Disable green write to this texture
colorWritableMask = colorWritableMask & (~MTLColorWriteMaskGreen);
}
if (intendedFormat.blueBits == 0 && actualFormat.blueBits)
{
emulatedChannels = true;
// Disable blue write to this texture
colorWritableMask = colorWritableMask & (~MTLColorWriteMaskBlue);
}
}
*emulatedChannelsOut = emulatedChannels;
return colorWritableMask;
}
gl::ImageIndex GetImageBaseLevelIndex(const mtl::TextureRef &image) gl::ImageIndex GetImageBaseLevelIndex(const mtl::TextureRef &image)
{ {
gl::ImageIndex imageBaseIndex; gl::ImageIndex imageBaseIndex;
...@@ -1067,8 +1028,9 @@ angle::Result TextureMtl::checkForEmulatedChannels(const gl::Context *context, ...@@ -1067,8 +1028,9 @@ angle::Result TextureMtl::checkForEmulatedChannels(const gl::Context *context,
const mtl::Format &mtlFormat, const mtl::Format &mtlFormat,
const mtl::TextureRef &texture) const mtl::TextureRef &texture)
{ {
bool emulatedChannels = false; bool emulatedChannels = false;
MTLColorWriteMask colorWritableMask = GetColorWriteMask(mtlFormat, &emulatedChannels); MTLColorWriteMask colorWritableMask =
mtl::GetEmulatedColorWriteMask(mtlFormat, &emulatedChannels);
texture->setColorWritableMask(colorWritableMask); texture->setColorWritableMask(colorWritableMask);
// For emulated channels that GL texture intends to not have, // For emulated channels that GL texture intends to not have,
......
...@@ -92,6 +92,13 @@ PrimitiveTopologyClass GetPrimitiveTopologyClass(gl::PrimitiveMode mode); ...@@ -92,6 +92,13 @@ 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);
// Get color write mask for a specified format. Some formats such as RGB565 doesn't have alpha
// channel but is emulated by a RGBA8 format, we need to disable alpha write for this format.
// - isFormatEmulated: if the format is emulated, this pointer will store a true value.
MTLColorWriteMask GetEmulatedColorWriteMask(const mtl::Format &mtlFormat, bool *isFormatEmulated);
MTLColorWriteMask GetEmulatedColorWriteMask(const mtl::Format &mtlFormat);
bool IsFormatEmulated(const mtl::Format &mtlFormat);
// Useful to set clear color for texture originally having no alpha in GL, but backend's format // Useful to set clear color for texture originally having no alpha in GL, but backend's format
// has alpha channel. // has alpha channel.
MTLClearColor EmulatedAlphaClearColor(MTLClearColor color, MTLColorWriteMask colorMask); MTLClearColor EmulatedAlphaClearColor(MTLClearColor color, MTLColorWriteMask colorMask);
......
...@@ -433,6 +433,59 @@ MTLIndexType GetIndexType(gl::DrawElementsType type) ...@@ -433,6 +433,59 @@ MTLIndexType GetIndexType(gl::DrawElementsType type)
} }
} }
MTLColorWriteMask GetEmulatedColorWriteMask(const mtl::Format &mtlFormat, bool *isEmulatedOut)
{
const angle::Format &intendedFormat = mtlFormat.intendedAngleFormat();
const angle::Format &actualFormat = mtlFormat.actualAngleFormat();
bool isFormatEmulated = false;
MTLColorWriteMask colorWritableMask = MTLColorWriteMaskAll;
if (intendedFormat.alphaBits == 0 && actualFormat.alphaBits)
{
isFormatEmulated = true;
// Disable alpha write to this texture
colorWritableMask = colorWritableMask & (~MTLColorWriteMaskAlpha);
}
if (intendedFormat.luminanceBits == 0)
{
if (intendedFormat.redBits == 0 && actualFormat.redBits)
{
isFormatEmulated = true;
// Disable red write to this texture
colorWritableMask = colorWritableMask & (~MTLColorWriteMaskRed);
}
if (intendedFormat.greenBits == 0 && actualFormat.greenBits)
{
isFormatEmulated = true;
// Disable green write to this texture
colorWritableMask = colorWritableMask & (~MTLColorWriteMaskGreen);
}
if (intendedFormat.blueBits == 0 && actualFormat.blueBits)
{
isFormatEmulated = true;
// Disable blue write to this texture
colorWritableMask = colorWritableMask & (~MTLColorWriteMaskBlue);
}
}
*isEmulatedOut = isFormatEmulated;
return colorWritableMask;
}
MTLColorWriteMask GetEmulatedColorWriteMask(const mtl::Format &mtlFormat)
{
// Ignore isFormatEmulated boolean value
bool isFormatEmulated;
return GetEmulatedColorWriteMask(mtlFormat, &isFormatEmulated);
}
bool IsFormatEmulated(const mtl::Format &mtlFormat)
{
bool isFormatEmulated;
(void)GetEmulatedColorWriteMask(mtlFormat, &isFormatEmulated);
return isFormatEmulated;
}
MTLClearColor EmulatedAlphaClearColor(MTLClearColor color, MTLColorWriteMask colorMask) MTLClearColor EmulatedAlphaClearColor(MTLClearColor color, MTLColorWriteMask colorMask)
{ {
MTLClearColor re = color; MTLClearColor re = color;
......
...@@ -362,6 +362,28 @@ TEST_P(FramebufferFormatsTest, ReadDrawCompleteness) ...@@ -362,6 +362,28 @@ TEST_P(FramebufferFormatsTest, ReadDrawCompleteness)
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
} }
// Test that a renderbuffer with RGB565 format works as expected. This test is intended for some
// back-end having no support for native RGB565 renderbuffer and thus having to emulate using RGBA
// format.
TEST_P(FramebufferFormatsTest, RGB565Renderbuffer)
{
GLRenderbuffer rbo;
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB565, 1, 1);
GLFramebuffer completeFBO;
glBindFramebuffer(GL_FRAMEBUFFER, completeFBO);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
ASSERT_GL_NO_ERROR();
glClearColor(1, 0, 0, 0.5f);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
}
class FramebufferTest_ES3 : public ANGLETest class FramebufferTest_ES3 : public ANGLETest
{}; {};
......
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