Commit f37f1dcb by Le Hoang Quyen Committed by Commit Bot

Metal: Init format table using Metal-Feature-Set-Tables.pdf

- Format table is now initialized using informations from https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf. Previously, it was setup using gl::GenerateMinimumTextureCaps(). - This CL also adds InitializeTextureDataFunction and LoadFunctionMap to mtl::Format. They are needed to properly initialize/convert textures with non-normalized formats. - This CL is prerequisite for integer & floating point format supports. - New test: DXT1CompressedTextureTest.DXT1Alpha (this test was added in the past but was reverted for some reasons). Bug: angleproject:2634 Change-Id: I5eaad812909a49c4c138d0f65fd21a6a199fcb22 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2332144 Commit-Queue: Le Hoang Quyen <le.hoang.q@gmail.com> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 23335ac0
...@@ -34,6 +34,14 @@ struct FeaturesMtl : FeatureSetBase ...@@ -34,6 +34,14 @@ struct FeaturesMtl : FeatureSetBase
Feature hasTextureSwizzle = {"has_texture_swizzle", FeatureCategory::MetalFeatures, Feature hasTextureSwizzle = {"has_texture_swizzle", FeatureCategory::MetalFeatures,
"The renderer supports texture swizzle", &members}; "The renderer supports texture swizzle", &members};
Feature hasDepthAutoResolve = {
"has_msaa_depth_auto_resolve", FeatureCategory::MetalFeatures,
"The renderer supports MSAA depth auto resolve at the end of render pass", &members};
Feature hasStencilAutoResolve = {
"has_msaa_stencil_auto_resolve", FeatureCategory::MetalFeatures,
"The renderer supports MSAA stencil auto resolve at the end of render pass", &members};
// On macos, separate depth & stencil buffers are not supproted. However, on iOS devices, // On macos, separate depth & stencil buffers are not supproted. However, on iOS devices,
// they are supproted: // they are supproted:
Feature allowSeparatedDepthStencilBuffers = { Feature allowSeparatedDepthStencilBuffers = {
......
{ {
"src/libANGLE/renderer/angle_format.py": "src/libANGLE/renderer/angle_format.py":
"32ba71942c0fd00e6807104f1bb80a3c", "32ba71942c0fd00e6807104f1bb80a3c",
"src/libANGLE/renderer/angle_format_map.json":
"aa4a0d3463b76858a75787b9cdec8e98",
"src/libANGLE/renderer/metal/gen_mtl_format_table.py": "src/libANGLE/renderer/metal/gen_mtl_format_table.py":
"780f56abea19db610d2b829ba817fdc6", "27769e4e9cce3b7af18b69d41351c3ed",
"src/libANGLE/renderer/metal/mtl_format_map.json": "src/libANGLE/renderer/metal/mtl_format_map.json":
"7aad5b3ed806e0d932cbbfe6d3b8a834", "b202d7a0349006e2bbd58c603d9cdc28",
"src/libANGLE/renderer/metal/mtl_format_table_autogen.mm": "src/libANGLE/renderer/metal/mtl_format_table_autogen.mm":
"efd031ead828c19f5476413b2b743087" "7a0ee6139ca1e7ec8b8b0a7de9180ef7"
} }
\ No newline at end of file
...@@ -80,6 +80,7 @@ angle_source_set("angle_metal_backend") { ...@@ -80,6 +80,7 @@ angle_source_set("angle_metal_backend") {
public_deps = [ public_deps = [
"${angle_root}:angle_glslang_wrapper", "${angle_root}:angle_glslang_wrapper",
"${angle_root}:angle_image_util",
"${angle_root}:libANGLE_headers", "${angle_root}:libANGLE_headers",
] ]
......
...@@ -278,6 +278,7 @@ class ContextMtl : public ContextImpl, public mtl::Context ...@@ -278,6 +278,7 @@ class ContextMtl : public ContextImpl, public mtl::Context
bool getDepthMask() const; bool getDepthMask() const;
const mtl::Format &getPixelFormat(angle::FormatID angleFormatId) const; const mtl::Format &getPixelFormat(angle::FormatID angleFormatId) const;
const mtl::FormatCaps &getNativeFormatCaps(MTLPixelFormat mtlFormat) const;
// See mtl::FormatTable::getVertexFormat() // See mtl::FormatTable::getVertexFormat()
const mtl::VertexFormat &getVertexFormat(angle::FormatID angleFormatId, const mtl::VertexFormat &getVertexFormat(angle::FormatID angleFormatId,
bool tightlyPacked) const; bool tightlyPacked) const;
......
...@@ -1118,6 +1118,11 @@ const mtl::VertexFormat &ContextMtl::getVertexFormat(angle::FormatID angleFormat ...@@ -1118,6 +1118,11 @@ const mtl::VertexFormat &ContextMtl::getVertexFormat(angle::FormatID angleFormat
return getDisplay()->getVertexFormat(angleFormatId, tightlyPacked); return getDisplay()->getVertexFormat(angleFormatId, tightlyPacked);
} }
const mtl::FormatCaps &ContextMtl::getNativeFormatCaps(MTLPixelFormat mtlFormat) const
{
return getDisplay()->getNativeFormatCaps(mtlFormat);
}
angle::Result ContextMtl::getIncompleteTexture(const gl::Context *context, angle::Result ContextMtl::getIncompleteTexture(const gl::Context *context,
gl::TextureType type, gl::TextureType type,
gl::Texture **textureOut) gl::Texture **textureOut)
......
...@@ -107,6 +107,11 @@ class DisplayMtl : public DisplayImpl ...@@ -107,6 +107,11 @@ class DisplayMtl : public DisplayImpl
const gl::Limitations &getNativeLimitations() const { return mNativeLimitations; } const gl::Limitations &getNativeLimitations() const { return mNativeLimitations; }
const angle::FeaturesMtl &getFeatures() const { return mFeatures; } const angle::FeaturesMtl &getFeatures() const { return mFeatures; }
// Check whether either of the specified iOS or Mac GPU family is supported
bool supportsEitherGPUFamily(uint8_t iOSFamily, uint8_t macFamily) const;
bool supportsIOSGPUFamily(uint8_t iOSFamily) const;
bool supportsMacGPUFamily(uint8_t macFamily) const;
id<MTLDevice> getMetalDevice() const { return mMetalDevice; } id<MTLDevice> getMetalDevice() const { return mMetalDevice; }
mtl::CommandQueue &cmdQueue() { return mCmdQueue; } mtl::CommandQueue &cmdQueue() { return mCmdQueue; }
...@@ -129,6 +134,10 @@ class DisplayMtl : public DisplayImpl ...@@ -129,6 +134,10 @@ class DisplayMtl : public DisplayImpl
{ {
return mFormatTable.getPixelFormat(angleFormatId); return mFormatTable.getPixelFormat(angleFormatId);
} }
const mtl::FormatCaps &getNativeFormatCaps(MTLPixelFormat mtlFormat) const
{
return mFormatTable.getNativeFormatCaps(mtlFormat);
}
// See mtl::FormatTable::getVertexFormat() // See mtl::FormatTable::getVertexFormat()
const mtl::VertexFormat &getVertexFormat(angle::FormatID angleFormatId, const mtl::VertexFormat &getVertexFormat(angle::FormatID angleFormatId,
...@@ -154,7 +163,7 @@ class DisplayMtl : public DisplayImpl ...@@ -154,7 +163,7 @@ class DisplayMtl : public DisplayImpl
mtl::CommandQueue mCmdQueue; mtl::CommandQueue mCmdQueue;
mtl::FormatTable mFormatTable; mutable mtl::FormatTable mFormatTable;
mtl::StateCache mStateCache; mtl::StateCache mStateCache;
mtl::RenderUtils mUtils; mtl::RenderUtils mUtils;
......
...@@ -452,7 +452,7 @@ void DisplayMtl::ensureCapsInitialized() const ...@@ -452,7 +452,7 @@ void DisplayMtl::ensureCapsInitialized() const
mNativeCaps.maxVaryingVectors = 31; mNativeCaps.maxVaryingVectors = 31;
mNativeCaps.maxVertexOutputComponents = 124; mNativeCaps.maxVertexOutputComponents = 124;
#else #else
if ([getMetalDevice() supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v1]) if (supportsIOSGPUFamily(3))
{ {
mNativeCaps.max2DTextureSize = 16384; mNativeCaps.max2DTextureSize = 16384;
mNativeCaps.maxVertexOutputComponents = 124; mNativeCaps.maxVertexOutputComponents = 124;
...@@ -662,6 +662,12 @@ void DisplayMtl::initializeTextureCaps() const ...@@ -662,6 +662,12 @@ void DisplayMtl::initializeTextureCaps() const
void DisplayMtl::initializeFeatures() void DisplayMtl::initializeFeatures()
{ {
bool isMetal2_2 = false;
if (ANGLE_APPLE_AVAILABLE_XCI(10.15, 13.0, 13.0))
{
isMetal2_2 = true;
}
// default values: // default values:
mFeatures.hasBaseVertexInstancedDraw.enabled = true; mFeatures.hasBaseVertexInstancedDraw.enabled = true;
mFeatures.hasDepthTextureFiltering.enabled = false; mFeatures.hasDepthTextureFiltering.enabled = false;
...@@ -669,33 +675,25 @@ void DisplayMtl::initializeFeatures() ...@@ -669,33 +675,25 @@ void DisplayMtl::initializeFeatures()
mFeatures.hasTextureSwizzle.enabled = false; mFeatures.hasTextureSwizzle.enabled = false;
mFeatures.allowSeparatedDepthStencilBuffers.enabled = false; mFeatures.allowSeparatedDepthStencilBuffers.enabled = false;
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST ANGLE_FEATURE_CONDITION((&mFeatures), hasDepthTextureFiltering,
mFeatures.hasDepthTextureFiltering.enabled = true; TARGET_OS_OSX || TARGET_OS_MACCATALYST);
mFeatures.allowMultisampleStoreAndResolve.enabled = true; ANGLE_FEATURE_CONDITION((&mFeatures), hasDepthAutoResolve, supportsEitherGPUFamily(3, 2));
ANGLE_FEATURE_CONDITION((&mFeatures), hasStencilAutoResolve, supportsEitherGPUFamily(5, 2));
ANGLE_FEATURE_CONDITION((&mFeatures), allowMultisampleStoreAndResolve,
supportsEitherGPUFamily(3, 1));
// Texture swizzle is only supported if macos sdk 10.15 is present ANGLE_FEATURE_CONDITION((&mFeatures), hasTextureSwizzle,
# if defined(__MAC_10_15) isMetal2_2 && supportsEitherGPUFamily(1, 2));
if (ANGLE_APPLE_AVAILABLE_XC(10.15, 13.0))
{ #if !TARGET_OS_MACCATALYST && (TARGET_OS_IOS || TARGET_OS_TV)
// The runtime OS must be MacOS 10.15+ or Mac Catalyst for this to be supported:
ANGLE_FEATURE_CONDITION((&mFeatures), hasTextureSwizzle,
[getMetalDevice() supportsFamily:MTLGPUFamilyMac2]);
}
# endif
#elif TARGET_OS_IOS
// Base Vertex drawing is only supported since GPU family 3. // Base Vertex drawing is only supported since GPU family 3.
ANGLE_FEATURE_CONDITION((&mFeatures), hasBaseVertexInstancedDraw, ANGLE_FEATURE_CONDITION((&mFeatures), hasBaseVertexInstancedDraw, supportsIOSGPUFamily(3));
[getMetalDevice() supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v1]);
ANGLE_FEATURE_CONDITION((&mFeatures), hasNonUniformDispatch, ANGLE_FEATURE_CONDITION((&mFeatures), hasNonUniformDispatch,
[getMetalDevice() supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily4_v1]); TARGET_OS_IOS && supportsIOSGPUFamily(4));
ANGLE_FEATURE_CONDITION((&mFeatures), allowMultisampleStoreAndResolve, ANGLE_FEATURE_CONDITION((&mFeatures), allowSeparatedDepthStencilBuffers, !TARGET_OS_SIMULATOR);
[getMetalDevice() supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v1]);
# if !TARGET_OS_SIMULATOR
mFeatures.allowSeparatedDepthStencilBuffers.enabled = true;
# endif
#endif #endif
angle::PlatformMethods *platform = ANGLEPlatformCurrent(); angle::PlatformMethods *platform = ANGLEPlatformCurrent();
...@@ -715,8 +713,8 @@ angle::Result DisplayMtl::initializeShaderLibrary() ...@@ -715,8 +713,8 @@ angle::Result DisplayMtl::initializeShaderLibrary()
compiled_shader_binary = compiled_default_metallib_debug; compiled_shader_binary = compiled_default_metallib_debug;
compiled_shader_binary_len = compiled_default_metallib_debug_len; compiled_shader_binary_len = compiled_default_metallib_debug_len;
#else #else
compiled_shader_binary = compiled_default_metallib; compiled_shader_binary = compiled_default_metallib;
compiled_shader_binary_len = compiled_default_metallib_len; compiled_shader_binary_len = compiled_default_metallib_len;
#endif #endif
mDefaultShaders = CreateShaderLibraryFromBinary(getMetalDevice(), compiled_shader_binary, mDefaultShaders = CreateShaderLibraryFromBinary(getMetalDevice(), compiled_shader_binary,
...@@ -734,4 +732,151 @@ angle::Result DisplayMtl::initializeShaderLibrary() ...@@ -734,4 +732,151 @@ angle::Result DisplayMtl::initializeShaderLibrary()
return angle::Result::Continue; return angle::Result::Continue;
} }
bool DisplayMtl::supportsIOSGPUFamily(uint8_t iOSFamily) const
{
#if (!TARGET_OS_IOS && !TARGET_OS_TV) || TARGET_OS_MACCATALYST
return false;
#else
# if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 130000) || (__TV_OS_VERSION_MAX_ALLOWED >= 130000)
// If device supports [MTLDevice supportsFamily:], then use it.
if (ANGLE_APPLE_AVAILABLE_I(13.0))
{
MTLGPUFamily family;
switch (iOSFamily)
{
case 1:
family = MTLGPUFamilyApple1;
break;
case 2:
family = MTLGPUFamilyApple2;
break;
case 3:
family = MTLGPUFamilyApple3;
break;
case 4:
family = MTLGPUFamilyApple4;
break;
case 5:
family = MTLGPUFamilyApple5;
break;
# if TARGET_OS_IOS
case 6:
family = MTLGPUFamilyApple6;
break;
# endif
default:
return false;
}
return [getMetalDevice() supportsFamily:family];
} // Metal 2.2
# endif // __IPHONE_OS_VERSION_MAX_ALLOWED
// If device doesn't support [MTLDevice supportsFamily:], then use
// [MTLDevice supportsFeatureSet:].
MTLFeatureSet featureSet;
switch (iOSFamily)
{
# if TARGET_OS_IOS
case 1:
featureSet = MTLFeatureSet_iOS_GPUFamily1_v1;
break;
case 2:
featureSet = MTLFeatureSet_iOS_GPUFamily2_v1;
break;
case 3:
featureSet = MTLFeatureSet_iOS_GPUFamily3_v1;
break;
case 4:
featureSet = MTLFeatureSet_iOS_GPUFamily4_v1;
break;
# if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000
case 5:
featureSet = MTLFeatureSet_iOS_GPUFamily5_v1;
break;
# endif // __IPHONE_OS_VERSION_MAX_ALLOWED
# elif TARGET_OS_TV
case 1:
case 2:
featureSet = MTLFeatureSet_tvOS_GPUFamily1_v1;
break;
case 3:
featureSet = MTLFeatureSet_tvOS_GPUFamily2_v1;
break;
# endif // TARGET_OS_IOS
default:
return false;
}
return [getMetalDevice() supportsFeatureSet:featureSet];
#endif // TARGET_OS_IOS || TARGET_OS_TV
}
bool DisplayMtl::supportsMacGPUFamily(uint8_t macFamily) const
{
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
# if defined(__MAC_10_15)
// If device supports [MTLDevice supportsFamily:], then use it.
if (ANGLE_APPLE_AVAILABLE_XC(10.15, 13.0))
{
MTLGPUFamily family;
switch (macFamily)
{
# if TARGET_OS_MACCATALYST
case 1:
family = MTLGPUFamilyMacCatalyst1;
break;
case 2:
family = MTLGPUFamilyMacCatalyst2;
break;
# else // TARGET_OS_MACCATALYST
case 1:
family = MTLGPUFamilyMac1;
break;
case 2:
family = MTLGPUFamilyMac2;
break;
# endif // TARGET_OS_MACCATALYST
default:
return false;
}
return [getMetalDevice() supportsFamily:family];
} // Metal 2.2
# endif
// If device doesn't support [MTLDevice supportsFamily:], then use
// [MTLDevice supportsFeatureSet:].
# if TARGET_OS_MACCATALYST
UNREACHABLE();
return false;
# else
MTLFeatureSet featureSet;
switch (macFamily)
{
case 1:
featureSet = MTLFeatureSet_macOS_GPUFamily1_v1;
break;
# if defined(__MAC_10_14)
case 2:
featureSet = MTLFeatureSet_macOS_GPUFamily2_v1;
break;
# endif
default:
return false;
}
return [getMetalDevice() supportsFeatureSet:featureSet];
# endif // TARGET_OS_MACCATALYST
#else // #if TARGET_OS_OSX || TARGET_OS_MACCATALYST
return false;
#endif
}
bool DisplayMtl::supportsEitherGPUFamily(uint8_t iOSFamily, uint8_t macFamily) const
{
return supportsIOSGPUFamily(iOSFamily) || supportsMacGPUFamily(macFamily);
}
} // namespace rx } // namespace rx
...@@ -67,8 +67,7 @@ angle::Result RenderbufferMtl::setStorageImpl(const gl::Context *context, ...@@ -67,8 +67,7 @@ angle::Result RenderbufferMtl::setStorageImpl(const gl::Context *context,
// For emulated channels that GL texture intends to not have, // For emulated channels that GL texture intends to not have,
// we need to initialize their content. // we need to initialize their content.
bool emulatedChannels; bool emulatedChannels = mtl::IsFormatEmulated(mFormat);
mTexture->setColorWritableMask(mtl::GetEmulatedColorWriteMask(mFormat, &emulatedChannels));
if (emulatedChannels) if (emulatedChannels)
{ {
gl::ImageIndex index; gl::ImageIndex index;
......
...@@ -255,6 +255,7 @@ class TextureMtl : public TextureImpl ...@@ -255,6 +255,7 @@ class TextureMtl : public TextureImpl
const gl::ImageIndex &index, const gl::ImageIndex &index,
const MTLRegion &mtlArea, const MTLRegion &mtlArea,
const gl::InternalFormat &internalFormat, const gl::InternalFormat &internalFormat,
GLenum type,
const angle::Format &pixelsFormat, const angle::Format &pixelsFormat,
size_t pixelsRowPitch, size_t pixelsRowPitch,
const uint8_t *pixels); const uint8_t *pixels);
......
...@@ -1007,9 +1007,9 @@ angle::Result TextureMtl::setSubImageImpl(const gl::Context *context, ...@@ -1007,9 +1007,9 @@ angle::Result TextureMtl::setSubImageImpl(const gl::Context *context,
angle::Format::Get(angle::Format::InternalFormatToID(formatInfo.sizedInternalFormat)); angle::Format::Get(angle::Format::InternalFormatToID(formatInfo.sizedInternalFormat));
// If source pixels are luminance or RGB8, we need to convert them to RGBA // If source pixels are luminance or RGB8, we need to convert them to RGBA
if (mFormat.actualFormatId != srcAngleFormat.id) if (mFormat.needConversion(srcAngleFormat.id))
{ {
return convertAndSetSubImage(context, index, mtlRegion, formatInfo, srcAngleFormat, return convertAndSetSubImage(context, index, mtlRegion, formatInfo, type, srcAngleFormat,
sourceRowPitch, pixels); sourceRowPitch, pixels);
} }
...@@ -1024,6 +1024,7 @@ angle::Result TextureMtl::convertAndSetSubImage(const gl::Context *context, ...@@ -1024,6 +1024,7 @@ angle::Result TextureMtl::convertAndSetSubImage(const gl::Context *context,
const gl::ImageIndex &index, const gl::ImageIndex &index,
const MTLRegion &mtlArea, const MTLRegion &mtlArea,
const gl::InternalFormat &internalFormat, const gl::InternalFormat &internalFormat,
GLenum type,
const angle::Format &pixelsFormat, const angle::Format &pixelsFormat,
size_t pixelsRowPitch, size_t pixelsRowPitch,
const uint8_t *pixels) const uint8_t *pixels)
...@@ -1034,29 +1035,63 @@ angle::Result TextureMtl::convertAndSetSubImage(const gl::Context *context, ...@@ -1034,29 +1035,63 @@ angle::Result TextureMtl::convertAndSetSubImage(const gl::Context *context,
ContextMtl *contextMtl = mtl::GetImpl(context); ContextMtl *contextMtl = mtl::GetImpl(context);
// Create scratch buffer LoadImageFunctionInfo loadFunctionInfo =
mFormat.textureLoadFunctions ? mFormat.textureLoadFunctions(type) : LoadImageFunctionInfo();
const angle::Format &dstFormat = angle::Format::Get(mFormat.actualFormatId); const angle::Format &dstFormat = angle::Format::Get(mFormat.actualFormatId);
angle::MemoryBuffer conversionRow; const size_t dstRowPitch = dstFormat.pixelBytes * mtlArea.size.width;
const size_t dstRowPitch = dstFormat.pixelBytes * mtlArea.size.width;
ANGLE_CHECK_GL_ALLOC(contextMtl, conversionRow.resize(dstRowPitch));
MTLRegion mtlRow = mtlArea; // Check if original image data is compressed:
mtlRow.size.height = 1; if (mFormat.intendedAngleFormat().isBlock)
const uint8_t *psrc = pixels;
for (NSUInteger r = 0; r < mtlArea.size.height; ++r, psrc += pixelsRowPitch)
{ {
mtlRow.origin.y = mtlArea.origin.y + r; ASSERT(loadFunctionInfo.loadFunction);
// Need to create a buffer to hold entire decompressed image.
const size_t dstDepthPitch = dstRowPitch * mtlArea.size.height;
angle::MemoryBuffer decompressBuf;
ANGLE_CHECK_GL_ALLOC(contextMtl, decompressBuf.resize(dstDepthPitch * mtlArea.size.depth));
// Convert pixels // Decompress
CopyImageCHROMIUM(psrc, pixelsRowPitch, pixelsFormat.pixelBytes, 0, loadFunctionInfo.loadFunction(mtlArea.size.width, mtlArea.size.height, mtlArea.size.depth,
pixelsFormat.pixelReadFunction, conversionRow.data(), dstRowPitch, pixels, pixelsRowPitch, 0, decompressBuf.data(), dstRowPitch,
dstFormat.pixelBytes, 0, dstFormat.pixelWriteFunction, dstDepthPitch);
internalFormat.format, dstFormat.componentType, mtlRow.size.width, 1, 1,
false, false, false);
// Upload to texture // Upload to texture
ANGLE_TRY(UploadTextureContents(context, image, dstFormat, mtlRow, 0, 0, ANGLE_TRY(UploadTextureContents(context, image, dstFormat, mtlArea, 0, 0,
conversionRow.data(), dstRowPitch)); decompressBuf.data(), dstRowPitch));
} // if (mFormat.intendedAngleFormat().isBlock)
else
{
// Create scratch buffer
angle::MemoryBuffer conversionRow;
ANGLE_CHECK_GL_ALLOC(contextMtl, conversionRow.resize(dstRowPitch));
MTLRegion mtlRow = mtlArea;
mtlRow.size.height = 1;
const uint8_t *psrc = pixels;
for (NSUInteger r = 0; r < mtlArea.size.height; ++r, psrc += pixelsRowPitch)
{
mtlRow.origin.y = mtlArea.origin.y + r;
// Convert pixels
if (loadFunctionInfo.loadFunction)
{
loadFunctionInfo.loadFunction(mtlRow.size.width, 1, 1, psrc, pixelsRowPitch, 0,
conversionRow.data(), dstRowPitch, 0);
}
else
{
CopyImageCHROMIUM(psrc, pixelsRowPitch, pixelsFormat.pixelBytes, 0,
pixelsFormat.pixelReadFunction, conversionRow.data(), dstRowPitch,
dstFormat.pixelBytes, 0, dstFormat.pixelWriteFunction,
internalFormat.format, dstFormat.componentType, mtlRow.size.width,
1, 1, false, false, false);
}
// Upload to texture
ANGLE_TRY(UploadTextureContents(context, image, dstFormat, mtlRow, 0, 0,
conversionRow.data(), dstRowPitch));
}
} }
return angle::Result::Continue; return angle::Result::Continue;
...@@ -1066,10 +1101,7 @@ angle::Result TextureMtl::checkForEmulatedChannels(const gl::Context *context, ...@@ -1066,10 +1101,7 @@ 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 = mtl::IsFormatEmulated(mtlFormat);
MTLColorWriteMask colorWritableMask =
mtl::GetEmulatedColorWriteMask(mtlFormat, &emulatedChannels);
texture->setColorWritableMask(colorWritableMask);
// For emulated channels that GL texture intends to not have, // For emulated channels that GL texture intends to not have,
// we need to initialize their content. // we need to initialize their content.
...@@ -1135,7 +1167,7 @@ angle::Result TextureMtl::copySubImageImpl(const gl::Context *context, ...@@ -1135,7 +1167,7 @@ angle::Result TextureMtl::copySubImageImpl(const gl::Context *context,
ANGLE_TRY(ensureImageCreated(context, index)); ANGLE_TRY(ensureImageCreated(context, index));
if (!mtl::Format::FormatRenderable(mFormat.metalFormat)) if (!mFormat.getCaps().isRenderable())
{ {
return copySubImageCPU(context, index, modifiedDestOffset, clippedSourceArea, return copySubImageCPU(context, index, modifiedDestOffset, clippedSourceArea,
internalFormat, source); internalFormat, source);
...@@ -1265,7 +1297,7 @@ angle::Result TextureMtl::copySubTextureImpl(const gl::Context *context, ...@@ -1265,7 +1297,7 @@ angle::Result TextureMtl::copySubTextureImpl(const gl::Context *context,
const mtl::Format &dstFormat = contextMtl->getPixelFormat( const mtl::Format &dstFormat = contextMtl->getPixelFormat(
angle::Format::InternalFormatToID(internalFormat.sizedInternalFormat)); angle::Format::InternalFormatToID(internalFormat.sizedInternalFormat));
if (!mtl::Format::FormatRenderable(dstFormat.metalFormat)) if (!dstFormat.getCaps().isRenderable())
{ {
return copySubTextureCPU(context, index, destOffset, internalFormat, 0, sourceBox, return copySubTextureCPU(context, index, destOffset, internalFormat, 0, sourceBox,
srcAngleFormat, unpackFlipY, unpackPremultiplyAlpha, srcAngleFormat, unpackFlipY, unpackPremultiplyAlpha,
......
...@@ -16,7 +16,7 @@ import re ...@@ -16,7 +16,7 @@ import re
import sys import sys
sys.path.append('..') sys.path.append('..')
import angle_format import angle_format as angle_format_utils
template_autogen_inl = """// GENERATED FILE - DO NOT EDIT. template_autogen_inl = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name} // Generated by {script_name} using data from {data_source_name}
...@@ -31,10 +31,15 @@ template_autogen_inl = """// GENERATED FILE - DO NOT EDIT. ...@@ -31,10 +31,15 @@ template_autogen_inl = """// GENERATED FILE - DO NOT EDIT.
#import <Metal/Metal.h> #import <Metal/Metal.h>
#include <TargetConditionals.h> #include <TargetConditionals.h>
#include "image_util/copyimage.h"
#include "image_util/generatemip.h"
#include "image_util/loadimage.h"
#include "libANGLE/renderer/Format.h" #include "libANGLE/renderer/Format.h"
#include "libANGLE/renderer/metal/DisplayMtl.h" #include "libANGLE/renderer/metal/DisplayMtl.h"
#include "libANGLE/renderer/metal/mtl_format_utils.h" #include "libANGLE/renderer/metal/mtl_format_utils.h"
using namespace angle;
namespace rx namespace rx
{{ {{
namespace mtl namespace mtl
...@@ -68,23 +73,47 @@ void VertexFormat::init(angle::FormatID angleFormatId, bool tightlyPacked) ...@@ -68,23 +73,47 @@ void VertexFormat::init(angle::FormatID angleFormatId, bool tightlyPacked)
}} // namespace rx }} // namespace rx
""" """
case_image_format_template1 = """ case angle::FormatID::{angle_format}: image_format_assign_template1 = """
this->metalFormat = {mtl_format}; this->metalFormat = {mtl_format};
this->actualFormatId = angle::FormatID::{actual_angle_format}; this->actualFormatId = angle::FormatID::{actual_angle_format};
break; this->initFunction = {init_function};
""" """
case_image_format_template2 = """ case angle::FormatID::{angle_format}: image_format_assign_template2 = """
if (metalDevice.depth24Stencil8PixelFormatSupported) if (metalDevice.depth24Stencil8PixelFormatSupported)
{{ {{
this->metalFormat = {mtl_format}; this->metalFormat = {mtl_format};
this->actualFormatId = angle::FormatID::{actual_angle_format}; this->actualFormatId = angle::FormatID::{actual_angle_format};
this->initFunction = {init_function};
}} }}
else else
{{ {{
this->metalFormat = {mtl_format_fallback}; this->metalFormat = {mtl_format_fallback};
this->actualFormatId = angle::FormatID::{actual_angle_format_fallback}; this->actualFormatId = angle::FormatID::{actual_angle_format_fallback};
this->initFunction = {init_function_fallback};
}}
"""
case_image_format_template1 = """ case angle::FormatID::{angle_format}:
{image_format_assign}
this->swizzled = false;
break;
"""
case_image_format_template2 = """ case angle::FormatID::{angle_format}:
#if defined(__IPHONE_13_0) || defined(__MAC_10_15)
if (display->getFeatures().hasTextureSwizzle.enabled)
{{
{image_format_assign_swizzled}
this->swizzled = true;
this->swizzle = {mtl_swizzle};
}}
else
#endif // #if defined(__IPHONE_13_0) || defined(__MAC_10_15)
{{
{image_format_assign_default}
this->swizzled = false;
}} }}
break; break;
...@@ -94,6 +123,8 @@ case_vertex_format_template1 = """ case angle::FormatID::{angle_format}: ...@@ -94,6 +123,8 @@ case_vertex_format_template1 = """ case angle::FormatID::{angle_format}:
this->metalFormat = {mtl_format}; this->metalFormat = {mtl_format};
this->actualFormatId = angle::FormatID::{actual_angle_format}; this->actualFormatId = angle::FormatID::{actual_angle_format};
this->vertexLoadFunction = {vertex_copy_function}; this->vertexLoadFunction = {vertex_copy_function};
this->defaultAlpha = {default_alpha};
this->actualSameGLType = {same_gl_type};
break; break;
""" """
...@@ -104,59 +135,157 @@ case_vertex_format_template2 = """ case angle::FormatID::{angle_format}: ...@@ -104,59 +135,157 @@ case_vertex_format_template2 = """ case angle::FormatID::{angle_format}:
this->metalFormat = {mtl_format_packed}; this->metalFormat = {mtl_format_packed};
this->actualFormatId = angle::FormatID::{actual_angle_format_packed}; this->actualFormatId = angle::FormatID::{actual_angle_format_packed};
this->vertexLoadFunction = {vertex_copy_function_packed}; this->vertexLoadFunction = {vertex_copy_function_packed};
this->defaultAlpha = {default_alpha_packed};
this->actualSameGLType = {same_gl_type_packed};
}} }}
else else
{{ {{
this->metalFormat = {mtl_format}; this->metalFormat = {mtl_format};
this->actualFormatId = angle::FormatID::{actual_angle_format}; this->actualFormatId = angle::FormatID::{actual_angle_format};
this->vertexLoadFunction = {vertex_copy_function}; this->vertexLoadFunction = {vertex_copy_function};
this->defaultAlpha = {default_alpha};
this->actualSameGLType = {same_gl_type};
}} }}
break; break;
""" """
def gen_image_map_switch_simple_case(angle_format, actual_angle_format, angle_to_mtl_map): # NOTE(hqle): This is a modified version of the get_vertex_copy_function() function in
mtl_format = angle_to_mtl_map[actual_angle_format] # src/libANGLE/renderer/angle_format.py
return case_image_format_template1.format( # - Return value is a tuple {copy_function, default_alpha_value, have_same_gl_type}.
angle_format=angle_format, actual_angle_format=actual_angle_format, mtl_format=mtl_format) def get_vertex_copy_function_and_default_alpha(src_format, dst_format):
if dst_format == "NONE":
return "nullptr", 0, "false"
def gen_image_map_switch_mac_case(angle_format, actual_angle_format, angle_to_mtl_map,
mac_specific_map, mac_fallbacks): num_channel = len(angle_format_utils.get_channel_tokens(src_format))
if actual_angle_format in mac_specific_map: if num_channel < 1 or num_channel > 4:
# look for the metal format in mac specific table return "nullptr", 0, "false"
mtl_format = mac_specific_map[actual_angle_format]
else: src_gl_type = angle_format_utils.get_format_gl_type(src_format)
# look for the metal format in common table dst_gl_type = angle_format_utils.get_format_gl_type(dst_format)
mtl_format = angle_to_mtl_map[actual_angle_format]
if src_gl_type == dst_gl_type:
if actual_angle_format in mac_fallbacks: if src_format.startswith('R10G10B10A2'):
# This format requires fallback when depth24Stencil8PixelFormatSupported flag is false. return 'CopyNativeVertexData<GLuint, 1, 1, 0>', 0, "true"
# Fallback format:
actual_angle_format_fallback = mac_fallbacks[actual_angle_format] if src_gl_type == None:
if actual_angle_format_fallback in mac_specific_map: return 'nullptr', 0, "true"
# look for the metal format in mac specific table dst_num_channel = len(angle_format_utils.get_channel_tokens(dst_format))
mtl_format_fallback = mac_specific_map[actual_angle_format_fallback] default_alpha = '1'
if num_channel == dst_num_channel or dst_num_channel < 4:
default_alpha = '0'
elif 'A16_FLOAT' in dst_format:
default_alpha = 'gl::Float16One'
elif 'A32_FLOAT' in dst_format:
default_alpha = 'gl::Float32One'
elif 'NORM' in dst_format:
default_alpha = 'std::numeric_limits<%s>::max()' % (src_gl_type)
return 'CopyNativeVertexData<%s, %d, %d, %s>' % (src_gl_type, num_channel, dst_num_channel,
default_alpha), default_alpha, "true"
if src_format.startswith('R10G10B10A2'):
assert 'FLOAT' in dst_format, ('get_vertex_copy_function: can only convert to float,' +
' not to ' + dst_format)
is_signed = 'true' if 'SINT' in src_format or 'SNORM' in src_format or 'SSCALED' in src_format else 'false'
is_normal = 'true' if 'NORM' in src_format else 'false'
return 'CopyXYZ10W2ToXYZW32FVertexData<%s, %s, true>' % (is_signed, is_normal), 0, "false"
return angle_format_utils.get_vertex_copy_function(src_format, dst_format), 0, "false"
# Generate format conversion switch case (generic case)
def gen_image_map_switch_case(angle_format, actual_angle_format_info, angle_to_mtl_map,
assign_gen_func):
if isinstance(actual_angle_format_info, dict):
default_actual_angle_format = actual_angle_format_info['default']
# Check if the format can be override with swizzle feature
if 'swizzle' in actual_angle_format_info:
swizzle_info = actual_angle_format_info['swizzle']
swizzle_channels = swizzle_info[0]
swizzled_actual_angle_format = swizzle_info[1]
swizzle_map = {
'R': 'GL_RED',
'G': 'GL_GREEN',
'B': 'GL_BLUE',
'A': 'GL_ALPHA',
'1': 'GL_ONE',
'0': 'GL_ZERO',
}
mtl_swizzle_make = '{{{r}, {g}, {b}, {a}}}'.format(
r=swizzle_map[swizzle_channels[0:1]],
g=swizzle_map[swizzle_channels[1:2]],
b=swizzle_map[swizzle_channels[2:3]],
a=swizzle_map[swizzle_channels[3:]])
return case_image_format_template2.format(
angle_format=angle_format,
image_format_assign_default=assign_gen_func(default_actual_angle_format,
angle_to_mtl_map),
image_format_assign_swizzled=assign_gen_func(swizzled_actual_angle_format,
angle_to_mtl_map),
mtl_swizzle=mtl_swizzle_make)
else: else:
# look for the metal format in common table # Only default case
mtl_format_fallback = angle_to_mtl_map[actual_angle_format_fallback] return gen_image_map_switch_case(angle_format, default_actual_angle_format,
# return if else block: angle_to_mtl_map, assign_gen_func)
return case_image_format_template2.format(
angle_format=angle_format,
actual_angle_format=actual_angle_format,
mtl_format=mtl_format,
actual_angle_format_fallback=actual_angle_format_fallback,
mtl_format_fallback=mtl_format_fallback)
else: else:
# return ordinary block: # Default case
return case_image_format_template1.format( return case_image_format_template1.format(
angle_format=angle_format, angle_format=angle_format,
image_format_assign=assign_gen_func(actual_angle_format_info, angle_to_mtl_map))
# Generate format conversion switch case (simple case)
def gen_image_map_switch_simple_case(angle_format, actual_angle_format_info, angle_to_gl,
angle_to_mtl_map):
def gen_format_assign_code(actual_angle_format, angle_to_mtl_map):
return image_format_assign_template1.format(
actual_angle_format=actual_angle_format, actual_angle_format=actual_angle_format,
mtl_format=mtl_format) mtl_format=angle_to_mtl_map[actual_angle_format],
init_function=angle_format_utils.get_internal_format_initializer(
angle_to_gl[angle_format], actual_angle_format))
return gen_image_map_switch_case(angle_format, actual_angle_format_info, angle_to_mtl_map,
gen_format_assign_code)
# Generate format conversion switch case (Mac case)
def gen_image_map_switch_mac_case(angle_format, actual_angle_format_info, angle_to_gl,
angle_to_mtl_map, mac_fallbacks):
gl_format = angle_to_gl[angle_format]
def gen_format_assign_code(actual_angle_format, angle_to_mtl_map):
if actual_angle_format in mac_fallbacks:
# This format requires fallback when depth24Stencil8PixelFormatSupported flag is false.
# Fallback format:
actual_angle_format_fallback = mac_fallbacks[actual_angle_format]
# return if else block:
return image_format_assign_template2.format(
actual_angle_format=actual_angle_format,
mtl_format=angle_to_mtl_map[actual_angle_format],
init_function=angle_format_utils.get_internal_format_initializer(
gl_format, actual_angle_format),
actual_angle_format_fallback=actual_angle_format_fallback,
mtl_format_fallback=angle_to_mtl_map[actual_angle_format_fallback],
init_function_fallback=angle_format_utils.get_internal_format_initializer(
gl_format, actual_angle_format_fallback))
else:
# return ordinary block:
return image_format_assign_template1.format(
actual_angle_format=actual_angle_format,
mtl_format=angle_to_mtl_map[actual_angle_format],
init_function=angle_format_utils.get_internal_format_initializer(
gl_format, actual_angle_format))
return gen_image_map_switch_case(angle_format, actual_angle_format_info, angle_to_mtl_map,
gen_format_assign_code)
def gen_image_map_switch_string(image_table): def gen_image_map_switch_string(image_table, angle_to_gl):
angle_override = image_table["override"] angle_override = image_table["override"]
mac_override = image_table["override_mac"] mac_override = image_table["override_mac"]
ios_override = image_table["override_ios"] ios_override = image_table["override_ios"]
...@@ -165,13 +294,20 @@ def gen_image_map_switch_string(image_table): ...@@ -165,13 +294,20 @@ def gen_image_map_switch_string(image_table):
mac_specific_map = image_table["map_mac"] mac_specific_map = image_table["map_mac"]
ios_specific_map = image_table["map_ios"] ios_specific_map = image_table["map_ios"]
# mac_specific_map + angle_to_mtl:
mac_angle_to_mtl = mac_specific_map.copy()
mac_angle_to_mtl.update(angle_to_mtl)
# ios_specific_map + angle_to_mtl
ios_angle_to_mtl = ios_specific_map.copy()
ios_angle_to_mtl.update(angle_to_mtl)
switch_data = '' switch_data = ''
def gen_image_map_switch_common_case(angle_format, actual_angle_format): def gen_image_map_switch_common_case(angle_format, actual_angle_format):
mac_case = gen_image_map_switch_mac_case(angle_format, actual_angle_format, angle_to_mtl, mac_case = gen_image_map_switch_mac_case(angle_format, actual_angle_format, angle_to_gl,
mac_specific_map, mac_fallbacks) mac_angle_to_mtl, mac_fallbacks)
non_mac_case = gen_image_map_switch_simple_case(angle_format, actual_angle_format, non_mac_case = gen_image_map_switch_simple_case(angle_format, actual_angle_format,
angle_to_mtl) angle_to_gl, angle_to_mtl)
if mac_case == non_mac_case: if mac_case == non_mac_case:
return mac_case return mac_case
...@@ -192,22 +328,20 @@ def gen_image_map_switch_string(image_table): ...@@ -192,22 +328,20 @@ def gen_image_map_switch_string(image_table):
# Mac specific # Mac specific
switch_data += "#if TARGET_OS_OSX || TARGET_OS_MACCATALYST\n" switch_data += "#if TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
for angle_format in sorted(mac_specific_map.keys()): for angle_format in sorted(mac_specific_map.keys()):
switch_data += gen_image_map_switch_mac_case(angle_format, angle_format, angle_to_mtl, switch_data += gen_image_map_switch_mac_case(angle_format, angle_format, angle_to_gl,
mac_specific_map, mac_fallbacks) mac_angle_to_mtl, mac_fallbacks)
for angle_format in sorted(mac_override.keys()): for angle_format in sorted(mac_override.keys()):
# overide case will always map to a format in common table, i.e. angle_to_mtl
switch_data += gen_image_map_switch_mac_case(angle_format, mac_override[angle_format], switch_data += gen_image_map_switch_mac_case(angle_format, mac_override[angle_format],
angle_to_mtl, mac_specific_map, mac_fallbacks) angle_to_gl, mac_angle_to_mtl, mac_fallbacks)
# iOS specific # iOS specific
switch_data += "#elif TARGET_OS_IOS // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n" switch_data += "#elif TARGET_OS_IOS || TARGET_OS_TV // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
for angle_format in sorted(ios_specific_map.keys()): for angle_format in sorted(ios_specific_map.keys()):
switch_data += gen_image_map_switch_simple_case(angle_format, angle_format, switch_data += gen_image_map_switch_simple_case(angle_format, angle_format, angle_to_gl,
ios_specific_map) ios_specific_map)
for angle_format in sorted(ios_override.keys()): for angle_format in sorted(ios_override.keys()):
# overide case will always map to a format in common table, i.e. angle_to_mtl
switch_data += gen_image_map_switch_simple_case(angle_format, ios_override[angle_format], switch_data += gen_image_map_switch_simple_case(angle_format, ios_override[angle_format],
angle_to_mtl) angle_to_gl, ios_angle_to_mtl)
switch_data += "#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n" switch_data += "#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
switch_data += " default:\n" switch_data += " default:\n"
switch_data += " this->metalFormat = MTLPixelFormatInvalid;\n" switch_data += " this->metalFormat = MTLPixelFormatInvalid;\n"
...@@ -217,28 +351,38 @@ def gen_image_map_switch_string(image_table): ...@@ -217,28 +351,38 @@ def gen_image_map_switch_string(image_table):
def gen_vertex_map_switch_case(angle_fmt, actual_angle_fmt, angle_to_mtl_map, override_packed_map): def gen_vertex_map_switch_case(angle_fmt, actual_angle_fmt, angle_to_mtl_map, override_packed_map):
mtl_format = angle_to_mtl_map[actual_angle_fmt] mtl_format = angle_to_mtl_map[actual_angle_fmt]
copy_function = angle_format.get_vertex_copy_function(angle_fmt, actual_angle_fmt) copy_function, default_alpha, same_gl_type = get_vertex_copy_function_and_default_alpha(
angle_fmt, actual_angle_fmt)
if actual_angle_fmt in override_packed_map: if actual_angle_fmt in override_packed_map:
# This format has an override when used in tightly packed buffer, # This format has an override when used in tightly packed buffer,
# Return if else block # Return if else block
angle_fmt_packed = override_packed_map[actual_angle_fmt] angle_fmt_packed = override_packed_map[actual_angle_fmt]
mtl_format_packed = angle_to_mtl_map[angle_fmt_packed] mtl_format_packed = angle_to_mtl_map[angle_fmt_packed]
copy_function_packed = angle_format.get_vertex_copy_function(angle_fmt, angle_fmt_packed) copy_function_packed, default_alpha_packed, same_gl_type_packed = get_vertex_copy_function_and_default_alpha(
angle_fmt, angle_fmt_packed)
return case_vertex_format_template2.format( return case_vertex_format_template2.format(
angle_format=angle_fmt, angle_format=angle_fmt,
mtl_format_packed=mtl_format_packed, mtl_format_packed=mtl_format_packed,
actual_angle_format_packed=angle_fmt_packed, actual_angle_format_packed=angle_fmt_packed,
vertex_copy_function_packed=copy_function_packed, vertex_copy_function_packed=copy_function_packed,
default_alpha_packed=default_alpha_packed,
same_gl_type_packed=same_gl_type_packed,
mtl_format=mtl_format, mtl_format=mtl_format,
actual_angle_format=actual_angle_fmt, actual_angle_format=actual_angle_fmt,
vertex_copy_function=copy_function) vertex_copy_function=copy_function,
default_alpha=default_alpha,
same_gl_type=same_gl_type)
else: else:
# This format has no packed buffer's override, return ordinary block. # This format has no packed buffer's override, return ordinary block.
return case_vertex_format_template1.format( return case_vertex_format_template1.format(
angle_format=angle_fmt, angle_format=angle_fmt,
mtl_format=mtl_format, mtl_format=mtl_format,
actual_angle_format=actual_angle_fmt, actual_angle_format=actual_angle_fmt,
vertex_copy_function=copy_function) vertex_copy_function=copy_function,
default_alpha=default_alpha,
same_gl_type=same_gl_type)
def gen_vertex_map_switch_string(vertex_table): def gen_vertex_map_switch_string(vertex_table):
...@@ -259,13 +403,16 @@ def gen_vertex_map_switch_string(vertex_table): ...@@ -259,13 +403,16 @@ def gen_vertex_map_switch_string(vertex_table):
switch_data += " this->metalFormat = MTLVertexFormatInvalid;\n" switch_data += " this->metalFormat = MTLVertexFormatInvalid;\n"
switch_data += " this->actualFormatId = angle::FormatID::NONE;\n" switch_data += " this->actualFormatId = angle::FormatID::NONE;\n"
switch_data += " this->vertexLoadFunction = nullptr;" switch_data += " this->vertexLoadFunction = nullptr;"
switch_data += " this->defaultAlpha = 0;"
switch_data += " this->actualSameGLType = false;"
return switch_data return switch_data
def main(): def main():
data_source_name = 'mtl_format_map.json'
# auto_script parameters. # auto_script parameters.
if len(sys.argv) > 1: if len(sys.argv) > 1:
inputs = ['../angle_format.py', 'mtl_format_map.json'] inputs = ['../angle_format.py', '../angle_format_map.json', data_source_name]
outputs = ['mtl_format_table_autogen.mm'] outputs = ['mtl_format_table_autogen.mm']
if sys.argv[1] == 'inputs': if sys.argv[1] == 'inputs':
...@@ -277,12 +424,13 @@ def main(): ...@@ -277,12 +424,13 @@ def main():
return 1 return 1
return 0 return 0
data_source_name = 'mtl_format_map.json' angle_to_gl = angle_format_utils.load_inverse_table('../angle_format_map.json')
map_json = angle_format.load_json(data_source_name)
map_json = angle_format_utils.load_json(data_source_name)
map_image = map_json["image"] map_image = map_json["image"]
map_vertex = map_json["vertex"] map_vertex = map_json["vertex"]
image_switch_data = gen_image_map_switch_string(map_image) image_switch_data = gen_image_map_switch_string(map_image, angle_to_gl)
vertex_switch_data = gen_vertex_map_switch_string(map_vertex) vertex_switch_data = gen_vertex_map_switch_string(map_vertex)
......
...@@ -4,26 +4,56 @@ ...@@ -4,26 +4,56 @@
"NONE": "MTLPixelFormatInvalid", "NONE": "MTLPixelFormatInvalid",
"A8_UNORM": "MTLPixelFormatA8Unorm", "A8_UNORM": "MTLPixelFormatA8Unorm",
"R8_UNORM": "MTLPixelFormatR8Unorm", "R8_UNORM": "MTLPixelFormatR8Unorm",
"R8_SNORM": "MTLPixelFormatR8Snorm",
"R8_UINT": "MTLPixelFormatR8Uint",
"R8_SINT": "MTLPixelFormatR8Sint",
"R8G8_UNORM": "MTLPixelFormatRG8Unorm", "R8G8_UNORM": "MTLPixelFormatRG8Unorm",
"R8G8_SNORM": "MTLPixelFormatRG8Snorm",
"R8G8_UINT": "MTLPixelFormatRG8Uint",
"R8G8_SINT": "MTLPixelFormatRG8Sint",
"R8G8B8A8_UINT": "MTLPixelFormatRGBA8Uint",
"R8G8B8A8_SINT": "MTLPixelFormatRGBA8Sint",
"R8G8B8A8_UNORM": "MTLPixelFormatRGBA8Unorm",
"R8G8B8A8_SNORM": "MTLPixelFormatRGBA8Snorm",
"R8G8B8A8_UNORM_SRGB": "MTLPixelFormatRGBA8Unorm_sRGB",
"B8G8R8A8_UNORM": "MTLPixelFormatBGRA8Unorm",
"B8G8R8A8_UNORM_SRGB": "MTLPixelFormatBGRA8Unorm_sRGB",
"R16_UNORM": "MTLPixelFormatR16Unorm", "R16_UNORM": "MTLPixelFormatR16Unorm",
"R16_SNORM": "MTLPixelFormatR16Snorm",
"R16_UINT": "MTLPixelFormatR16Uint",
"R16_SINT": "MTLPixelFormatR16Sint",
"R16_FLOAT": "MTLPixelFormatR16Float", "R16_FLOAT": "MTLPixelFormatR16Float",
"R16G16_UNORM": "MTLPixelFormatRG16Unorm",
"R16G16_SNORM": "MTLPixelFormatRG16Snorm",
"R16G16_UINT": "MTLPixelFormatRG16Uint",
"R16G16_SINT": "MTLPixelFormatRG16Sint",
"R16G16_FLOAT": "MTLPixelFormatRG16Float", "R16G16_FLOAT": "MTLPixelFormatRG16Float",
"R16G16B16A16_UNORM": "MTLPixelFormatRGBA16Unorm",
"R16G16B16A16_SNORM": "MTLPixelFormatRGBA16Snorm",
"R16G16B16A16_UINT": "MTLPixelFormatRGBA16Uint",
"R16G16B16A16_SINT": "MTLPixelFormatRGBA16Sint",
"R16G16B16A16_FLOAT": "MTLPixelFormatRGBA16Float", "R16G16B16A16_FLOAT": "MTLPixelFormatRGBA16Float",
"R32_UINT": "MTLPixelFormatR32Uint",
"R32_SINT": "MTLPixelFormatR32Sint",
"R32_FLOAT": "MTLPixelFormatR32Float", "R32_FLOAT": "MTLPixelFormatR32Float",
"R32G32_UINT": "MTLPixelFormatRG32Uint",
"R32G32_SINT": "MTLPixelFormatRG32Sint",
"R32G32_FLOAT": "MTLPixelFormatRG32Float", "R32G32_FLOAT": "MTLPixelFormatRG32Float",
"R32G32B32A32_UINT": "MTLPixelFormatRGBA32Uint",
"R32G32B32A32_SINT": "MTLPixelFormatRGBA32Sint",
"R32G32B32A32_FLOAT": "MTLPixelFormatRGBA32Float", "R32G32B32A32_FLOAT": "MTLPixelFormatRGBA32Float",
"R8G8B8A8_UNORM": "MTLPixelFormatRGBA8Unorm",
"R8G8B8A8_UNORM_SRGB": "MTLPixelFormatRGBA8Unorm_sRGB",
"B8G8R8A8_UNORM": "MTLPixelFormatBGRA8Unorm",
"B8G8R8A8_UNORM_SRGB": "MTLPixelFormatBGRA8Unorm_sRGB",
"D32_FLOAT": "MTLPixelFormatDepth32Float", "D32_FLOAT": "MTLPixelFormatDepth32Float",
"S8_UINT": "MTLPixelFormatStencil8", "S8_UINT": "MTLPixelFormatStencil8",
"D32_FLOAT_S8X24_UINT": "MTLPixelFormatDepth32Float_Stencil8", "D32_FLOAT_S8X24_UINT": "MTLPixelFormatDepth32Float_Stencil8",
"B10G10R10A2_UNORM": "MTLPixelFormatBGR10A2Unorm" "B10G10R10A2_UNORM": "MTLPixelFormatBGR10A2Unorm",
"R10G10B10A2_UINT": "MTLPixelFormatRGB10A2Uint",
"R10G10B10A2_UNORM": "MTLPixelFormatRGB10A2Unorm",
"R11G11B10_FLOAT": "MTLPixelFormatRG11B10Float",
"R9G9B9E5_SHAREDEXP": "MTLPixelFormatRGB9E5Float"
}, },
"map_ios": { "map_ios": {
"R5G6B5_UNORM": "MTLPixelFormatB5G6R5Unorm", "R5G6B5_UNORM": "MTLPixelFormatB5G6R5Unorm",
"R5G5B5A1_UNORM": "MTLPixelFormatBGR5A1Unorm", "R5G5B5A1_UNORM": "MTLPixelFormatA1BGR5Unorm",
"R4G4B4A4_UNORM": "MTLPixelFormatABGR4Unorm", "R4G4B4A4_UNORM": "MTLPixelFormatABGR4Unorm",
"PVRTC1_RGB_4BPP_UNORM_BLOCK": "MTLPixelFormatPVRTC_RGB_4BPP", "PVRTC1_RGB_4BPP_UNORM_BLOCK": "MTLPixelFormatPVRTC_RGB_4BPP",
"PVRTC1_RGB_2BPP_UNORM_BLOCK": "MTLPixelFormatPVRTC_RGB_2BPP", "PVRTC1_RGB_2BPP_UNORM_BLOCK": "MTLPixelFormatPVRTC_RGB_2BPP",
...@@ -33,7 +63,6 @@ ...@@ -33,7 +63,6 @@
"PVRTC1_RGB_4BPP_UNORM_SRGB_BLOCK": "MTLPixelFormatPVRTC_RGB_4BPP_sRGB", "PVRTC1_RGB_4BPP_UNORM_SRGB_BLOCK": "MTLPixelFormatPVRTC_RGB_4BPP_sRGB",
"PVRTC1_RGBA_2BPP_UNORM_SRGB_BLOCK": "MTLPixelFormatPVRTC_RGBA_2BPP_sRGB", "PVRTC1_RGBA_2BPP_UNORM_SRGB_BLOCK": "MTLPixelFormatPVRTC_RGBA_2BPP_sRGB",
"PVRTC1_RGBA_4BPP_UNORM_SRGB_BLOCK": "MTLPixelFormatPVRTC_RGBA_4BPP_sRGB", "PVRTC1_RGBA_4BPP_UNORM_SRGB_BLOCK": "MTLPixelFormatPVRTC_RGBA_4BPP_sRGB",
"ETC1_R8G8B8_UNORM_BLOCK": "MTLPixelFormatETC2_RGB8",
"ETC2_R8G8B8_UNORM_BLOCK": "MTLPixelFormatETC2_RGB8", "ETC2_R8G8B8_UNORM_BLOCK": "MTLPixelFormatETC2_RGB8",
"ETC2_R8G8B8_SRGB_BLOCK": "MTLPixelFormatETC2_RGB8_sRGB", "ETC2_R8G8B8_SRGB_BLOCK": "MTLPixelFormatETC2_RGB8_sRGB",
"ETC2_R8G8B8A1_UNORM_BLOCK": "MTLPixelFormatETC2_RGB8A1", "ETC2_R8G8B8A1_UNORM_BLOCK": "MTLPixelFormatETC2_RGB8A1",
...@@ -42,14 +71,12 @@ ...@@ -42,14 +71,12 @@
"ETC2_R8G8B8A8_SRGB_BLOCK": "MTLPixelFormatEAC_RGBA8_sRGB", "ETC2_R8G8B8A8_SRGB_BLOCK": "MTLPixelFormatEAC_RGBA8_sRGB",
"EAC_R11_UNORM_BLOCK": "MTLPixelFormatEAC_R11Unorm", "EAC_R11_UNORM_BLOCK": "MTLPixelFormatEAC_R11Unorm",
"EAC_R11_SNORM_BLOCK": "MTLPixelFormatEAC_R11Snorm", "EAC_R11_SNORM_BLOCK": "MTLPixelFormatEAC_R11Snorm",
"EAC_R11G11_UNORM_BLOCK": "MTLPixelFormatEAC_R11Unorm", "EAC_R11G11_UNORM_BLOCK": "MTLPixelFormatEAC_RG11Unorm",
"EAC_R11G11_SNORM_BLOCK": "MTLPixelFormatEAC_RG11Snorm" "EAC_R11G11_SNORM_BLOCK": "MTLPixelFormatEAC_RG11Snorm"
}, },
"map_mac": { "map_mac": {
"D16_UNORM": "MTLPixelFormatDepth16Unorm", "D16_UNORM": "MTLPixelFormatDepth16Unorm",
"D24_UNORM_S8_UINT": "MTLPixelFormatDepth24Unorm_Stencil8", "D24_UNORM_S8_UINT": "MTLPixelFormatDepth24Unorm_Stencil8",
"BC1_RGB_UNORM_BLOCK": "MTLPixelFormatBC1_RGBA",
"BC1_RGB_UNORM_SRGB_BLOCK": "MTLPixelFormatBC1_RGBA_sRGB",
"BC1_RGBA_UNORM_BLOCK": "MTLPixelFormatBC1_RGBA", "BC1_RGBA_UNORM_BLOCK": "MTLPixelFormatBC1_RGBA",
"BC1_RGBA_UNORM_SRGB_BLOCK": "MTLPixelFormatBC1_RGBA_sRGB", "BC1_RGBA_UNORM_SRGB_BLOCK": "MTLPixelFormatBC1_RGBA_sRGB",
"BC2_RGBA_UNORM_BLOCK": "MTLPixelFormatBC2_RGBA", "BC2_RGBA_UNORM_BLOCK": "MTLPixelFormatBC2_RGBA",
...@@ -65,9 +92,18 @@ ...@@ -65,9 +92,18 @@
"L8_UNORM": "R8G8B8A8_UNORM", "L8_UNORM": "R8G8B8A8_UNORM",
"L8A8_UNORM": "R8G8B8A8_UNORM", "L8A8_UNORM": "R8G8B8A8_UNORM",
"R8G8B8_UNORM": "R8G8B8A8_UNORM", "R8G8B8_UNORM": "R8G8B8A8_UNORM",
"R8G8B8_SNORM": "R8G8B8A8_SNORM",
"R8G8B8_UINT": "R8G8B8A8_UINT",
"R8G8B8_SINT": "R8G8B8A8_SINT",
"R8G8B8_UNORM_SRGB": "R8G8B8A8_UNORM_SRGB", "R8G8B8_UNORM_SRGB": "R8G8B8A8_UNORM_SRGB",
"R32G32B32_FLOAT": "R32G32B32A32_FLOAT", "R32G32B32_FLOAT": "R32G32B32A32_FLOAT",
"R32G32B32_UINT": "R32G32B32A32_UINT",
"R32G32B32_SINT": "R32G32B32A32_SINT",
"R16G16B16_FLOAT": "R16G16B16A16_FLOAT", "R16G16B16_FLOAT": "R16G16B16A16_FLOAT",
"R16G16B16_UINT": "R16G16B16A16_UINT",
"R16G16B16_SINT": "R16G16B16A16_SINT",
"R16G16B16_UNORM": "R16G16B16A16_UNORM",
"R16G16B16_SNORM": "R16G16B16A16_SNORM",
"A16_FLOAT": "R16G16B16A16_FLOAT", "A16_FLOAT": "R16G16B16A16_FLOAT",
"L16_FLOAT": "R16G16B16A16_FLOAT", "L16_FLOAT": "R16G16B16A16_FLOAT",
"L16A16_FLOAT": "R16G16B16A16_FLOAT", "L16A16_FLOAT": "R16G16B16A16_FLOAT",
...@@ -79,12 +115,32 @@ ...@@ -79,12 +115,32 @@
}, },
"override_ios": { "override_ios": {
"D24_UNORM_S8_UINT": "D32_FLOAT_S8X24_UINT", "D24_UNORM_S8_UINT": "D32_FLOAT_S8X24_UINT",
"D16_UNORM": "D32_FLOAT" "D16_UNORM": "D32_FLOAT",
"ETC1_R8G8B8_UNORM_BLOCK": "ETC2_R8G8B8_UNORM_BLOCK"
}, },
"override_mac": { "override_mac": {
"R5G6B5_UNORM": "R8G8B8A8_UNORM", "R5G6B5_UNORM": "R8G8B8A8_UNORM",
"R5G5B5A1_UNORM": "R8G8B8A8_UNORM", "R5G5B5A1_UNORM": "R8G8B8A8_UNORM",
"R4G4B4A4_UNORM": "R8G8B8A8_UNORM" "R4G4B4A4_UNORM": "R8G8B8A8_UNORM",
"BC1_RGB_UNORM_BLOCK": {
"default": "NONE",
"swizzle": ["RGB1", "BC1_RGBA_UNORM_BLOCK"]
},
"BC1_RGB_UNORM_SRGB_BLOCK": {
"default": "NONE",
"swizzle": ["RGB1", "BC1_RGBA_UNORM_SRGB_BLOCK"]
},
"ETC1_R8G8B8_UNORM_BLOCK": "R8G8B8A8_UNORM",
"ETC2_R8G8B8_UNORM_BLOCK": "R8G8B8A8_UNORM",
"ETC2_R8G8B8_SRGB_BLOCK": "R8G8B8A8_UNORM_SRGB",
"ETC2_R8G8B8A1_UNORM_BLOCK": "R8G8B8A8_UNORM",
"ETC2_R8G8B8A1_SRGB_BLOCK": "R8G8B8A8_UNORM_SRGB",
"ETC2_R8G8B8A8_UNORM_BLOCK": "R8G8B8A8_UNORM",
"ETC2_R8G8B8A8_SRGB_BLOCK": "R8G8B8A8_UNORM_SRGB",
"EAC_R11_UNORM_BLOCK": "R16_UNORM",
"EAC_R11_SNORM_BLOCK": "R16_SNORM",
"EAC_R11G11_UNORM_BLOCK": "R16G16_UNORM",
"EAC_R11G11_SNORM_BLOCK": "R16G16_SNORM"
}, },
"d24s8_fallbacks_mac": { "d24s8_fallbacks_mac": {
"D24_UNORM_S8_UINT": "D32_FLOAT_S8X24_UINT" "D24_UNORM_S8_UINT": "D32_FLOAT_S8X24_UINT"
...@@ -143,48 +199,87 @@ ...@@ -143,48 +199,87 @@
"R16G16B16A16_USCALED": "MTLVertexFormatUShort4", "R16G16B16A16_USCALED": "MTLVertexFormatUShort4",
"R16G16B16A16_SSCALED": "MTLVertexFormatShort4", "R16G16B16A16_SSCALED": "MTLVertexFormatShort4",
"R32_UINT": "MTLVertexFormatUInt",
"R32_SINT": "MTLVertexFormatInt",
"R32G32_UINT": "MTLVertexFormatUInt2",
"R32G32_SINT": "MTLVertexFormatInt2",
"R32G32B32_UINT": "MTLVertexFormatUInt3",
"R32G32B32_SINT": "MTLVertexFormatInt3",
"R32G32B32A32_UINT": "MTLVertexFormatUInt4",
"R32G32B32A32_SINT": "MTLVertexFormatInt4",
"R16_FLOAT": "MTLVertexFormatHalf",
"R16G16_FLOAT": "MTLVertexFormatHalf2",
"R16G16B16_FLOAT": "MTLVertexFormatHalf3",
"R16G16B16A16_FLOAT": "MTLVertexFormatHalf4",
"R32_FLOAT": "MTLVertexFormatFloat", "R32_FLOAT": "MTLVertexFormatFloat",
"R32G32_FLOAT": "MTLVertexFormatFloat2", "R32G32_FLOAT": "MTLVertexFormatFloat2",
"R32G32B32_FLOAT": "MTLVertexFormatFloat3", "R32G32B32_FLOAT": "MTLVertexFormatFloat3",
"R32G32B32A32_FLOAT": "MTLVertexFormatFloat4" "R32G32B32A32_FLOAT": "MTLVertexFormatFloat4",
"R10G10B10A2_SNORM" : "MTLVertexFormatInt1010102Normalized",
"R10G10B10A2_UNORM" : "MTLVertexFormatUInt1010102Normalized"
}, },
"override": { "override": {
"R32_FIXED": "R32_FLOAT", "R32_FIXED": "R32_FLOAT",
"R32_UNORM": "R32_FLOAT",
"R32_SNORM": "R32_FLOAT",
"R32_USCALED": "R32_FLOAT",
"R32_SSCALED": "R32_FLOAT",
"R32G32_FIXED": "R32G32_FLOAT", "R32G32_FIXED": "R32G32_FLOAT",
"R32G32_UNORM": "R32G32_FLOAT",
"R32G32_SNORM": "R32G32_FLOAT",
"R32G32_USCALED": "R32G32_FLOAT",
"R32G32_SSCALED": "R32G32_FLOAT",
"R32G32B32_FIXED": "R32G32B32_FLOAT", "R32G32B32_FIXED": "R32G32B32_FLOAT",
"R32G32B32A32_FIXED": "R32G32B32A32_FLOAT" "R32G32B32_UNORM": "R32G32B32_FLOAT",
"R32G32B32_SNORM": "R32G32B32_FLOAT",
"R32G32B32_USCALED": "R32G32B32_FLOAT",
"R32G32B32_SSCALED": "R32G32B32_FLOAT",
"R32G32B32A32_FIXED": "R32G32B32A32_FLOAT",
"R32G32B32A32_UNORM": "R32G32B32A32_FLOAT",
"R32G32B32A32_SNORM": "R32G32B32A32_FLOAT",
"R32G32B32A32_USCALED": "R32G32B32A32_FLOAT",
"R32G32B32A32_SSCALED": "R32G32B32A32_FLOAT",
"R10G10B10A2_SINT": "R32G32B32A32_FLOAT",
"R10G10B10A2_SSCALED": "R32G32B32A32_FLOAT",
"R10G10B10A2_UINT": "R32G32B32A32_FLOAT",
"R10G10B10A2_USCALED": "R32G32B32A32_FLOAT"
}, },
"override_tightly_packed": { "override_tightly_packed": {
"R16_UNORM": "R32_FLOAT", "R16_FLOAT": "R16G16_FLOAT",
"R16_SNORM": "R32_FLOAT", "R16_UNORM": "R16G16_UNORM",
"R16_UINT": "R32_FLOAT", "R16_SNORM": "R16G16_SNORM",
"R16_SINT": "R32_FLOAT", "R16_UINT": "R16G16_UINT",
"R16_USCALED": "R32_FLOAT", "R16_SINT": "R16G16_SINT",
"R16_SSCALED": "R32_FLOAT", "R16_USCALED": "R16G16_UINT",
"R16G16B16_UNORM": "R32G32B32_FLOAT", "R16_SSCALED": "R16G16_SINT",
"R16G16B16_SNORM": "R32G32B32_FLOAT", "R16G16B16_FLOAT": "R16G16B16A16_FLOAT",
"R16G16B16_UINT": "R32G32B32_FLOAT", "R16G16B16_UNORM": "R16G16B16A16_UNORM",
"R16G16B16_SINT": "R32G32B32_FLOAT", "R16G16B16_SNORM": "R16G16B16A16_SNORM",
"R16G16B16_USCALED": "R32G32B32_FLOAT", "R16G16B16_UINT": "R16G16B16A16_UINT",
"R16G16B16_SSCALED": "R32G32B32_FLOAT", "R16G16B16_SINT": "R16G16B16A16_SINT",
"R8_UNORM": "R32_FLOAT", "R16G16B16_USCALED": "R16G16B16A16_UINT",
"R8_SNORM": "R32_FLOAT", "R16G16B16_SSCALED": "R16G16B16A16_SINT",
"R8_UINT": "R32_FLOAT", "R8_UNORM": "R8G8B8A8_UNORM",
"R8_SINT": "R32_FLOAT", "R8_SNORM": "R8G8B8A8_SNORM",
"R8_USCALED": "R32_FLOAT", "R8_UINT": "R8G8B8A8_UINT",
"R8_SSCALED": "R32_FLOAT", "R8_SINT": "R8G8B8A8_SINT",
"R8G8_UNORM": "R32G32_FLOAT", "R8_USCALED": "R8G8B8A8_UINT",
"R8G8_SNORM": "R32G32_FLOAT", "R8_SSCALED": "R8G8B8A8_SINT",
"R8G8_UINT": "R32G32_FLOAT", "R8G8_UNORM": "R8G8B8A8_UNORM",
"R8G8_SINT": "R32G32_FLOAT", "R8G8_SNORM": "R8G8B8A8_SNORM",
"R8G8_USCALED": "R32G32_FLOAT", "R8G8_UINT": "R8G8B8A8_UINT",
"R8G8_SSCALED": "R32G32_FLOAT", "R8G8_SINT": "R8G8B8A8_SINT",
"R8G8B8_UNORM": "R32G32B32_FLOAT", "R8G8_USCALED": "R8G8B8A8_UINT",
"R8G8B8_SNORM": "R32G32B32_FLOAT", "R8G8_SSCALED": "R8G8B8A8_SINT",
"R8G8B8_UINT": "R32G32B32_FLOAT", "R8G8B8_UNORM": "R8G8B8A8_UNORM",
"R8G8B8_SINT": "R32G32B32_FLOAT", "R8G8B8_SNORM": "R8G8B8A8_SNORM",
"R8G8B8_USCALED": "R32G32B32_FLOAT", "R8G8B8_UINT": "R8G8B8A8_UINT",
"R8G8B8_SSCALED": "R32G32B32_FLOAT" "R8G8B8_SINT": "R8G8B8A8_SINT",
"R8G8B8_USCALED": "R8G8B8A8_UINT",
"R8G8B8_SSCALED": "R8G8B8A8_SINT"
} }
} }
} }
\ No newline at end of file
...@@ -11,10 +11,15 @@ ...@@ -11,10 +11,15 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
#include <TargetConditionals.h> #include <TargetConditionals.h>
#include "image_util/copyimage.h"
#include "image_util/generatemip.h"
#include "image_util/loadimage.h"
#include "libANGLE/renderer/Format.h" #include "libANGLE/renderer/Format.h"
#include "libANGLE/renderer/metal/DisplayMtl.h" #include "libANGLE/renderer/metal/DisplayMtl.h"
#include "libANGLE/renderer/metal/mtl_format_utils.h" #include "libANGLE/renderer/metal/mtl_format_utils.h"
using namespace angle;
namespace rx namespace rx
{ {
namespace mtl namespace mtl
...@@ -30,383 +35,1166 @@ void Format::init(const DisplayMtl *display, angle::FormatID intendedFormatId_) ...@@ -30,383 +35,1166 @@ void Format::init(const DisplayMtl *display, angle::FormatID intendedFormatId_)
switch (this->intendedFormatId) switch (this->intendedFormatId)
{ {
case angle::FormatID::A8_UNORM: case angle::FormatID::A8_UNORM:
this->metalFormat = MTLPixelFormatA8Unorm; this->metalFormat = MTLPixelFormatA8Unorm;
this->actualFormatId = angle::FormatID::A8_UNORM; this->actualFormatId = angle::FormatID::A8_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::B10G10R10A2_UNORM: case angle::FormatID::B10G10R10A2_UNORM:
this->metalFormat = MTLPixelFormatBGR10A2Unorm; this->metalFormat = MTLPixelFormatBGR10A2Unorm;
this->actualFormatId = angle::FormatID::B10G10R10A2_UNORM; this->actualFormatId = angle::FormatID::B10G10R10A2_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::B8G8R8A8_UNORM: case angle::FormatID::B8G8R8A8_UNORM:
this->metalFormat = MTLPixelFormatBGRA8Unorm; this->metalFormat = MTLPixelFormatBGRA8Unorm;
this->actualFormatId = angle::FormatID::B8G8R8A8_UNORM; this->actualFormatId = angle::FormatID::B8G8R8A8_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::B8G8R8A8_UNORM_SRGB: case angle::FormatID::B8G8R8A8_UNORM_SRGB:
this->metalFormat = MTLPixelFormatBGRA8Unorm_sRGB; this->metalFormat = MTLPixelFormatBGRA8Unorm_sRGB;
this->actualFormatId = angle::FormatID::B8G8R8A8_UNORM_SRGB; this->actualFormatId = angle::FormatID::B8G8R8A8_UNORM_SRGB;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::D32_FLOAT: case angle::FormatID::D32_FLOAT:
this->metalFormat = MTLPixelFormatDepth32Float; this->metalFormat = MTLPixelFormatDepth32Float;
this->actualFormatId = angle::FormatID::D32_FLOAT; this->actualFormatId = angle::FormatID::D32_FLOAT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::D32_FLOAT_S8X24_UINT: case angle::FormatID::D32_FLOAT_S8X24_UINT:
this->metalFormat = MTLPixelFormatDepth32Float_Stencil8; this->metalFormat = MTLPixelFormatDepth32Float_Stencil8;
this->actualFormatId = angle::FormatID::D32_FLOAT_S8X24_UINT; this->actualFormatId = angle::FormatID::D32_FLOAT_S8X24_UINT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::NONE: case angle::FormatID::NONE:
this->metalFormat = MTLPixelFormatInvalid; this->metalFormat = MTLPixelFormatInvalid;
this->actualFormatId = angle::FormatID::NONE; this->actualFormatId = angle::FormatID::NONE;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R10G10B10A2_UINT:
this->metalFormat = MTLPixelFormatRGB10A2Uint;
this->actualFormatId = angle::FormatID::R10G10B10A2_UINT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R10G10B10A2_UNORM:
this->metalFormat = MTLPixelFormatRGB10A2Unorm;
this->actualFormatId = angle::FormatID::R10G10B10A2_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R11G11B10_FLOAT:
this->metalFormat = MTLPixelFormatRG11B10Float;
this->actualFormatId = angle::FormatID::R11G11B10_FLOAT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R16G16B16A16_FLOAT: case angle::FormatID::R16G16B16A16_FLOAT:
this->metalFormat = MTLPixelFormatRGBA16Float; this->metalFormat = MTLPixelFormatRGBA16Float;
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT; this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R16G16B16A16_SINT:
this->metalFormat = MTLPixelFormatRGBA16Sint;
this->actualFormatId = angle::FormatID::R16G16B16A16_SINT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R16G16B16A16_SNORM:
this->metalFormat = MTLPixelFormatRGBA16Snorm;
this->actualFormatId = angle::FormatID::R16G16B16A16_SNORM;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R16G16B16A16_UINT:
this->metalFormat = MTLPixelFormatRGBA16Uint;
this->actualFormatId = angle::FormatID::R16G16B16A16_UINT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R16G16B16A16_UNORM:
this->metalFormat = MTLPixelFormatRGBA16Unorm;
this->actualFormatId = angle::FormatID::R16G16B16A16_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R16G16_FLOAT: case angle::FormatID::R16G16_FLOAT:
this->metalFormat = MTLPixelFormatRG16Float; this->metalFormat = MTLPixelFormatRG16Float;
this->actualFormatId = angle::FormatID::R16G16_FLOAT; this->actualFormatId = angle::FormatID::R16G16_FLOAT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R16G16_SINT:
this->metalFormat = MTLPixelFormatRG16Sint;
this->actualFormatId = angle::FormatID::R16G16_SINT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R16G16_SNORM:
this->metalFormat = MTLPixelFormatRG16Snorm;
this->actualFormatId = angle::FormatID::R16G16_SNORM;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R16G16_UINT:
this->metalFormat = MTLPixelFormatRG16Uint;
this->actualFormatId = angle::FormatID::R16G16_UINT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R16G16_UNORM:
this->metalFormat = MTLPixelFormatRG16Unorm;
this->actualFormatId = angle::FormatID::R16G16_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R16_FLOAT: case angle::FormatID::R16_FLOAT:
this->metalFormat = MTLPixelFormatR16Float; this->metalFormat = MTLPixelFormatR16Float;
this->actualFormatId = angle::FormatID::R16_FLOAT; this->actualFormatId = angle::FormatID::R16_FLOAT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R16_SINT:
this->metalFormat = MTLPixelFormatR16Sint;
this->actualFormatId = angle::FormatID::R16_SINT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R16_SNORM:
this->metalFormat = MTLPixelFormatR16Snorm;
this->actualFormatId = angle::FormatID::R16_SNORM;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R16_UINT:
this->metalFormat = MTLPixelFormatR16Uint;
this->actualFormatId = angle::FormatID::R16_UINT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R16_UNORM: case angle::FormatID::R16_UNORM:
this->metalFormat = MTLPixelFormatR16Unorm; this->metalFormat = MTLPixelFormatR16Unorm;
this->actualFormatId = angle::FormatID::R16_UNORM; this->actualFormatId = angle::FormatID::R16_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R32G32B32A32_FLOAT: case angle::FormatID::R32G32B32A32_FLOAT:
this->metalFormat = MTLPixelFormatRGBA32Float; this->metalFormat = MTLPixelFormatRGBA32Float;
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT; this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R32G32B32A32_SINT:
this->metalFormat = MTLPixelFormatRGBA32Sint;
this->actualFormatId = angle::FormatID::R32G32B32A32_SINT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R32G32B32A32_UINT:
this->metalFormat = MTLPixelFormatRGBA32Uint;
this->actualFormatId = angle::FormatID::R32G32B32A32_UINT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R32G32_FLOAT: case angle::FormatID::R32G32_FLOAT:
this->metalFormat = MTLPixelFormatRG32Float; this->metalFormat = MTLPixelFormatRG32Float;
this->actualFormatId = angle::FormatID::R32G32_FLOAT; this->actualFormatId = angle::FormatID::R32G32_FLOAT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R32G32_SINT:
this->metalFormat = MTLPixelFormatRG32Sint;
this->actualFormatId = angle::FormatID::R32G32_SINT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R32G32_UINT:
this->metalFormat = MTLPixelFormatRG32Uint;
this->actualFormatId = angle::FormatID::R32G32_UINT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R32_FLOAT: case angle::FormatID::R32_FLOAT:
this->metalFormat = MTLPixelFormatR32Float; this->metalFormat = MTLPixelFormatR32Float;
this->actualFormatId = angle::FormatID::R32_FLOAT; this->actualFormatId = angle::FormatID::R32_FLOAT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R32_SINT:
this->metalFormat = MTLPixelFormatR32Sint;
this->actualFormatId = angle::FormatID::R32_SINT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R32_UINT:
this->metalFormat = MTLPixelFormatR32Uint;
this->actualFormatId = angle::FormatID::R32_UINT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R8G8B8A8_SINT:
this->metalFormat = MTLPixelFormatRGBA8Sint;
this->actualFormatId = angle::FormatID::R8G8B8A8_SINT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R8G8B8A8_SNORM:
this->metalFormat = MTLPixelFormatRGBA8Snorm;
this->actualFormatId = angle::FormatID::R8G8B8A8_SNORM;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R8G8B8A8_UINT:
this->metalFormat = MTLPixelFormatRGBA8Uint;
this->actualFormatId = angle::FormatID::R8G8B8A8_UINT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R8G8B8A8_UNORM: case angle::FormatID::R8G8B8A8_UNORM:
this->metalFormat = MTLPixelFormatRGBA8Unorm; this->metalFormat = MTLPixelFormatRGBA8Unorm;
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R8G8B8A8_UNORM_SRGB: case angle::FormatID::R8G8B8A8_UNORM_SRGB:
this->metalFormat = MTLPixelFormatRGBA8Unorm_sRGB; this->metalFormat = MTLPixelFormatRGBA8Unorm_sRGB;
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM_SRGB; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM_SRGB;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R8G8_SINT:
this->metalFormat = MTLPixelFormatRG8Sint;
this->actualFormatId = angle::FormatID::R8G8_SINT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R8G8_SNORM:
this->metalFormat = MTLPixelFormatRG8Snorm;
this->actualFormatId = angle::FormatID::R8G8_SNORM;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R8G8_UINT:
this->metalFormat = MTLPixelFormatRG8Uint;
this->actualFormatId = angle::FormatID::R8G8_UINT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R8G8_UNORM: case angle::FormatID::R8G8_UNORM:
this->metalFormat = MTLPixelFormatRG8Unorm; this->metalFormat = MTLPixelFormatRG8Unorm;
this->actualFormatId = angle::FormatID::R8G8_UNORM; this->actualFormatId = angle::FormatID::R8G8_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R8_SINT:
this->metalFormat = MTLPixelFormatR8Sint;
this->actualFormatId = angle::FormatID::R8_SINT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R8_SNORM:
this->metalFormat = MTLPixelFormatR8Snorm;
this->actualFormatId = angle::FormatID::R8_SNORM;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R8_UINT:
this->metalFormat = MTLPixelFormatR8Uint;
this->actualFormatId = angle::FormatID::R8_UINT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R8_UNORM: case angle::FormatID::R8_UNORM:
this->metalFormat = MTLPixelFormatR8Unorm; this->metalFormat = MTLPixelFormatR8Unorm;
this->actualFormatId = angle::FormatID::R8_UNORM; this->actualFormatId = angle::FormatID::R8_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::R9G9B9E5_SHAREDEXP:
this->metalFormat = MTLPixelFormatRGB9E5Float;
this->actualFormatId = angle::FormatID::R9G9B9E5_SHAREDEXP;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::S8_UINT: case angle::FormatID::S8_UINT:
this->metalFormat = MTLPixelFormatStencil8; this->metalFormat = MTLPixelFormatStencil8;
this->actualFormatId = angle::FormatID::S8_UINT; this->actualFormatId = angle::FormatID::S8_UINT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::A16_FLOAT: case angle::FormatID::A16_FLOAT:
this->metalFormat = MTLPixelFormatRGBA16Float; this->metalFormat = MTLPixelFormatRGBA16Float;
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT; this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::A32_FLOAT: case angle::FormatID::A32_FLOAT:
this->metalFormat = MTLPixelFormatRGBA32Float; this->metalFormat = MTLPixelFormatRGBA32Float;
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT; this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::D24_UNORM_X8_UINT: case angle::FormatID::D24_UNORM_X8_UINT:
this->metalFormat = MTLPixelFormatDepth32Float; this->metalFormat = MTLPixelFormatDepth32Float;
this->actualFormatId = angle::FormatID::D32_FLOAT; this->actualFormatId = angle::FormatID::D32_FLOAT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::D32_UNORM: case angle::FormatID::D32_UNORM:
this->metalFormat = MTLPixelFormatDepth32Float; this->metalFormat = MTLPixelFormatDepth32Float;
this->actualFormatId = angle::FormatID::D32_FLOAT; this->actualFormatId = angle::FormatID::D32_FLOAT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::L16A16_FLOAT: case angle::FormatID::L16A16_FLOAT:
this->metalFormat = MTLPixelFormatRGBA16Float; this->metalFormat = MTLPixelFormatRGBA16Float;
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT; this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::L16_FLOAT: case angle::FormatID::L16_FLOAT:
this->metalFormat = MTLPixelFormatRGBA16Float; this->metalFormat = MTLPixelFormatRGBA16Float;
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT; this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
this->initFunction =
Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>;
this->swizzled = false;
break; break;
case angle::FormatID::L32A32_FLOAT: case angle::FormatID::L32A32_FLOAT:
this->metalFormat = MTLPixelFormatRGBA32Float; this->metalFormat = MTLPixelFormatRGBA32Float;
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT; this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::L32_FLOAT: case angle::FormatID::L32_FLOAT:
this->metalFormat = MTLPixelFormatRGBA32Float; this->metalFormat = MTLPixelFormatRGBA32Float;
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT; this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
this->initFunction = Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000,
0x00000000, gl::Float32One>;
this->swizzled = false;
break; break;
case angle::FormatID::L8A8_UNORM: case angle::FormatID::L8A8_UNORM:
this->metalFormat = MTLPixelFormatRGBA8Unorm; this->metalFormat = MTLPixelFormatRGBA8Unorm;
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::L8_UNORM: case angle::FormatID::L8_UNORM:
this->metalFormat = MTLPixelFormatRGBA8Unorm; this->metalFormat = MTLPixelFormatRGBA8Unorm;
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
this->initFunction = Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
this->swizzled = false;
break; break;
case angle::FormatID::R16G16B16_FLOAT: case angle::FormatID::R16G16B16_FLOAT:
this->metalFormat = MTLPixelFormatRGBA16Float; this->metalFormat = MTLPixelFormatRGBA16Float;
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT; this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
this->initFunction =
Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>;
this->swizzled = false;
break;
case angle::FormatID::R16G16B16_SINT:
this->metalFormat = MTLPixelFormatRGBA16Sint;
this->actualFormatId = angle::FormatID::R16G16B16A16_SINT;
this->initFunction = Initialize4ComponentData<GLshort, 0x0000, 0x0000, 0x0000, 0x0001>;
this->swizzled = false;
break;
case angle::FormatID::R16G16B16_SNORM:
this->metalFormat = MTLPixelFormatRGBA16Snorm;
this->actualFormatId = angle::FormatID::R16G16B16A16_SNORM;
this->initFunction = Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x7FFF>;
this->swizzled = false;
break;
case angle::FormatID::R16G16B16_UINT:
this->metalFormat = MTLPixelFormatRGBA16Uint;
this->actualFormatId = angle::FormatID::R16G16B16A16_UINT;
this->initFunction = Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x0001>;
this->swizzled = false;
break;
case angle::FormatID::R16G16B16_UNORM:
this->metalFormat = MTLPixelFormatRGBA16Unorm;
this->actualFormatId = angle::FormatID::R16G16B16A16_UNORM;
this->initFunction = Initialize4ComponentData<GLubyte, 0x0000, 0x0000, 0x0000, 0xFFFF>;
this->swizzled = false;
break; break;
case angle::FormatID::R32G32B32_FLOAT: case angle::FormatID::R32G32B32_FLOAT:
this->metalFormat = MTLPixelFormatRGBA32Float; this->metalFormat = MTLPixelFormatRGBA32Float;
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT; this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
this->initFunction = Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000,
0x00000000, gl::Float32One>;
this->swizzled = false;
break;
case angle::FormatID::R32G32B32_SINT:
this->metalFormat = MTLPixelFormatRGBA32Sint;
this->actualFormatId = angle::FormatID::R32G32B32A32_SINT;
this->initFunction =
Initialize4ComponentData<GLint, 0x00000000, 0x00000000, 0x00000000, 0x00000001>;
this->swizzled = false;
break;
case angle::FormatID::R32G32B32_UINT:
this->metalFormat = MTLPixelFormatRGBA32Uint;
this->actualFormatId = angle::FormatID::R32G32B32A32_UINT;
this->initFunction =
Initialize4ComponentData<GLuint, 0x00000000, 0x00000000, 0x00000000, 0x00000001>;
this->swizzled = false;
break;
case angle::FormatID::R8G8B8_SINT:
this->metalFormat = MTLPixelFormatRGBA8Sint;
this->actualFormatId = angle::FormatID::R8G8B8A8_SINT;
this->initFunction = Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x01>;
this->swizzled = false;
break;
case angle::FormatID::R8G8B8_SNORM:
this->metalFormat = MTLPixelFormatRGBA8Snorm;
this->actualFormatId = angle::FormatID::R8G8B8A8_SNORM;
this->initFunction = Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x7F>;
this->swizzled = false;
break;
case angle::FormatID::R8G8B8_UINT:
this->metalFormat = MTLPixelFormatRGBA8Uint;
this->actualFormatId = angle::FormatID::R8G8B8A8_UINT;
this->initFunction = Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0x01>;
this->swizzled = false;
break; break;
case angle::FormatID::R8G8B8_UNORM: case angle::FormatID::R8G8B8_UNORM:
this->metalFormat = MTLPixelFormatRGBA8Unorm; this->metalFormat = MTLPixelFormatRGBA8Unorm;
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
this->initFunction = Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
this->swizzled = false;
break; break;
case angle::FormatID::R8G8B8_UNORM_SRGB: case angle::FormatID::R8G8B8_UNORM_SRGB:
this->metalFormat = MTLPixelFormatRGBA8Unorm_sRGB; this->metalFormat = MTLPixelFormatRGBA8Unorm_sRGB;
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM_SRGB; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM_SRGB;
this->initFunction = Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
this->swizzled = false;
break; break;
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST #if TARGET_OS_OSX || TARGET_OS_MACCATALYST
case angle::FormatID::BC1_RGBA_UNORM_BLOCK: case angle::FormatID::BC1_RGBA_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatBC1_RGBA; this->metalFormat = MTLPixelFormatBC1_RGBA;
this->actualFormatId = angle::FormatID::BC1_RGBA_UNORM_BLOCK; this->actualFormatId = angle::FormatID::BC1_RGBA_UNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK:
this->metalFormat = MTLPixelFormatBC1_RGBA_sRGB;
this->actualFormatId = angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::BC2_RGBA_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatBC2_RGBA;
this->actualFormatId = angle::FormatID::BC2_RGBA_UNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK:
this->metalFormat = MTLPixelFormatBC2_RGBA_sRGB;
this->actualFormatId = angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK: case angle::FormatID::BC3_RGBA_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatBC1_RGBA_sRGB;
this->actualFormatId = angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK; this->metalFormat = MTLPixelFormatBC3_RGBA;
this->actualFormatId = angle::FormatID::BC3_RGBA_UNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK:
this->metalFormat = MTLPixelFormatBC3_RGBA_sRGB;
this->actualFormatId = angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::BC4_RED_SNORM_BLOCK:
this->metalFormat = MTLPixelFormatBC4_RSnorm;
this->actualFormatId = angle::FormatID::BC4_RED_SNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::BC4_RED_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatBC4_RUnorm;
this->actualFormatId = angle::FormatID::BC4_RED_UNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::BC5_RG_SNORM_BLOCK:
this->metalFormat = MTLPixelFormatBC5_RGSnorm;
this->actualFormatId = angle::FormatID::BC5_RG_SNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::BC5_RG_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatBC5_RGUnorm;
this->actualFormatId = angle::FormatID::BC5_RG_UNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::D16_UNORM:
this->metalFormat = MTLPixelFormatDepth16Unorm;
this->actualFormatId = angle::FormatID::D16_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::D24_UNORM_S8_UINT:
if (metalDevice.depth24Stencil8PixelFormatSupported)
{
this->metalFormat = MTLPixelFormatDepth24Unorm_Stencil8;
this->actualFormatId = angle::FormatID::D24_UNORM_S8_UINT;
this->initFunction = nullptr;
}
else
{
this->metalFormat = MTLPixelFormatDepth32Float_Stencil8;
this->actualFormatId = angle::FormatID::D32_FLOAT_S8X24_UINT;
this->initFunction = nullptr;
}
this->swizzled = false;
break;
case angle::FormatID::BC1_RGB_UNORM_BLOCK:
# if defined(__IPHONE_13_0) || defined(__MAC_10_15)
if (display->getFeatures().hasTextureSwizzle.enabled)
{
this->metalFormat = MTLPixelFormatBC1_RGBA;
this->actualFormatId = angle::FormatID::BC1_RGBA_UNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = true;
this->swizzle = {GL_RED, GL_GREEN, GL_BLUE, GL_ONE};
}
else
# endif // #if defined(__IPHONE_13_0) || defined(__MAC_10_15)
{
this->metalFormat = MTLPixelFormatInvalid;
this->actualFormatId = angle::FormatID::NONE;
this->initFunction = nullptr;
this->swizzled = false;
}
break;
case angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK:
# if defined(__IPHONE_13_0) || defined(__MAC_10_15)
if (display->getFeatures().hasTextureSwizzle.enabled)
{
this->metalFormat = MTLPixelFormatBC1_RGBA_sRGB;
this->actualFormatId = angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK;
this->initFunction = nullptr;
this->swizzled = true;
this->swizzle = {GL_RED, GL_GREEN, GL_BLUE, GL_ONE};
}
else
# endif // #if defined(__IPHONE_13_0) || defined(__MAC_10_15)
{
this->metalFormat = MTLPixelFormatInvalid;
this->actualFormatId = angle::FormatID::NONE;
this->initFunction = nullptr;
this->swizzled = false;
}
break;
case angle::FormatID::EAC_R11G11_SNORM_BLOCK:
this->metalFormat = MTLPixelFormatRG16Snorm;
this->actualFormatId = angle::FormatID::R16G16_SNORM;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::EAC_R11G11_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatRG16Unorm;
this->actualFormatId = angle::FormatID::R16G16_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::EAC_R11_SNORM_BLOCK:
this->metalFormat = MTLPixelFormatR16Snorm;
this->actualFormatId = angle::FormatID::R16_SNORM;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::EAC_R11_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatR16Unorm;
this->actualFormatId = angle::FormatID::R16_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::ETC1_R8G8B8_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatRGBA8Unorm;
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
this->initFunction = Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
this->swizzled = false;
break;
case angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK:
this->metalFormat = MTLPixelFormatRGBA8Unorm_sRGB;
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM_SRGB;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::BC1_RGB_UNORM_BLOCK: case angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatBC1_RGBA;
this->actualFormatId = angle::FormatID::BC1_RGB_UNORM_BLOCK;
break;
case angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK: this->metalFormat = MTLPixelFormatRGBA8Unorm;
this->metalFormat = MTLPixelFormatBC1_RGBA_sRGB; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
this->actualFormatId = angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK; this->initFunction = Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
break;
case angle::FormatID::BC2_RGBA_UNORM_BLOCK: this->swizzled = false;
this->metalFormat = MTLPixelFormatBC2_RGBA;
this->actualFormatId = angle::FormatID::BC2_RGBA_UNORM_BLOCK;
break; break;
case angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK: case angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK:
this->metalFormat = MTLPixelFormatBC2_RGBA_sRGB;
this->actualFormatId = angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK;
break;
case angle::FormatID::BC3_RGBA_UNORM_BLOCK: this->metalFormat = MTLPixelFormatRGBA8Unorm_sRGB;
this->metalFormat = MTLPixelFormatBC3_RGBA; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM_SRGB;
this->actualFormatId = angle::FormatID::BC3_RGBA_UNORM_BLOCK; this->initFunction = nullptr;
break;
case angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK: this->swizzled = false;
this->metalFormat = MTLPixelFormatBC3_RGBA_sRGB;
this->actualFormatId = angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK;
break; break;
case angle::FormatID::BC4_RED_SNORM_BLOCK: case angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatBC4_RSnorm;
this->actualFormatId = angle::FormatID::BC4_RED_SNORM_BLOCK;
break;
case angle::FormatID::BC4_RED_UNORM_BLOCK: this->metalFormat = MTLPixelFormatRGBA8Unorm;
this->metalFormat = MTLPixelFormatBC4_RUnorm; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
this->actualFormatId = angle::FormatID::BC4_RED_UNORM_BLOCK; this->initFunction = nullptr;
break;
case angle::FormatID::BC5_RG_SNORM_BLOCK: this->swizzled = false;
this->metalFormat = MTLPixelFormatBC5_RGSnorm;
this->actualFormatId = angle::FormatID::BC5_RG_SNORM_BLOCK;
break; break;
case angle::FormatID::BC5_RG_UNORM_BLOCK: case angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK:
this->metalFormat = MTLPixelFormatBC5_RGUnorm;
this->actualFormatId = angle::FormatID::BC5_RG_UNORM_BLOCK;
break;
case angle::FormatID::D16_UNORM: this->metalFormat = MTLPixelFormatRGBA8Unorm_sRGB;
this->metalFormat = MTLPixelFormatDepth16Unorm; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM_SRGB;
this->actualFormatId = angle::FormatID::D16_UNORM; this->initFunction = Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
this->swizzled = false;
break; break;
case angle::FormatID::D24_UNORM_S8_UINT: case angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK:
if (metalDevice.depth24Stencil8PixelFormatSupported)
{ this->metalFormat = MTLPixelFormatRGBA8Unorm;
this->metalFormat = MTLPixelFormatDepth24Unorm_Stencil8; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
this->actualFormatId = angle::FormatID::D24_UNORM_S8_UINT; this->initFunction = Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
}
else this->swizzled = false;
{
this->metalFormat = MTLPixelFormatDepth32Float_Stencil8;
this->actualFormatId = angle::FormatID::D32_FLOAT_S8X24_UINT;
}
break; break;
case angle::FormatID::R4G4B4A4_UNORM: case angle::FormatID::R4G4B4A4_UNORM:
this->metalFormat = MTLPixelFormatRGBA8Unorm; this->metalFormat = MTLPixelFormatRGBA8Unorm;
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R5G5B5A1_UNORM: case angle::FormatID::R5G5B5A1_UNORM:
this->metalFormat = MTLPixelFormatRGBA8Unorm; this->metalFormat = MTLPixelFormatRGBA8Unorm;
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R5G6B5_UNORM: case angle::FormatID::R5G6B5_UNORM:
this->metalFormat = MTLPixelFormatRGBA8Unorm; this->metalFormat = MTLPixelFormatRGBA8Unorm;
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
this->initFunction = Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
this->swizzled = false;
break; break;
#elif TARGET_OS_IOS // TARGET_OS_OSX || TARGET_OS_MACCATALYST #elif TARGET_OS_IOS || TARGET_OS_TV // TARGET_OS_OSX || TARGET_OS_MACCATALYST
case angle::FormatID::EAC_R11G11_SNORM_BLOCK: case angle::FormatID::EAC_R11G11_SNORM_BLOCK:
this->metalFormat = MTLPixelFormatEAC_RG11Snorm; this->metalFormat = MTLPixelFormatEAC_RG11Snorm;
this->actualFormatId = angle::FormatID::EAC_R11G11_SNORM_BLOCK; this->actualFormatId = angle::FormatID::EAC_R11G11_SNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::EAC_R11G11_UNORM_BLOCK: case angle::FormatID::EAC_R11G11_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatEAC_R11Unorm;
this->metalFormat = MTLPixelFormatEAC_RG11Unorm;
this->actualFormatId = angle::FormatID::EAC_R11G11_UNORM_BLOCK; this->actualFormatId = angle::FormatID::EAC_R11G11_UNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::EAC_R11_SNORM_BLOCK: case angle::FormatID::EAC_R11_SNORM_BLOCK:
this->metalFormat = MTLPixelFormatEAC_R11Snorm; this->metalFormat = MTLPixelFormatEAC_R11Snorm;
this->actualFormatId = angle::FormatID::EAC_R11_SNORM_BLOCK; this->actualFormatId = angle::FormatID::EAC_R11_SNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::EAC_R11_UNORM_BLOCK: case angle::FormatID::EAC_R11_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatEAC_R11Unorm; this->metalFormat = MTLPixelFormatEAC_R11Unorm;
this->actualFormatId = angle::FormatID::EAC_R11_UNORM_BLOCK; this->actualFormatId = angle::FormatID::EAC_R11_UNORM_BLOCK;
break; this->initFunction = nullptr;
case angle::FormatID::ETC1_R8G8B8_UNORM_BLOCK: this->swizzled = false;
this->metalFormat = MTLPixelFormatETC2_RGB8;
this->actualFormatId = angle::FormatID::ETC1_R8G8B8_UNORM_BLOCK;
break; break;
case angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK: case angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK:
this->metalFormat = MTLPixelFormatETC2_RGB8A1_sRGB; this->metalFormat = MTLPixelFormatETC2_RGB8A1_sRGB;
this->actualFormatId = angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK; this->actualFormatId = angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK: case angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatETC2_RGB8A1; this->metalFormat = MTLPixelFormatETC2_RGB8A1;
this->actualFormatId = angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK; this->actualFormatId = angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK;
this->initFunction = Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
this->swizzled = false;
break; break;
case angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK: case angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK:
this->metalFormat = MTLPixelFormatEAC_RGBA8_sRGB; this->metalFormat = MTLPixelFormatEAC_RGBA8_sRGB;
this->actualFormatId = angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK; this->actualFormatId = angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK: case angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatEAC_RGBA8; this->metalFormat = MTLPixelFormatEAC_RGBA8;
this->actualFormatId = angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK; this->actualFormatId = angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK: case angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK:
this->metalFormat = MTLPixelFormatETC2_RGB8_sRGB; this->metalFormat = MTLPixelFormatETC2_RGB8_sRGB;
this->actualFormatId = angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK; this->actualFormatId = angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK: case angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatETC2_RGB8; this->metalFormat = MTLPixelFormatETC2_RGB8;
this->actualFormatId = angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK; this->actualFormatId = angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::PVRTC1_RGBA_2BPP_UNORM_BLOCK: case angle::FormatID::PVRTC1_RGBA_2BPP_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatPVRTC_RGBA_2BPP; this->metalFormat = MTLPixelFormatPVRTC_RGBA_2BPP;
this->actualFormatId = angle::FormatID::PVRTC1_RGBA_2BPP_UNORM_BLOCK; this->actualFormatId = angle::FormatID::PVRTC1_RGBA_2BPP_UNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::PVRTC1_RGBA_2BPP_UNORM_SRGB_BLOCK: case angle::FormatID::PVRTC1_RGBA_2BPP_UNORM_SRGB_BLOCK:
this->metalFormat = MTLPixelFormatPVRTC_RGBA_2BPP_sRGB; this->metalFormat = MTLPixelFormatPVRTC_RGBA_2BPP_sRGB;
this->actualFormatId = angle::FormatID::PVRTC1_RGBA_2BPP_UNORM_SRGB_BLOCK; this->actualFormatId = angle::FormatID::PVRTC1_RGBA_2BPP_UNORM_SRGB_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::PVRTC1_RGBA_4BPP_UNORM_BLOCK: case angle::FormatID::PVRTC1_RGBA_4BPP_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatPVRTC_RGBA_4BPP; this->metalFormat = MTLPixelFormatPVRTC_RGBA_4BPP;
this->actualFormatId = angle::FormatID::PVRTC1_RGBA_4BPP_UNORM_BLOCK; this->actualFormatId = angle::FormatID::PVRTC1_RGBA_4BPP_UNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::PVRTC1_RGBA_4BPP_UNORM_SRGB_BLOCK: case angle::FormatID::PVRTC1_RGBA_4BPP_UNORM_SRGB_BLOCK:
this->metalFormat = MTLPixelFormatPVRTC_RGBA_4BPP_sRGB; this->metalFormat = MTLPixelFormatPVRTC_RGBA_4BPP_sRGB;
this->actualFormatId = angle::FormatID::PVRTC1_RGBA_4BPP_UNORM_SRGB_BLOCK; this->actualFormatId = angle::FormatID::PVRTC1_RGBA_4BPP_UNORM_SRGB_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::PVRTC1_RGB_2BPP_UNORM_BLOCK: case angle::FormatID::PVRTC1_RGB_2BPP_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatPVRTC_RGB_2BPP; this->metalFormat = MTLPixelFormatPVRTC_RGB_2BPP;
this->actualFormatId = angle::FormatID::PVRTC1_RGB_2BPP_UNORM_BLOCK; this->actualFormatId = angle::FormatID::PVRTC1_RGB_2BPP_UNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::PVRTC1_RGB_2BPP_UNORM_SRGB_BLOCK: case angle::FormatID::PVRTC1_RGB_2BPP_UNORM_SRGB_BLOCK:
this->metalFormat = MTLPixelFormatPVRTC_RGB_2BPP_sRGB; this->metalFormat = MTLPixelFormatPVRTC_RGB_2BPP_sRGB;
this->actualFormatId = angle::FormatID::PVRTC1_RGB_2BPP_UNORM_SRGB_BLOCK; this->actualFormatId = angle::FormatID::PVRTC1_RGB_2BPP_UNORM_SRGB_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::PVRTC1_RGB_4BPP_UNORM_BLOCK: case angle::FormatID::PVRTC1_RGB_4BPP_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatPVRTC_RGB_4BPP; this->metalFormat = MTLPixelFormatPVRTC_RGB_4BPP;
this->actualFormatId = angle::FormatID::PVRTC1_RGB_4BPP_UNORM_BLOCK; this->actualFormatId = angle::FormatID::PVRTC1_RGB_4BPP_UNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::PVRTC1_RGB_4BPP_UNORM_SRGB_BLOCK: case angle::FormatID::PVRTC1_RGB_4BPP_UNORM_SRGB_BLOCK:
this->metalFormat = MTLPixelFormatPVRTC_RGB_4BPP_sRGB; this->metalFormat = MTLPixelFormatPVRTC_RGB_4BPP_sRGB;
this->actualFormatId = angle::FormatID::PVRTC1_RGB_4BPP_UNORM_SRGB_BLOCK; this->actualFormatId = angle::FormatID::PVRTC1_RGB_4BPP_UNORM_SRGB_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R4G4B4A4_UNORM: case angle::FormatID::R4G4B4A4_UNORM:
this->metalFormat = MTLPixelFormatABGR4Unorm; this->metalFormat = MTLPixelFormatABGR4Unorm;
this->actualFormatId = angle::FormatID::R4G4B4A4_UNORM; this->actualFormatId = angle::FormatID::R4G4B4A4_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R5G5B5A1_UNORM: case angle::FormatID::R5G5B5A1_UNORM:
this->metalFormat = MTLPixelFormatBGR5A1Unorm;
this->metalFormat = MTLPixelFormatA1BGR5Unorm;
this->actualFormatId = angle::FormatID::R5G5B5A1_UNORM; this->actualFormatId = angle::FormatID::R5G5B5A1_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::R5G6B5_UNORM: case angle::FormatID::R5G6B5_UNORM:
this->metalFormat = MTLPixelFormatB5G6R5Unorm; this->metalFormat = MTLPixelFormatB5G6R5Unorm;
this->actualFormatId = angle::FormatID::R5G6B5_UNORM; this->actualFormatId = angle::FormatID::R5G6B5_UNORM;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::D16_UNORM: case angle::FormatID::D16_UNORM:
this->metalFormat = MTLPixelFormatDepth32Float; this->metalFormat = MTLPixelFormatDepth32Float;
this->actualFormatId = angle::FormatID::D32_FLOAT; this->actualFormatId = angle::FormatID::D32_FLOAT;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
case angle::FormatID::D24_UNORM_S8_UINT: case angle::FormatID::D24_UNORM_S8_UINT:
this->metalFormat = MTLPixelFormatDepth32Float_Stencil8; this->metalFormat = MTLPixelFormatDepth32Float_Stencil8;
this->actualFormatId = angle::FormatID::D32_FLOAT_S8X24_UINT; this->actualFormatId = angle::FormatID::D32_FLOAT_S8X24_UINT;
this->initFunction = nullptr;
this->swizzled = false;
break;
case angle::FormatID::ETC1_R8G8B8_UNORM_BLOCK:
this->metalFormat = MTLPixelFormatETC2_RGB8;
this->actualFormatId = angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK;
this->initFunction = nullptr;
this->swizzled = false;
break; break;
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST #endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
...@@ -427,257 +1215,403 @@ void VertexFormat::init(angle::FormatID angleFormatId, bool tightlyPacked) ...@@ -427,257 +1215,403 @@ void VertexFormat::init(angle::FormatID angleFormatId, bool tightlyPacked)
this->metalFormat = MTLVertexFormatInvalid; this->metalFormat = MTLVertexFormatInvalid;
this->actualFormatId = angle::FormatID::NONE; this->actualFormatId = angle::FormatID::NONE;
this->vertexLoadFunction = nullptr; this->vertexLoadFunction = nullptr;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R10G10B10A2_SNORM:
this->metalFormat = MTLVertexFormatInt1010102Normalized;
this->actualFormatId = angle::FormatID::R10G10B10A2_SNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLuint, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break;
case angle::FormatID::R10G10B10A2_UNORM:
this->metalFormat = MTLVertexFormatUInt1010102Normalized;
this->actualFormatId = angle::FormatID::R10G10B10A2_UNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLuint, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break;
case angle::FormatID::R16G16B16A16_FLOAT:
this->metalFormat = MTLVertexFormatHalf4;
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
this->vertexLoadFunction = CopyNativeVertexData<GLhalf, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R16G16B16A16_SINT: case angle::FormatID::R16G16B16A16_SINT:
this->metalFormat = MTLVertexFormatShort4; this->metalFormat = MTLVertexFormatShort4;
this->actualFormatId = angle::FormatID::R16G16B16A16_SINT; this->actualFormatId = angle::FormatID::R16G16B16A16_SINT;
this->vertexLoadFunction = CopyNativeVertexData<GLshort, 4, 4, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R16G16B16A16_SNORM: case angle::FormatID::R16G16B16A16_SNORM:
this->metalFormat = MTLVertexFormatShort4Normalized; this->metalFormat = MTLVertexFormatShort4Normalized;
this->actualFormatId = angle::FormatID::R16G16B16A16_SNORM; this->actualFormatId = angle::FormatID::R16G16B16A16_SNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLshort, 4, 4, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R16G16B16A16_SSCALED: case angle::FormatID::R16G16B16A16_SSCALED:
this->metalFormat = MTLVertexFormatShort4; this->metalFormat = MTLVertexFormatShort4;
this->actualFormatId = angle::FormatID::R16G16B16A16_SSCALED; this->actualFormatId = angle::FormatID::R16G16B16A16_SSCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLshort, 4, 4, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R16G16B16A16_UINT: case angle::FormatID::R16G16B16A16_UINT:
this->metalFormat = MTLVertexFormatUShort4; this->metalFormat = MTLVertexFormatUShort4;
this->actualFormatId = angle::FormatID::R16G16B16A16_UINT; this->actualFormatId = angle::FormatID::R16G16B16A16_UINT;
this->vertexLoadFunction = CopyNativeVertexData<GLushort, 4, 4, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R16G16B16A16_UNORM: case angle::FormatID::R16G16B16A16_UNORM:
this->metalFormat = MTLVertexFormatUShort4Normalized; this->metalFormat = MTLVertexFormatUShort4Normalized;
this->actualFormatId = angle::FormatID::R16G16B16A16_UNORM; this->actualFormatId = angle::FormatID::R16G16B16A16_UNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLushort, 4, 4, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R16G16B16A16_USCALED: case angle::FormatID::R16G16B16A16_USCALED:
this->metalFormat = MTLVertexFormatUShort4; this->metalFormat = MTLVertexFormatUShort4;
this->actualFormatId = angle::FormatID::R16G16B16A16_USCALED; this->actualFormatId = angle::FormatID::R16G16B16A16_USCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLushort, 4, 4, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break;
case angle::FormatID::R16G16B16_FLOAT:
if (tightlyPacked)
{
this->metalFormat = MTLVertexFormatHalf4;
this->actualFormatId = angle::FormatID::R16G16B16A16_FLOAT;
this->vertexLoadFunction = CopyNativeVertexData<GLhalf, 3, 4, gl::Float16One>;
this->defaultAlpha = gl::Float16One;
this->actualSameGLType = true;
}
else
{
this->metalFormat = MTLVertexFormatHalf3;
this->actualFormatId = angle::FormatID::R16G16B16_FLOAT;
this->vertexLoadFunction = CopyNativeVertexData<GLhalf, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
}
break; break;
case angle::FormatID::R16G16B16_SINT: case angle::FormatID::R16G16B16_SINT:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat3; this->metalFormat = MTLVertexFormatShort4;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT; this->actualFormatId = angle::FormatID::R16G16B16A16_SINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLshort, 3, 3, false>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 3, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatShort3; this->metalFormat = MTLVertexFormatShort3;
this->actualFormatId = angle::FormatID::R16G16B16_SINT; this->actualFormatId = angle::FormatID::R16G16B16_SINT;
this->vertexLoadFunction = CopyNativeVertexData<GLshort, 3, 3, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R16G16B16_SNORM: case angle::FormatID::R16G16B16_SNORM:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat3; this->metalFormat = MTLVertexFormatShort4Normalized;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT; this->actualFormatId = angle::FormatID::R16G16B16A16_SNORM;
this->vertexLoadFunction = CopyTo32FVertexData<GLshort, 3, 3, true>; this->vertexLoadFunction =
CopyNativeVertexData<GLshort, 3, 4, std::numeric_limits<GLshort>::max()>;
this->defaultAlpha = std::numeric_limits<GLshort>::max();
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatShort3Normalized; this->metalFormat = MTLVertexFormatShort3Normalized;
this->actualFormatId = angle::FormatID::R16G16B16_SNORM; this->actualFormatId = angle::FormatID::R16G16B16_SNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLshort, 3, 3, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R16G16B16_SSCALED: case angle::FormatID::R16G16B16_SSCALED:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat3; this->metalFormat = MTLVertexFormatShort4;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT; this->actualFormatId = angle::FormatID::R16G16B16A16_SINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLshort, 3, 3, false>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 3, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatShort3; this->metalFormat = MTLVertexFormatShort3;
this->actualFormatId = angle::FormatID::R16G16B16_SSCALED; this->actualFormatId = angle::FormatID::R16G16B16_SSCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLshort, 3, 3, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R16G16B16_UINT: case angle::FormatID::R16G16B16_UINT:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat3; this->metalFormat = MTLVertexFormatUShort4;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT; this->actualFormatId = angle::FormatID::R16G16B16A16_UINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLushort, 3, 3, false>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 3, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatUShort3; this->metalFormat = MTLVertexFormatUShort3;
this->actualFormatId = angle::FormatID::R16G16B16_UINT; this->actualFormatId = angle::FormatID::R16G16B16_UINT;
this->vertexLoadFunction = CopyNativeVertexData<GLushort, 3, 3, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R16G16B16_UNORM: case angle::FormatID::R16G16B16_UNORM:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat3; this->metalFormat = MTLVertexFormatUShort4Normalized;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT; this->actualFormatId = angle::FormatID::R16G16B16A16_UNORM;
this->vertexLoadFunction = CopyTo32FVertexData<GLushort, 3, 3, true>; this->vertexLoadFunction =
CopyNativeVertexData<GLushort, 3, 4, std::numeric_limits<GLushort>::max()>;
this->defaultAlpha = std::numeric_limits<GLushort>::max();
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatUShort3Normalized; this->metalFormat = MTLVertexFormatUShort3Normalized;
this->actualFormatId = angle::FormatID::R16G16B16_UNORM; this->actualFormatId = angle::FormatID::R16G16B16_UNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLushort, 3, 3, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R16G16B16_USCALED: case angle::FormatID::R16G16B16_USCALED:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat3; this->metalFormat = MTLVertexFormatUShort4;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT; this->actualFormatId = angle::FormatID::R16G16B16A16_UINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLushort, 3, 3, false>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 3, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatUShort3; this->metalFormat = MTLVertexFormatUShort3;
this->actualFormatId = angle::FormatID::R16G16B16_USCALED; this->actualFormatId = angle::FormatID::R16G16B16_USCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLushort, 3, 3, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R16G16_FLOAT:
this->metalFormat = MTLVertexFormatHalf2;
this->actualFormatId = angle::FormatID::R16G16_FLOAT;
this->vertexLoadFunction = CopyNativeVertexData<GLhalf, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break;
case angle::FormatID::R16G16_SINT: case angle::FormatID::R16G16_SINT:
this->metalFormat = MTLVertexFormatShort2; this->metalFormat = MTLVertexFormatShort2;
this->actualFormatId = angle::FormatID::R16G16_SINT; this->actualFormatId = angle::FormatID::R16G16_SINT;
this->vertexLoadFunction = CopyNativeVertexData<GLshort, 2, 2, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R16G16_SNORM: case angle::FormatID::R16G16_SNORM:
this->metalFormat = MTLVertexFormatShort2Normalized; this->metalFormat = MTLVertexFormatShort2Normalized;
this->actualFormatId = angle::FormatID::R16G16_SNORM; this->actualFormatId = angle::FormatID::R16G16_SNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLshort, 2, 2, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R16G16_SSCALED: case angle::FormatID::R16G16_SSCALED:
this->metalFormat = MTLVertexFormatShort2; this->metalFormat = MTLVertexFormatShort2;
this->actualFormatId = angle::FormatID::R16G16_SSCALED; this->actualFormatId = angle::FormatID::R16G16_SSCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLshort, 2, 2, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R16G16_UINT: case angle::FormatID::R16G16_UINT:
this->metalFormat = MTLVertexFormatUShort2; this->metalFormat = MTLVertexFormatUShort2;
this->actualFormatId = angle::FormatID::R16G16_UINT; this->actualFormatId = angle::FormatID::R16G16_UINT;
this->vertexLoadFunction = CopyNativeVertexData<GLushort, 2, 2, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R16G16_UNORM: case angle::FormatID::R16G16_UNORM:
this->metalFormat = MTLVertexFormatUShort2Normalized; this->metalFormat = MTLVertexFormatUShort2Normalized;
this->actualFormatId = angle::FormatID::R16G16_UNORM; this->actualFormatId = angle::FormatID::R16G16_UNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLushort, 2, 2, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R16G16_USCALED: case angle::FormatID::R16G16_USCALED:
this->metalFormat = MTLVertexFormatUShort2; this->metalFormat = MTLVertexFormatUShort2;
this->actualFormatId = angle::FormatID::R16G16_USCALED; this->actualFormatId = angle::FormatID::R16G16_USCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLushort, 2, 2, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break;
case angle::FormatID::R16_FLOAT:
if (tightlyPacked)
{
this->metalFormat = MTLVertexFormatHalf2;
this->actualFormatId = angle::FormatID::R16G16_FLOAT;
this->vertexLoadFunction = CopyNativeVertexData<GLhalf, 1, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
}
else
{
this->metalFormat = MTLVertexFormatHalf;
this->actualFormatId = angle::FormatID::R16_FLOAT;
this->vertexLoadFunction = CopyNativeVertexData<GLhalf, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
}
break; break;
case angle::FormatID::R16_SINT: case angle::FormatID::R16_SINT:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat; this->metalFormat = MTLVertexFormatShort2;
this->actualFormatId = angle::FormatID::R32_FLOAT; this->actualFormatId = angle::FormatID::R16G16_SINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLshort, 1, 1, false>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 1, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatShort; this->metalFormat = MTLVertexFormatShort;
this->actualFormatId = angle::FormatID::R16_SINT; this->actualFormatId = angle::FormatID::R16_SINT;
this->vertexLoadFunction = CopyNativeVertexData<GLshort, 1, 1, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R16_SNORM: case angle::FormatID::R16_SNORM:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat; this->metalFormat = MTLVertexFormatShort2Normalized;
this->actualFormatId = angle::FormatID::R32_FLOAT; this->actualFormatId = angle::FormatID::R16G16_SNORM;
this->vertexLoadFunction = CopyTo32FVertexData<GLshort, 1, 1, true>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 1, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatShortNormalized; this->metalFormat = MTLVertexFormatShortNormalized;
this->actualFormatId = angle::FormatID::R16_SNORM; this->actualFormatId = angle::FormatID::R16_SNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLshort, 1, 1, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R16_SSCALED: case angle::FormatID::R16_SSCALED:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat; this->metalFormat = MTLVertexFormatShort2;
this->actualFormatId = angle::FormatID::R32_FLOAT; this->actualFormatId = angle::FormatID::R16G16_SINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLshort, 1, 1, false>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 1, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatShort; this->metalFormat = MTLVertexFormatShort;
this->actualFormatId = angle::FormatID::R16_SSCALED; this->actualFormatId = angle::FormatID::R16_SSCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLshort, 1, 1, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLshort, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R16_UINT: case angle::FormatID::R16_UINT:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat; this->metalFormat = MTLVertexFormatUShort2;
this->actualFormatId = angle::FormatID::R32_FLOAT; this->actualFormatId = angle::FormatID::R16G16_UINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLushort, 1, 1, false>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 1, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatUShort; this->metalFormat = MTLVertexFormatUShort;
this->actualFormatId = angle::FormatID::R16_UINT; this->actualFormatId = angle::FormatID::R16_UINT;
this->vertexLoadFunction = CopyNativeVertexData<GLushort, 1, 1, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R16_UNORM: case angle::FormatID::R16_UNORM:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat; this->metalFormat = MTLVertexFormatUShort2Normalized;
this->actualFormatId = angle::FormatID::R32_FLOAT; this->actualFormatId = angle::FormatID::R16G16_UNORM;
this->vertexLoadFunction = CopyTo32FVertexData<GLushort, 1, 1, true>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 1, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatUShortNormalized; this->metalFormat = MTLVertexFormatUShortNormalized;
this->actualFormatId = angle::FormatID::R16_UNORM; this->actualFormatId = angle::FormatID::R16_UNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLushort, 1, 1, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R16_USCALED: case angle::FormatID::R16_USCALED:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat; this->metalFormat = MTLVertexFormatUShort2;
this->actualFormatId = angle::FormatID::R32_FLOAT; this->actualFormatId = angle::FormatID::R16G16_UINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLushort, 1, 1, false>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 1, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatUShort; this->metalFormat = MTLVertexFormatUShort;
this->actualFormatId = angle::FormatID::R16_USCALED; this->actualFormatId = angle::FormatID::R16_USCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLushort, 1, 1, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLushort, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
...@@ -685,360 +1619,692 @@ void VertexFormat::init(angle::FormatID angleFormatId, bool tightlyPacked) ...@@ -685,360 +1619,692 @@ void VertexFormat::init(angle::FormatID angleFormatId, bool tightlyPacked)
this->metalFormat = MTLVertexFormatFloat4; this->metalFormat = MTLVertexFormatFloat4;
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT; this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
this->vertexLoadFunction = CopyNativeVertexData<GLfloat, 4, 4, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLfloat, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break;
case angle::FormatID::R32G32B32A32_SINT:
this->metalFormat = MTLVertexFormatInt4;
this->actualFormatId = angle::FormatID::R32G32B32A32_SINT;
this->vertexLoadFunction = CopyNativeVertexData<GLint, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break;
case angle::FormatID::R32G32B32A32_UINT:
this->metalFormat = MTLVertexFormatUInt4;
this->actualFormatId = angle::FormatID::R32G32B32A32_UINT;
this->vertexLoadFunction = CopyNativeVertexData<GLuint, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R32G32B32_FLOAT: case angle::FormatID::R32G32B32_FLOAT:
this->metalFormat = MTLVertexFormatFloat3; this->metalFormat = MTLVertexFormatFloat3;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT; this->actualFormatId = angle::FormatID::R32G32B32_FLOAT;
this->vertexLoadFunction = CopyNativeVertexData<GLfloat, 3, 3, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLfloat, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break;
case angle::FormatID::R32G32B32_SINT:
this->metalFormat = MTLVertexFormatInt3;
this->actualFormatId = angle::FormatID::R32G32B32_SINT;
this->vertexLoadFunction = CopyNativeVertexData<GLint, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break;
case angle::FormatID::R32G32B32_UINT:
this->metalFormat = MTLVertexFormatUInt3;
this->actualFormatId = angle::FormatID::R32G32B32_UINT;
this->vertexLoadFunction = CopyNativeVertexData<GLuint, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R32G32_FLOAT: case angle::FormatID::R32G32_FLOAT:
this->metalFormat = MTLVertexFormatFloat2; this->metalFormat = MTLVertexFormatFloat2;
this->actualFormatId = angle::FormatID::R32G32_FLOAT; this->actualFormatId = angle::FormatID::R32G32_FLOAT;
this->vertexLoadFunction = CopyNativeVertexData<GLfloat, 2, 2, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLfloat, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break;
case angle::FormatID::R32G32_SINT:
this->metalFormat = MTLVertexFormatInt2;
this->actualFormatId = angle::FormatID::R32G32_SINT;
this->vertexLoadFunction = CopyNativeVertexData<GLint, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break;
case angle::FormatID::R32G32_UINT:
this->metalFormat = MTLVertexFormatUInt2;
this->actualFormatId = angle::FormatID::R32G32_UINT;
this->vertexLoadFunction = CopyNativeVertexData<GLuint, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R32_FLOAT: case angle::FormatID::R32_FLOAT:
this->metalFormat = MTLVertexFormatFloat; this->metalFormat = MTLVertexFormatFloat;
this->actualFormatId = angle::FormatID::R32_FLOAT; this->actualFormatId = angle::FormatID::R32_FLOAT;
this->vertexLoadFunction = CopyNativeVertexData<GLfloat, 1, 1, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLfloat, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break;
case angle::FormatID::R32_SINT:
this->metalFormat = MTLVertexFormatInt;
this->actualFormatId = angle::FormatID::R32_SINT;
this->vertexLoadFunction = CopyNativeVertexData<GLint, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break;
case angle::FormatID::R32_UINT:
this->metalFormat = MTLVertexFormatUInt;
this->actualFormatId = angle::FormatID::R32_UINT;
this->vertexLoadFunction = CopyNativeVertexData<GLuint, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R8G8B8A8_SINT: case angle::FormatID::R8G8B8A8_SINT:
this->metalFormat = MTLVertexFormatChar4; this->metalFormat = MTLVertexFormatChar4;
this->actualFormatId = angle::FormatID::R8G8B8A8_SINT; this->actualFormatId = angle::FormatID::R8G8B8A8_SINT;
this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 4, 4, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R8G8B8A8_SNORM: case angle::FormatID::R8G8B8A8_SNORM:
this->metalFormat = MTLVertexFormatChar4Normalized; this->metalFormat = MTLVertexFormatChar4Normalized;
this->actualFormatId = angle::FormatID::R8G8B8A8_SNORM; this->actualFormatId = angle::FormatID::R8G8B8A8_SNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 4, 4, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R8G8B8A8_SSCALED: case angle::FormatID::R8G8B8A8_SSCALED:
this->metalFormat = MTLVertexFormatChar4; this->metalFormat = MTLVertexFormatChar4;
this->actualFormatId = angle::FormatID::R8G8B8A8_SSCALED; this->actualFormatId = angle::FormatID::R8G8B8A8_SSCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 4, 4, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R8G8B8A8_UINT: case angle::FormatID::R8G8B8A8_UINT:
this->metalFormat = MTLVertexFormatUChar4; this->metalFormat = MTLVertexFormatUChar4;
this->actualFormatId = angle::FormatID::R8G8B8A8_UINT; this->actualFormatId = angle::FormatID::R8G8B8A8_UINT;
this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 4, 4, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R8G8B8A8_UNORM: case angle::FormatID::R8G8B8A8_UNORM:
this->metalFormat = MTLVertexFormatUChar4Normalized; this->metalFormat = MTLVertexFormatUChar4Normalized;
this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 4, 4, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R8G8B8A8_USCALED: case angle::FormatID::R8G8B8A8_USCALED:
this->metalFormat = MTLVertexFormatUChar4; this->metalFormat = MTLVertexFormatUChar4;
this->actualFormatId = angle::FormatID::R8G8B8A8_USCALED; this->actualFormatId = angle::FormatID::R8G8B8A8_USCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 4, 4, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 4, 4, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
break; break;
case angle::FormatID::R8G8B8_SINT: case angle::FormatID::R8G8B8_SINT:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat3; this->metalFormat = MTLVertexFormatChar4;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_SINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLbyte, 3, 3, false>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 3, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatChar3; this->metalFormat = MTLVertexFormatChar3;
this->actualFormatId = angle::FormatID::R8G8B8_SINT; this->actualFormatId = angle::FormatID::R8G8B8_SINT;
this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 3, 3, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8G8B8_SNORM: case angle::FormatID::R8G8B8_SNORM:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat3; this->metalFormat = MTLVertexFormatChar4Normalized;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_SNORM;
this->vertexLoadFunction = CopyTo32FVertexData<GLbyte, 3, 3, true>; this->vertexLoadFunction =
CopyNativeVertexData<GLbyte, 3, 4, std::numeric_limits<GLbyte>::max()>;
this->defaultAlpha = std::numeric_limits<GLbyte>::max();
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatChar3Normalized; this->metalFormat = MTLVertexFormatChar3Normalized;
this->actualFormatId = angle::FormatID::R8G8B8_SNORM; this->actualFormatId = angle::FormatID::R8G8B8_SNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 3, 3, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8G8B8_SSCALED: case angle::FormatID::R8G8B8_SSCALED:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat3; this->metalFormat = MTLVertexFormatChar4;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_SINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLbyte, 3, 3, false>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 3, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatChar3; this->metalFormat = MTLVertexFormatChar3;
this->actualFormatId = angle::FormatID::R8G8B8_SSCALED; this->actualFormatId = angle::FormatID::R8G8B8_SSCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 3, 3, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8G8B8_UINT: case angle::FormatID::R8G8B8_UINT:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat3; this->metalFormat = MTLVertexFormatUChar4;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_UINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLubyte, 3, 3, false>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 3, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatUChar3; this->metalFormat = MTLVertexFormatUChar3;
this->actualFormatId = angle::FormatID::R8G8B8_UINT; this->actualFormatId = angle::FormatID::R8G8B8_UINT;
this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 3, 3, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8G8B8_UNORM: case angle::FormatID::R8G8B8_UNORM:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat3; this->metalFormat = MTLVertexFormatUChar4Normalized;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
this->vertexLoadFunction = CopyTo32FVertexData<GLubyte, 3, 3, true>; this->vertexLoadFunction =
CopyNativeVertexData<GLubyte, 3, 4, std::numeric_limits<GLubyte>::max()>;
this->defaultAlpha = std::numeric_limits<GLubyte>::max();
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatUChar3Normalized; this->metalFormat = MTLVertexFormatUChar3Normalized;
this->actualFormatId = angle::FormatID::R8G8B8_UNORM; this->actualFormatId = angle::FormatID::R8G8B8_UNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 3, 3, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8G8B8_USCALED: case angle::FormatID::R8G8B8_USCALED:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat3; this->metalFormat = MTLVertexFormatUChar4;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_UINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLubyte, 3, 3, false>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 3, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatUChar3; this->metalFormat = MTLVertexFormatUChar3;
this->actualFormatId = angle::FormatID::R8G8B8_USCALED; this->actualFormatId = angle::FormatID::R8G8B8_USCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 3, 3, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 3, 3, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8G8_SINT: case angle::FormatID::R8G8_SINT:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat2; this->metalFormat = MTLVertexFormatChar4;
this->actualFormatId = angle::FormatID::R32G32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_SINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLbyte, 2, 2, false>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 2, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatChar2; this->metalFormat = MTLVertexFormatChar2;
this->actualFormatId = angle::FormatID::R8G8_SINT; this->actualFormatId = angle::FormatID::R8G8_SINT;
this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 2, 2, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8G8_SNORM: case angle::FormatID::R8G8_SNORM:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat2; this->metalFormat = MTLVertexFormatChar4Normalized;
this->actualFormatId = angle::FormatID::R32G32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_SNORM;
this->vertexLoadFunction = CopyTo32FVertexData<GLbyte, 2, 2, true>; this->vertexLoadFunction =
CopyNativeVertexData<GLbyte, 2, 4, std::numeric_limits<GLbyte>::max()>;
this->defaultAlpha = std::numeric_limits<GLbyte>::max();
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatChar2Normalized; this->metalFormat = MTLVertexFormatChar2Normalized;
this->actualFormatId = angle::FormatID::R8G8_SNORM; this->actualFormatId = angle::FormatID::R8G8_SNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 2, 2, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8G8_SSCALED: case angle::FormatID::R8G8_SSCALED:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat2; this->metalFormat = MTLVertexFormatChar4;
this->actualFormatId = angle::FormatID::R32G32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_SINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLbyte, 2, 2, false>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 2, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatChar2; this->metalFormat = MTLVertexFormatChar2;
this->actualFormatId = angle::FormatID::R8G8_SSCALED; this->actualFormatId = angle::FormatID::R8G8_SSCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 2, 2, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8G8_UINT: case angle::FormatID::R8G8_UINT:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat2; this->metalFormat = MTLVertexFormatUChar4;
this->actualFormatId = angle::FormatID::R32G32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_UINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLubyte, 2, 2, false>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 2, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatUChar2; this->metalFormat = MTLVertexFormatUChar2;
this->actualFormatId = angle::FormatID::R8G8_UINT; this->actualFormatId = angle::FormatID::R8G8_UINT;
this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 2, 2, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8G8_UNORM: case angle::FormatID::R8G8_UNORM:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat2; this->metalFormat = MTLVertexFormatUChar4Normalized;
this->actualFormatId = angle::FormatID::R32G32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
this->vertexLoadFunction = CopyTo32FVertexData<GLubyte, 2, 2, true>; this->vertexLoadFunction =
CopyNativeVertexData<GLubyte, 2, 4, std::numeric_limits<GLubyte>::max()>;
this->defaultAlpha = std::numeric_limits<GLubyte>::max();
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatUChar2Normalized; this->metalFormat = MTLVertexFormatUChar2Normalized;
this->actualFormatId = angle::FormatID::R8G8_UNORM; this->actualFormatId = angle::FormatID::R8G8_UNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 2, 2, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8G8_USCALED: case angle::FormatID::R8G8_USCALED:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat2; this->metalFormat = MTLVertexFormatUChar4;
this->actualFormatId = angle::FormatID::R32G32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_UINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLubyte, 2, 2, false>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 2, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatUChar2; this->metalFormat = MTLVertexFormatUChar2;
this->actualFormatId = angle::FormatID::R8G8_USCALED; this->actualFormatId = angle::FormatID::R8G8_USCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 2, 2, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 2, 2, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8_SINT: case angle::FormatID::R8_SINT:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat; this->metalFormat = MTLVertexFormatChar4;
this->actualFormatId = angle::FormatID::R32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_SINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLbyte, 1, 1, false>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 1, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatChar; this->metalFormat = MTLVertexFormatChar;
this->actualFormatId = angle::FormatID::R8_SINT; this->actualFormatId = angle::FormatID::R8_SINT;
this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 1, 1, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8_SNORM: case angle::FormatID::R8_SNORM:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat; this->metalFormat = MTLVertexFormatChar4Normalized;
this->actualFormatId = angle::FormatID::R32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_SNORM;
this->vertexLoadFunction = CopyTo32FVertexData<GLbyte, 1, 1, true>; this->vertexLoadFunction =
CopyNativeVertexData<GLbyte, 1, 4, std::numeric_limits<GLbyte>::max()>;
this->defaultAlpha = std::numeric_limits<GLbyte>::max();
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatCharNormalized; this->metalFormat = MTLVertexFormatCharNormalized;
this->actualFormatId = angle::FormatID::R8_SNORM; this->actualFormatId = angle::FormatID::R8_SNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 1, 1, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8_SSCALED: case angle::FormatID::R8_SSCALED:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat; this->metalFormat = MTLVertexFormatChar4;
this->actualFormatId = angle::FormatID::R32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_SINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLbyte, 1, 1, false>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 1, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatChar; this->metalFormat = MTLVertexFormatChar;
this->actualFormatId = angle::FormatID::R8_SSCALED; this->actualFormatId = angle::FormatID::R8_SSCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 1, 1, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLbyte, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8_UINT: case angle::FormatID::R8_UINT:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat; this->metalFormat = MTLVertexFormatUChar4;
this->actualFormatId = angle::FormatID::R32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_UINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLubyte, 1, 1, false>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 1, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatUChar; this->metalFormat = MTLVertexFormatUChar;
this->actualFormatId = angle::FormatID::R8_UINT; this->actualFormatId = angle::FormatID::R8_UINT;
this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 1, 1, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8_UNORM: case angle::FormatID::R8_UNORM:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat; this->metalFormat = MTLVertexFormatUChar4Normalized;
this->actualFormatId = angle::FormatID::R32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM;
this->vertexLoadFunction = CopyTo32FVertexData<GLubyte, 1, 1, true>; this->vertexLoadFunction =
CopyNativeVertexData<GLubyte, 1, 4, std::numeric_limits<GLubyte>::max()>;
this->defaultAlpha = std::numeric_limits<GLubyte>::max();
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatUCharNormalized; this->metalFormat = MTLVertexFormatUCharNormalized;
this->actualFormatId = angle::FormatID::R8_UNORM; this->actualFormatId = angle::FormatID::R8_UNORM;
this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 1, 1, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R8_USCALED: case angle::FormatID::R8_USCALED:
if (tightlyPacked) if (tightlyPacked)
{ {
this->metalFormat = MTLVertexFormatFloat; this->metalFormat = MTLVertexFormatUChar4;
this->actualFormatId = angle::FormatID::R32_FLOAT; this->actualFormatId = angle::FormatID::R8G8B8A8_UINT;
this->vertexLoadFunction = CopyTo32FVertexData<GLubyte, 1, 1, false>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 1, 4, 1>;
this->defaultAlpha = 1;
this->actualSameGLType = true;
} }
else else
{ {
this->metalFormat = MTLVertexFormatUChar; this->metalFormat = MTLVertexFormatUChar;
this->actualFormatId = angle::FormatID::R8_USCALED; this->actualFormatId = angle::FormatID::R8_USCALED;
this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 1, 1, 0>; this->vertexLoadFunction = CopyNativeVertexData<GLubyte, 1, 1, 0>;
this->defaultAlpha = 0;
this->actualSameGLType = true;
} }
break; break;
case angle::FormatID::R10G10B10A2_SINT:
this->metalFormat = MTLVertexFormatFloat4;
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
this->vertexLoadFunction = CopyXYZ10W2ToXYZW32FVertexData<true, false, true>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R10G10B10A2_SSCALED:
this->metalFormat = MTLVertexFormatFloat4;
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
this->vertexLoadFunction = CopyXYZ10W2ToXYZW32FVertexData<true, false, true>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R10G10B10A2_UINT:
this->metalFormat = MTLVertexFormatFloat4;
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
this->vertexLoadFunction = CopyXYZ10W2ToXYZW32FVertexData<false, false, true>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R10G10B10A2_USCALED:
this->metalFormat = MTLVertexFormatFloat4;
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
this->vertexLoadFunction = CopyXYZ10W2ToXYZW32FVertexData<false, false, true>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32G32B32A32_FIXED: case angle::FormatID::R32G32B32A32_FIXED:
this->metalFormat = MTLVertexFormatFloat4; this->metalFormat = MTLVertexFormatFloat4;
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT; this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
this->vertexLoadFunction = Copy32FixedTo32FVertexData<4, 4>; this->vertexLoadFunction = Copy32FixedTo32FVertexData<4, 4>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32G32B32A32_SNORM:
this->metalFormat = MTLVertexFormatFloat4;
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLint, 4, 4, true>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32G32B32A32_SSCALED:
this->metalFormat = MTLVertexFormatFloat4;
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLint, 4, 4, false>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32G32B32A32_UNORM:
this->metalFormat = MTLVertexFormatFloat4;
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLuint, 4, 4, true>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32G32B32A32_USCALED:
this->metalFormat = MTLVertexFormatFloat4;
this->actualFormatId = angle::FormatID::R32G32B32A32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLuint, 4, 4, false>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break; break;
case angle::FormatID::R32G32B32_FIXED: case angle::FormatID::R32G32B32_FIXED:
this->metalFormat = MTLVertexFormatFloat3; this->metalFormat = MTLVertexFormatFloat3;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT; this->actualFormatId = angle::FormatID::R32G32B32_FLOAT;
this->vertexLoadFunction = Copy32FixedTo32FVertexData<3, 3>; this->vertexLoadFunction = Copy32FixedTo32FVertexData<3, 3>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32G32B32_SNORM:
this->metalFormat = MTLVertexFormatFloat3;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLint, 3, 3, true>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32G32B32_SSCALED:
this->metalFormat = MTLVertexFormatFloat3;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLint, 3, 3, false>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32G32B32_UNORM:
this->metalFormat = MTLVertexFormatFloat3;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLuint, 3, 3, true>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32G32B32_USCALED:
this->metalFormat = MTLVertexFormatFloat3;
this->actualFormatId = angle::FormatID::R32G32B32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLuint, 3, 3, false>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break; break;
case angle::FormatID::R32G32_FIXED: case angle::FormatID::R32G32_FIXED:
this->metalFormat = MTLVertexFormatFloat2; this->metalFormat = MTLVertexFormatFloat2;
this->actualFormatId = angle::FormatID::R32G32_FLOAT; this->actualFormatId = angle::FormatID::R32G32_FLOAT;
this->vertexLoadFunction = Copy32FixedTo32FVertexData<2, 2>; this->vertexLoadFunction = Copy32FixedTo32FVertexData<2, 2>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32G32_SNORM:
this->metalFormat = MTLVertexFormatFloat2;
this->actualFormatId = angle::FormatID::R32G32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLint, 2, 2, true>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32G32_SSCALED:
this->metalFormat = MTLVertexFormatFloat2;
this->actualFormatId = angle::FormatID::R32G32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLint, 2, 2, false>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32G32_UNORM:
this->metalFormat = MTLVertexFormatFloat2;
this->actualFormatId = angle::FormatID::R32G32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLuint, 2, 2, true>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32G32_USCALED:
this->metalFormat = MTLVertexFormatFloat2;
this->actualFormatId = angle::FormatID::R32G32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLuint, 2, 2, false>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break; break;
case angle::FormatID::R32_FIXED: case angle::FormatID::R32_FIXED:
this->metalFormat = MTLVertexFormatFloat; this->metalFormat = MTLVertexFormatFloat;
this->actualFormatId = angle::FormatID::R32_FLOAT; this->actualFormatId = angle::FormatID::R32_FLOAT;
this->vertexLoadFunction = Copy32FixedTo32FVertexData<1, 1>; this->vertexLoadFunction = Copy32FixedTo32FVertexData<1, 1>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32_SNORM:
this->metalFormat = MTLVertexFormatFloat;
this->actualFormatId = angle::FormatID::R32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLint, 1, 1, true>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32_SSCALED:
this->metalFormat = MTLVertexFormatFloat;
this->actualFormatId = angle::FormatID::R32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLint, 1, 1, false>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32_UNORM:
this->metalFormat = MTLVertexFormatFloat;
this->actualFormatId = angle::FormatID::R32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLuint, 1, 1, true>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break;
case angle::FormatID::R32_USCALED:
this->metalFormat = MTLVertexFormatFloat;
this->actualFormatId = angle::FormatID::R32_FLOAT;
this->vertexLoadFunction = CopyTo32FVertexData<GLuint, 1, 1, false>;
this->defaultAlpha = 0;
this->actualSameGLType = false;
break; break;
default: default:
this->metalFormat = MTLVertexFormatInvalid; this->metalFormat = MTLVertexFormatInvalid;
this->actualFormatId = angle::FormatID::NONE; this->actualFormatId = angle::FormatID::NONE;
this->vertexLoadFunction = nullptr; this->vertexLoadFunction = nullptr;
this->defaultAlpha = 0;
this->actualSameGLType = false;
} }
} }
......
...@@ -13,10 +13,13 @@ ...@@ -13,10 +13,13 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
#include <unordered_map>
#include "common/angleutils.h" #include "common/angleutils.h"
#include "libANGLE/Caps.h" #include "libANGLE/Caps.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/renderer/copyvertex.h" #include "libANGLE/renderer/copyvertex.h"
#include "libANGLE/renderer/renderer_utils.h"
namespace rx namespace rx
{ {
...@@ -41,6 +44,19 @@ struct FormatBase ...@@ -41,6 +44,19 @@ struct FormatBase
angle::FormatID intendedFormatId = angle::FormatID::NONE; angle::FormatID intendedFormatId = angle::FormatID::NONE;
}; };
struct FormatCaps
{
bool isRenderable() const { return colorRenderable || depthRenderable; }
bool filterable = false;
bool writable = false;
bool colorRenderable = false;
bool depthRenderable = false;
bool blendable = false;
bool multisample = false; // can be used as MSAA target
bool resolve = false; // Can be used as resolve target
};
// Pixel format // Pixel format
struct Format : public FormatBase struct Format : public FormatBase
{ {
...@@ -49,12 +65,31 @@ struct Format : public FormatBase ...@@ -49,12 +65,31 @@ struct Format : public FormatBase
const gl::InternalFormat &intendedInternalFormat() const; const gl::InternalFormat &intendedInternalFormat() const;
bool valid() const { return metalFormat != MTLPixelFormatInvalid; } bool valid() const { return metalFormat != MTLPixelFormatInvalid; }
bool hasDepthAndStencilBits() const
{
return actualAngleFormat().depthBits && actualAngleFormat().stencilBits;
}
bool hasDepthOrStencilBits() const
{
return actualAngleFormat().depthBits || actualAngleFormat().stencilBits;
}
bool isPVRTC() const;
static bool FormatRenderable(MTLPixelFormat format); const FormatCaps &getCaps() const { return *caps; }
static bool FormatCPUReadable(MTLPixelFormat format);
// Need conversion between source format and this format?
bool needConversion(angle::FormatID srcFormatId) const;
MTLPixelFormat metalFormat = MTLPixelFormatInvalid; MTLPixelFormat metalFormat = MTLPixelFormatInvalid;
LoadFunctionMap textureLoadFunctions = nullptr;
InitializeTextureDataFunction initFunction = nullptr;
const FormatCaps *caps = nullptr;
bool swizzled = false;
std::array<GLenum, 4> swizzle;
private: private:
void init(const DisplayMtl *display, angle::FormatID intendedFormatId); void init(const DisplayMtl *display, angle::FormatID intendedFormatId);
...@@ -70,6 +105,11 @@ struct VertexFormat : public FormatBase ...@@ -70,6 +105,11 @@ struct VertexFormat : public FormatBase
VertexCopyFunction vertexLoadFunction = nullptr; VertexCopyFunction vertexLoadFunction = nullptr;
uint32_t defaultAlpha = 0;
// Intended and actual format have same GL type, and possibly only differ in number of
// components?
bool actualSameGLType = true;
private: private:
void init(angle::FormatID angleFormatId, bool tightlyPacked = false); void init(angle::FormatID angleFormatId, bool tightlyPacked = false);
...@@ -86,9 +126,10 @@ class FormatTable final : angle::NonCopyable ...@@ -86,9 +126,10 @@ class FormatTable final : angle::NonCopyable
void generateTextureCaps(const DisplayMtl *display, void generateTextureCaps(const DisplayMtl *display,
gl::TextureCapsMap *capsMapOut, gl::TextureCapsMap *capsMapOut,
std::vector<GLenum> *compressedFormatsOut) const; std::vector<GLenum> *compressedFormatsOut);
const Format &getPixelFormat(angle::FormatID angleFormatId) const; const Format &getPixelFormat(angle::FormatID angleFormatId) const;
const FormatCaps &getNativeFormatCaps(MTLPixelFormat mtlFormat) const;
// tightlyPacked means this format will be used in a tightly packed vertex buffer. // tightlyPacked means this format will be used in a tightly packed vertex buffer.
// In that case, it's easier to just convert everything to float to ensure // In that case, it's easier to just convert everything to float to ensure
...@@ -96,10 +137,34 @@ class FormatTable final : angle::NonCopyable ...@@ -96,10 +137,34 @@ class FormatTable final : angle::NonCopyable
// of how many components each element has. // of how many components each element has.
const VertexFormat &getVertexFormat(angle::FormatID angleFormatId, bool tightlyPacked) const; const VertexFormat &getVertexFormat(angle::FormatID angleFormatId, bool tightlyPacked) const;
uint32_t getMaxSamples() const { return mMaxSamples; }
private: private:
void initNativeFormatCaps(const DisplayMtl *display);
void setFormatCaps(MTLPixelFormat formatId,
bool filterable,
bool writable,
bool blendable,
bool multisample,
bool resolve,
bool colorRenderable);
void setFormatCaps(MTLPixelFormat formatId,
bool filterable,
bool writable,
bool blendable,
bool multisample,
bool resolve,
bool colorRenderable,
bool depthRenderable);
void setCompressedFormatCaps(MTLPixelFormat formatId, bool filterable);
std::array<Format, angle::kNumANGLEFormats> mPixelFormatTable; std::array<Format, angle::kNumANGLEFormats> mPixelFormatTable;
std::unordered_map<MTLPixelFormat, FormatCaps> mNativePixelFormatCapsTable;
// One for tightly packed buffers, one for general cases. // One for tightly packed buffers, one for general cases.
std::array<VertexFormat, angle::kNumANGLEFormats> mVertexFormatTables[2]; std::array<VertexFormat, angle::kNumANGLEFormats> mVertexFormatTables[2];
uint32_t mMaxSamples;
}; };
} // namespace mtl } // namespace mtl
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/renderer/Format.h" #include "libANGLE/renderer/Format.h"
#include "libANGLE/renderer/load_functions_table.h"
#include "libANGLE/renderer/metal/DisplayMtl.h" #include "libANGLE/renderer/metal/DisplayMtl.h"
namespace rx namespace rx
...@@ -27,14 +28,6 @@ bool OverrideTextureCaps(const DisplayMtl *display, angle::FormatID formatId, gl ...@@ -27,14 +28,6 @@ bool OverrideTextureCaps(const DisplayMtl *display, angle::FormatID formatId, gl
// NOTE(hqle): Auto generate this. // NOTE(hqle): Auto generate this.
switch (formatId) switch (formatId)
{ {
case angle::FormatID::R8G8_UNORM:
case angle::FormatID::R8G8B8_UNORM:
case angle::FormatID::R8G8B8_UNORM_SRGB:
case angle::FormatID::R8G8B8A8_UNORM:
case angle::FormatID::R8G8B8A8_UNORM_SRGB:
case angle::FormatID::B8G8R8A8_UNORM:
case angle::FormatID::B8G8R8A8_UNORM_SRGB:
case angle::FormatID::B10G10R10A2_UNORM:
// NOTE: even though iOS devices don't support filtering depth textures, we still report as // NOTE: even though iOS devices don't support filtering depth textures, we still report as
// supported here in order for the OES_depth_texture extension to be enabled. // supported here in order for the OES_depth_texture extension to be enabled.
// During draw call, the filter modes will be converted to nearest. // During draw call, the filter modes will be converted to nearest.
...@@ -55,107 +48,51 @@ bool OverrideTextureCaps(const DisplayMtl *display, angle::FormatID formatId, gl ...@@ -55,107 +48,51 @@ bool OverrideTextureCaps(const DisplayMtl *display, angle::FormatID formatId, gl
void GenerateTextureCapsMap(const FormatTable &formatTable, void GenerateTextureCapsMap(const FormatTable &formatTable,
const DisplayMtl *display, const DisplayMtl *display,
gl::TextureCapsMap *capsMapOut, gl::TextureCapsMap *capsMapOut,
std::vector<GLenum> *compressedFormatsOut) std::vector<GLenum> *compressedFormatsOut,
uint32_t *maxSamplesOut)
{ {
auto &textureCapsMap = *capsMapOut; auto &textureCapsMap = *capsMapOut;
auto &compressedFormats = *compressedFormatsOut; auto &compressedFormats = *compressedFormatsOut;
compressedFormats.clear(); compressedFormats.clear();
// Metal doesn't have programmatical way to determine texture format support.
// What is available is the online documents from Apple. What we can do here
// is manually set certain extension flag to true then let angle decide the supported formats.
//
// TODO(hqle): The proper way of doing this is creating a detailed "format support table" json
// file with info parsed from https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf.
// Then using that json file to generate a table in C++ file.
gl::Extensions tmpTextureExtensions;
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
// https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
// Requires depth24Stencil8PixelFormatSupported=YES for these extensions
bool packedDepthStencil24Support =
display->getMetalDevice().depth24Stencil8PixelFormatSupported;
tmpTextureExtensions.packedDepthStencilOES = true; // We support this reguardless
tmpTextureExtensions.colorBufferHalfFloat = packedDepthStencil24Support;
tmpTextureExtensions.colorBufferFloat = packedDepthStencil24Support;
tmpTextureExtensions.colorBufferFloatRGB = packedDepthStencil24Support;
tmpTextureExtensions.colorBufferFloatRGBA = packedDepthStencil24Support;
tmpTextureExtensions.textureHalfFloat = packedDepthStencil24Support;
tmpTextureExtensions.textureFloatOES = packedDepthStencil24Support;
tmpTextureExtensions.textureHalfFloatLinear = packedDepthStencil24Support;
tmpTextureExtensions.textureFloatLinearOES = packedDepthStencil24Support;
tmpTextureExtensions.textureRG = packedDepthStencil24Support;
tmpTextureExtensions.textureFormatBGRA8888 = packedDepthStencil24Support;
tmpTextureExtensions.textureCompressionDXT3 = true;
tmpTextureExtensions.textureCompressionDXT5 = true;
// We can only fully support DXT1 without alpha using texture swizzle support from MacOs 10.15
tmpTextureExtensions.textureCompressionDXT1 = display->getFeatures().hasTextureSwizzle.enabled;
tmpTextureExtensions.textureCompressionS3TCsRGB = tmpTextureExtensions.textureCompressionDXT1;
#else
tmpTextureExtensions.packedDepthStencilOES = true; // override to D32_FLOAT_S8X24_UINT
tmpTextureExtensions.colorBufferHalfFloat = true;
tmpTextureExtensions.colorBufferFloat = true;
tmpTextureExtensions.colorBufferFloatRGB = true;
tmpTextureExtensions.colorBufferFloatRGBA = true;
tmpTextureExtensions.textureHalfFloat = true;
tmpTextureExtensions.textureHalfFloatLinear = true;
tmpTextureExtensions.textureFloatOES = true;
tmpTextureExtensions.textureRG = true;
tmpTextureExtensions.textureFormatBGRA8888 = true;
if ([display->getMetalDevice() supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v1])
{
tmpTextureExtensions.compressedETC1RGB8Texture = true;
tmpTextureExtensions.compressedETC2RGB8Texture = true;
tmpTextureExtensions.compressedETC2sRGB8Texture = true;
tmpTextureExtensions.compressedETC2RGBA8Texture = true;
tmpTextureExtensions.compressedETC2sRGB8Alpha8Texture = true;
tmpTextureExtensions.compressedEACR11UnsignedTexture = true;
tmpTextureExtensions.compressedEACR11SignedTexture = true;
tmpTextureExtensions.compressedEACRG11UnsignedTexture = true;
tmpTextureExtensions.compressedEACRG11SignedTexture = true;
tmpTextureExtensions.compressedTexturePVRTC = true;
tmpTextureExtensions.compressedTexturePVRTCsRGB = true;
}
#endif
tmpTextureExtensions.sRGB = true;
tmpTextureExtensions.depth32OES = true;
tmpTextureExtensions.depth24OES = true;
tmpTextureExtensions.rgb8rgba8OES = true;
tmpTextureExtensions.textureStorage = true;
tmpTextureExtensions.depthTextureOES = true;
tmpTextureExtensions.depthTextureANGLE = true;
auto formatVerifier = [&](const gl::InternalFormat &internalFormatInfo) { auto formatVerifier = [&](const gl::InternalFormat &internalFormatInfo) {
angle::FormatID angleFormatId = angle::FormatID angleFormatId =
angle::Format::InternalFormatToID(internalFormatInfo.sizedInternalFormat); angle::Format::InternalFormatToID(internalFormatInfo.sizedInternalFormat);
const Format &mtlFormat = formatTable.getPixelFormat(angleFormatId); const Format &mtlFormat = formatTable.getPixelFormat(angleFormatId);
if (!mtlFormat.valid()) if (!mtlFormat.valid())
{ {
return; return;
} }
const FormatCaps &formatCaps = mtlFormat.getCaps();
const angle::Format &intendedAngleFormat = mtlFormat.intendedAngleFormat(); const angle::Format &intendedAngleFormat = mtlFormat.intendedAngleFormat();
gl::TextureCaps textureCaps; gl::TextureCaps textureCaps;
const auto &clientVersion = kMaxSupportedGLVersion; // First let check whether we can override certain special cases.
// First let check whether we can determine programmatically.
if (!OverrideTextureCaps(display, mtlFormat.intendedFormatId, &textureCaps)) if (!OverrideTextureCaps(display, mtlFormat.intendedFormatId, &textureCaps))
{ {
// Let angle decide based on extensions we enabled above. // Fill the texture caps using pixel format's caps
textureCaps = gl::GenerateMinimumTextureCaps(internalFormatInfo.sizedInternalFormat, textureCaps.filterable = mtlFormat.getCaps().filterable;
clientVersion, tmpTextureExtensions); textureCaps.renderbuffer =
mtlFormat.getCaps().colorRenderable || mtlFormat.getCaps().depthRenderable;
textureCaps.texturable = true;
textureCaps.blendable = mtlFormat.getCaps().blendable;
textureCaps.textureAttachment = textureCaps.renderbuffer;
} }
// NOTE(hqle): Support MSAA. if (formatCaps.multisample)
textureCaps.sampleCounts.clear(); {
textureCaps.sampleCounts.insert(0); constexpr uint32_t sampleCounts[] = {2, 4, 8};
textureCaps.sampleCounts.insert(1); for (auto sampleCount : sampleCounts)
{
if ([display->getMetalDevice() supportsTextureSampleCount:sampleCount])
{
textureCaps.sampleCounts.insert(sampleCount);
*maxSamplesOut = std::max(*maxSamplesOut, sampleCount);
}
}
}
textureCapsMap.set(mtlFormat.intendedFormatId, textureCaps); textureCapsMap.set(mtlFormat.intendedFormatId, textureCaps);
...@@ -163,11 +100,6 @@ void GenerateTextureCapsMap(const FormatTable &formatTable, ...@@ -163,11 +100,6 @@ void GenerateTextureCapsMap(const FormatTable &formatTable,
{ {
compressedFormats.push_back(intendedAngleFormat.glInternalFormat); compressedFormats.push_back(intendedAngleFormat.glInternalFormat);
} }
// Verify implementation mismatch
ASSERT(!textureCaps.renderbuffer || mtl::Format::FormatRenderable(mtlFormat.metalFormat));
ASSERT(!textureCaps.textureAttachment ||
mtl::Format::FormatRenderable(mtlFormat.metalFormat));
}; };
// Texture caps map. // Texture caps map.
...@@ -195,78 +127,74 @@ const angle::Format &FormatBase::intendedAngleFormat() const ...@@ -195,78 +127,74 @@ const angle::Format &FormatBase::intendedAngleFormat() const
} }
// Format implementation // Format implementation
/** static */ const gl::InternalFormat &Format::intendedInternalFormat() const
bool Format::FormatRenderable(MTLPixelFormat format) {
return gl::GetSizedInternalFormatInfo(intendedAngleFormat().glInternalFormat);
}
bool Format::needConversion(angle::FormatID srcFormatId) const
{ {
switch (format) if ((srcFormatId == angle::FormatID::BC1_RGB_UNORM_BLOCK &&
actualFormatId == angle::FormatID::BC1_RGBA_UNORM_BLOCK) ||
(srcFormatId == angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK &&
actualFormatId == angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK))
{ {
case MTLPixelFormatR8Unorm: // DXT1 RGB format already swizzled with alpha=1, so no need to convert
case MTLPixelFormatRG8Unorm: ASSERT(swizzled);
case MTLPixelFormatR16Float: return false;
case MTLPixelFormatRG16Float:
case MTLPixelFormatRGBA16Float:
case MTLPixelFormatR32Float:
case MTLPixelFormatRG32Float:
case MTLPixelFormatRGBA32Float:
case MTLPixelFormatBGRA8Unorm:
case MTLPixelFormatBGRA8Unorm_sRGB:
case MTLPixelFormatRGBA8Unorm:
case MTLPixelFormatRGBA8Unorm_sRGB:
case MTLPixelFormatDepth32Float:
case MTLPixelFormatStencil8:
case MTLPixelFormatDepth32Float_Stencil8:
case MTLPixelFormatBGR10A2Unorm:
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
case MTLPixelFormatDepth16Unorm:
case MTLPixelFormatDepth24Unorm_Stencil8:
#else
case MTLPixelFormatR8Unorm_sRGB:
case MTLPixelFormatRG8Unorm_sRGB:
case MTLPixelFormatB5G6R5Unorm:
case MTLPixelFormatA1BGR5Unorm:
case MTLPixelFormatABGR4Unorm:
case MTLPixelFormatBGR5A1Unorm:
#endif
// NOTE(hqle): we may add more formats support here in future.
return true;
default:
return false;
} }
return false; if (srcFormatId == angle::FormatID::ETC1_R8G8B8_UNORM_BLOCK &&
actualFormatId == angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK)
{
// ETC1 RGB & ETC2 RGB are technically the same.
return false;
}
return srcFormatId != actualFormatId;
} }
/** static */ bool Format::isPVRTC() const
bool Format::FormatCPUReadable(MTLPixelFormat format)
{ {
switch (format) switch (metalFormat)
{ {
case MTLPixelFormatDepth32Float: #if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
case MTLPixelFormatStencil8: case MTLPixelFormatPVRTC_RGB_2BPP:
case MTLPixelFormatDepth32Float_Stencil8: case MTLPixelFormatPVRTC_RGB_2BPP_sRGB:
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST case MTLPixelFormatPVRTC_RGB_4BPP:
case MTLPixelFormatDepth16Unorm: case MTLPixelFormatPVRTC_RGB_4BPP_sRGB:
case MTLPixelFormatDepth24Unorm_Stencil8: case MTLPixelFormatPVRTC_RGBA_2BPP:
case MTLPixelFormatPVRTC_RGBA_2BPP_sRGB:
case MTLPixelFormatPVRTC_RGBA_4BPP:
case MTLPixelFormatPVRTC_RGBA_4BPP_sRGB:
return true;
#endif #endif
// NOTE(hqle): we may add more formats support here in future.
return false;
default: default:
return true; return false;
} }
} }
const gl::InternalFormat &Format::intendedInternalFormat() const
{
return gl::GetSizedInternalFormatInfo(intendedAngleFormat().glInternalFormat);
}
// FormatTable implementation // FormatTable implementation
angle::Result FormatTable::initialize(const DisplayMtl *display) angle::Result FormatTable::initialize(const DisplayMtl *display)
{ {
mMaxSamples = 0;
// Initialize native format caps
initNativeFormatCaps(display);
for (size_t i = 0; i < angle::kNumANGLEFormats; ++i) for (size_t i = 0; i < angle::kNumANGLEFormats; ++i)
{ {
const auto formatId = static_cast<angle::FormatID>(i); const auto formatId = static_cast<angle::FormatID>(i);
mPixelFormatTable[i].init(display, formatId); mPixelFormatTable[i].init(display, formatId);
mPixelFormatTable[i].caps = &mNativePixelFormatCapsTable[mPixelFormatTable[i].metalFormat];
if (!mPixelFormatTable[i].caps->depthRenderable &&
mPixelFormatTable[i].actualFormatId != mPixelFormatTable[i].intendedFormatId)
{
mPixelFormatTable[i].textureLoadFunctions = angle::GetLoadFunctionsMap(
mPixelFormatTable[i].intendedAngleFormat().glInternalFormat,
mPixelFormatTable[i].actualFormatId);
}
mVertexFormatTables[0][i].init(formatId, false); mVertexFormatTables[0][i].init(formatId, false);
mVertexFormatTables[1][i].init(formatId, true); mVertexFormatTables[1][i].init(formatId, true);
} }
...@@ -276,15 +204,20 @@ angle::Result FormatTable::initialize(const DisplayMtl *display) ...@@ -276,15 +204,20 @@ angle::Result FormatTable::initialize(const DisplayMtl *display)
void FormatTable::generateTextureCaps(const DisplayMtl *display, void FormatTable::generateTextureCaps(const DisplayMtl *display,
gl::TextureCapsMap *capsMapOut, gl::TextureCapsMap *capsMapOut,
std::vector<GLenum> *compressedFormatsOut) const std::vector<GLenum> *compressedFormatsOut)
{ {
GenerateTextureCapsMap(*this, display, capsMapOut, compressedFormatsOut); GenerateTextureCapsMap(*this, display, capsMapOut, compressedFormatsOut, &mMaxSamples);
} }
const Format &FormatTable::getPixelFormat(angle::FormatID angleFormatId) const const Format &FormatTable::getPixelFormat(angle::FormatID angleFormatId) const
{ {
return mPixelFormatTable[static_cast<size_t>(angleFormatId)]; return mPixelFormatTable[static_cast<size_t>(angleFormatId)];
} }
const FormatCaps &FormatTable::getNativeFormatCaps(MTLPixelFormat mtlFormat) const
{
ASSERT(mNativePixelFormatCapsTable.count(mtlFormat));
return mNativePixelFormatCapsTable.at(mtlFormat);
}
const VertexFormat &FormatTable::getVertexFormat(angle::FormatID angleFormatId, const VertexFormat &FormatTable::getVertexFormat(angle::FormatID angleFormatId,
bool tightlyPacked) const bool tightlyPacked) const
{ {
...@@ -292,5 +225,158 @@ const VertexFormat &FormatTable::getVertexFormat(angle::FormatID angleFormatId, ...@@ -292,5 +225,158 @@ const VertexFormat &FormatTable::getVertexFormat(angle::FormatID angleFormatId,
return mVertexFormatTables[tableIdx][static_cast<size_t>(angleFormatId)]; return mVertexFormatTables[tableIdx][static_cast<size_t>(angleFormatId)];
} }
void FormatTable::setFormatCaps(MTLPixelFormat formatId,
bool filterable,
bool writable,
bool blendable,
bool multisample,
bool resolve,
bool colorRenderable)
{
setFormatCaps(formatId, filterable, writable, blendable, multisample, resolve, colorRenderable,
false);
}
void FormatTable::setFormatCaps(MTLPixelFormat id,
bool filterable,
bool writable,
bool blendable,
bool multisample,
bool resolve,
bool colorRenderable,
bool depthRenderable)
{
mNativePixelFormatCapsTable[id].filterable = filterable;
mNativePixelFormatCapsTable[id].writable = writable;
mNativePixelFormatCapsTable[id].colorRenderable = colorRenderable;
mNativePixelFormatCapsTable[id].depthRenderable = depthRenderable;
mNativePixelFormatCapsTable[id].blendable = blendable;
mNativePixelFormatCapsTable[id].multisample = multisample;
mNativePixelFormatCapsTable[id].resolve = resolve;
}
void FormatTable::setCompressedFormatCaps(MTLPixelFormat formatId, bool filterable)
{
setFormatCaps(formatId, filterable, false, false, false, false, false, false);
}
void FormatTable::initNativeFormatCaps(const DisplayMtl *display)
{
const angle::FeaturesMtl &featuresMtl = display->getFeatures();
// Skip auto resolve if either hasDepth/StencilAutoResolve or allowMultisampleStoreAndResolve
// feature are disabled.
bool supportDepthAutoResolve = featuresMtl.hasDepthAutoResolve.enabled &&
featuresMtl.allowMultisampleStoreAndResolve.enabled;
bool supportStencilAutoResolve = featuresMtl.hasStencilAutoResolve.enabled &&
featuresMtl.allowMultisampleStoreAndResolve.enabled;
bool supportDepthStencilAutoResolve = supportDepthAutoResolve && supportStencilAutoResolve;
// Source: https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
// clang-format off
// | formatId | filterable | writable | blendable | multisample | resolve | colorRenderable |
setFormatCaps(MTLPixelFormatA8Unorm, true, false, false, false, false, false);
setFormatCaps(MTLPixelFormatR8Unorm, true, true, true, true, true, true);
setFormatCaps(MTLPixelFormatR8Snorm, true, true, true, true, display->supportsEitherGPUFamily(2, 1), true);
setFormatCaps(MTLPixelFormatR16Unorm, true, true, true, true, display->supportsMacGPUFamily(1), true);
setFormatCaps(MTLPixelFormatR16Snorm, true, true, true, true, display->supportsMacGPUFamily(1), true);
setFormatCaps(MTLPixelFormatRG8Unorm, true, true, true, true, true, true);
setFormatCaps(MTLPixelFormatRG8Snorm, true, true, true, true, display->supportsEitherGPUFamily(2, 1), true);
setFormatCaps(MTLPixelFormatRG16Unorm, true, true, true, true, display->supportsMacGPUFamily(1), true);
setFormatCaps(MTLPixelFormatRG16Snorm, true, true, true, true, display->supportsMacGPUFamily(1), true);
setFormatCaps(MTLPixelFormatRGBA16Unorm, true, true, true, true, display->supportsMacGPUFamily(1), true);
setFormatCaps(MTLPixelFormatRGBA16Snorm, true, true, true, true, display->supportsMacGPUFamily(1), true);
setFormatCaps(MTLPixelFormatRGBA16Float, true, true, true, true, true, true);
// | formatId | filterable | writable | blendable | multisample | resolve | colorRenderable |
setFormatCaps(MTLPixelFormatRGBA8Unorm, true, true, true, true, true, true);
setFormatCaps(MTLPixelFormatRGBA8Unorm_sRGB, true, display->supportsIOSGPUFamily(2), true, true, true, true);
setFormatCaps(MTLPixelFormatRGBA8Snorm, true, true, true, true, display->supportsEitherGPUFamily(2, 1), true);
setFormatCaps(MTLPixelFormatBGRA8Unorm, true, true, true, true, true, true);
setFormatCaps(MTLPixelFormatBGRA8Unorm_sRGB, true, display->supportsIOSGPUFamily(2), true, true, true, true);
// | formatId | filterable | writable | blendable | multisample | resolve | colorRenderable |
setFormatCaps(MTLPixelFormatR16Float, true, true, true, true, true, true);
setFormatCaps(MTLPixelFormatRG16Float, true, true, true, true, true, true);
setFormatCaps(MTLPixelFormatR32Float, display->supportsMacGPUFamily(1), true, true, true, display->supportsMacGPUFamily(1), true);
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
// | formatId | filterable | writable | blendable | multisample | resolve | colorRenderable |
setFormatCaps(MTLPixelFormatB5G6R5Unorm, true, false, true, true, true, true);
setFormatCaps(MTLPixelFormatABGR4Unorm, true, false, true, true, true, true);
setFormatCaps(MTLPixelFormatBGR5A1Unorm, true, false, true, true, true, true);
setFormatCaps(MTLPixelFormatA1BGR5Unorm, true, false, true, true, true, true);
#endif
// | formatId | filterable | writable | blendable | multisample | resolve | colorRenderable |
setFormatCaps(MTLPixelFormatBGR10A2Unorm, true, display->supportsEitherGPUFamily(3, 1), true, true, true, true);
setFormatCaps(MTLPixelFormatRGB10A2Unorm, true, display->supportsEitherGPUFamily(3, 1), true, true, true, true);
setFormatCaps(MTLPixelFormatRGB10A2Uint, false, display->supportsEitherGPUFamily(3, 1), false, true, false, true);
setFormatCaps(MTLPixelFormatRG11B10Float, true, display->supportsEitherGPUFamily(3, 1), true, true, true, true);
// | formatId | filterable | writable | blendable | multisample | resolve | colorRenderable |
setFormatCaps(MTLPixelFormatRGB9E5Float, true, display->supportsIOSGPUFamily(3), display->supportsIOSGPUFamily(1), display->supportsIOSGPUFamily(1), display->supportsIOSGPUFamily(1), display->supportsIOSGPUFamily(1));
// | formatId | filterable | writable | blendable | multisample | resolve | colorRenderable |
setFormatCaps(MTLPixelFormatR8Uint, false, true, false, true, false, true);
setFormatCaps(MTLPixelFormatR8Sint, false, true, false, true, false, true);
setFormatCaps(MTLPixelFormatR16Uint, false, true, false, true, false, true);
setFormatCaps(MTLPixelFormatR16Sint, false, true, false, true, false, true);
setFormatCaps(MTLPixelFormatRG8Uint, false, true, false, true, false, true);
setFormatCaps(MTLPixelFormatRG8Sint, false, true, false, true, false, true);
setFormatCaps(MTLPixelFormatR32Uint, false, true, false, display->supportsMacGPUFamily(1), false, true);
setFormatCaps(MTLPixelFormatR32Sint, false, true, false, display->supportsMacGPUFamily(1), false, true);
setFormatCaps(MTLPixelFormatRG16Uint, false, true, false, true, false, true);
setFormatCaps(MTLPixelFormatRG16Sint, false, true, false, true, false, true);
setFormatCaps(MTLPixelFormatRGBA8Uint, false, true, false, true, false, true);
setFormatCaps(MTLPixelFormatRGBA8Sint, false, true, false, true, false, true);
setFormatCaps(MTLPixelFormatRG32Uint, false, true, false, display->supportsMacGPUFamily(1), false, true);
setFormatCaps(MTLPixelFormatRG32Sint, false, true, false, display->supportsMacGPUFamily(1), false, true);
setFormatCaps(MTLPixelFormatRGBA16Uint, false, true, false, true, false, true);
setFormatCaps(MTLPixelFormatRGBA16Sint, false, true, false, true, false, true);
setFormatCaps(MTLPixelFormatRGBA32Uint, false, true, false, display->supportsMacGPUFamily(1), false, true);
setFormatCaps(MTLPixelFormatRGBA32Sint, false, true, false, display->supportsMacGPUFamily(1), false, true);
// | formatId | filterable | writable | blendable | multisample | resolve | colorRenderable |
setFormatCaps(MTLPixelFormatRG32Float, display->supportsMacGPUFamily(1), true, true, display->supportsMacGPUFamily(1), display->supportsMacGPUFamily(1), true);
setFormatCaps(MTLPixelFormatRGBA32Float, display->supportsMacGPUFamily(1), true, display->supportsMacGPUFamily(1), display->supportsMacGPUFamily(1), display->supportsMacGPUFamily(1), true);
// | formatId | filterable | writable | blendable | multisample | resolve | colorRenderable | depthRenderable |
setFormatCaps(MTLPixelFormatDepth32Float, display->supportsMacGPUFamily(1), false, false, true, supportDepthAutoResolve, false, true);
setFormatCaps(MTLPixelFormatStencil8, false, false, false, true, false, false, true);
setFormatCaps(MTLPixelFormatDepth32Float_Stencil8, display->supportsMacGPUFamily(1), false, false, true, supportDepthStencilAutoResolve, false, true);
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
setFormatCaps(MTLPixelFormatDepth16Unorm, true, false, false, true, supportDepthAutoResolve, false, true);
setFormatCaps(MTLPixelFormatDepth24Unorm_Stencil8, display->supportsMacGPUFamily(1), false, false, true, supportDepthStencilAutoResolve, false, display->supportsMacGPUFamily(1));
setCompressedFormatCaps(MTLPixelFormatBC1_RGBA, true);
setCompressedFormatCaps(MTLPixelFormatBC1_RGBA_sRGB, true);
setCompressedFormatCaps(MTLPixelFormatBC2_RGBA, true);
setCompressedFormatCaps(MTLPixelFormatBC2_RGBA_sRGB, true);
setCompressedFormatCaps(MTLPixelFormatBC3_RGBA, true);
setCompressedFormatCaps(MTLPixelFormatBC3_RGBA_sRGB, true);
#else
setCompressedFormatCaps(MTLPixelFormatPVRTC_RGB_2BPP, true);
setCompressedFormatCaps(MTLPixelFormatPVRTC_RGB_2BPP_sRGB, true);
setCompressedFormatCaps(MTLPixelFormatPVRTC_RGB_4BPP, true);
setCompressedFormatCaps(MTLPixelFormatPVRTC_RGB_4BPP_sRGB, true);
setCompressedFormatCaps(MTLPixelFormatPVRTC_RGBA_2BPP, true);
setCompressedFormatCaps(MTLPixelFormatPVRTC_RGBA_2BPP_sRGB, true);
setCompressedFormatCaps(MTLPixelFormatPVRTC_RGBA_4BPP, true);
setCompressedFormatCaps(MTLPixelFormatPVRTC_RGBA_4BPP_sRGB, true);
setCompressedFormatCaps(MTLPixelFormatEAC_R11Unorm, true);
setCompressedFormatCaps(MTLPixelFormatEAC_R11Snorm, true);
setCompressedFormatCaps(MTLPixelFormatEAC_RG11Unorm, true);
setCompressedFormatCaps(MTLPixelFormatEAC_RG11Snorm, true);
setCompressedFormatCaps(MTLPixelFormatEAC_RGBA8, true);
setCompressedFormatCaps(MTLPixelFormatEAC_RGBA8_sRGB, true);
setCompressedFormatCaps(MTLPixelFormatETC2_RGB8, true);
setCompressedFormatCaps(MTLPixelFormatETC2_RGB8_sRGB, true);
setCompressedFormatCaps(MTLPixelFormatETC2_RGB8A1, true);
setCompressedFormatCaps(MTLPixelFormatETC2_RGB8A1_sRGB, true);
#endif
// clang-format on
}
} // namespace mtl } // namespace mtl
} // namespace rx } // namespace rx
...@@ -100,7 +100,7 @@ class Texture final : public Resource, ...@@ -100,7 +100,7 @@ class Texture final : public Resource,
uint32_t height, uint32_t height,
uint32_t mips /** use zero to create full mipmaps chain */, uint32_t mips /** use zero to create full mipmaps chain */,
bool renderTargetOnly, bool renderTargetOnly,
bool allowTextureView, bool allowFormatView,
TextureRef *refOut); TextureRef *refOut);
static angle::Result MakeCubeTexture(ContextMtl *context, static angle::Result MakeCubeTexture(ContextMtl *context,
...@@ -108,7 +108,7 @@ class Texture final : public Resource, ...@@ -108,7 +108,7 @@ class Texture final : public Resource,
uint32_t size, uint32_t size,
uint32_t mips /** use zero to create full mipmaps chain */, uint32_t mips /** use zero to create full mipmaps chain */,
bool renderTargetOnly, bool renderTargetOnly,
bool allowTextureView, bool allowFormatView,
TextureRef *refOut); TextureRef *refOut);
static angle::Result Make2DMSTexture(ContextMtl *context, static angle::Result Make2DMSTexture(ContextMtl *context,
...@@ -117,7 +117,7 @@ class Texture final : public Resource, ...@@ -117,7 +117,7 @@ class Texture final : public Resource,
uint32_t height, uint32_t height,
uint32_t samples, uint32_t samples,
bool renderTargetOnly, bool renderTargetOnly,
bool allowTextureView, bool allowFormatView,
TextureRef *refOut); TextureRef *refOut);
static TextureRef MakeFromMetal(id<MTLTexture> metalTexture); static TextureRef MakeFromMetal(id<MTLTexture> metalTexture);
...@@ -125,6 +125,8 @@ class Texture final : public Resource, ...@@ -125,6 +125,8 @@ class Texture final : public Resource,
// Allow CPU to read & write data directly to this texture? // Allow CPU to read & write data directly to this texture?
bool isCPUAccessible() const; bool isCPUAccessible() const;
bool supportFormatView() const;
void replaceRegion(ContextMtl *context, void replaceRegion(ContextMtl *context,
MTLRegion region, MTLRegion region,
uint32_t mipmapLevel, uint32_t mipmapLevel,
...@@ -145,6 +147,9 @@ class Texture final : public Resource, ...@@ -145,6 +147,9 @@ class Texture final : public Resource,
TextureRef createSliceMipView(uint32_t slice, uint32_t level); TextureRef createSliceMipView(uint32_t slice, uint32_t level);
// Create a view with different format // Create a view with different format
TextureRef createViewWithDifferentFormat(MTLPixelFormat format); TextureRef createViewWithDifferentFormat(MTLPixelFormat format);
// 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.
TextureRef createViewWithCompatibleFormat(MTLPixelFormat format);
MTLTextureType textureType() const; MTLTextureType textureType() const;
MTLPixelFormat pixelFormat() const; MTLPixelFormat pixelFormat() const;
...@@ -175,12 +180,20 @@ class Texture final : public Resource, ...@@ -175,12 +180,20 @@ class Texture final : public Resource,
private: private:
using ParentClass = WrappedObject<id<MTLTexture>>; using ParentClass = WrappedObject<id<MTLTexture>>;
static angle::Result MakeTexture(ContextMtl *context,
const Format &mtlFormat,
MTLTextureDescriptor *desc,
uint32_t mips,
bool renderTargetOnly,
bool allowFormatView,
TextureRef *refOut);
Texture(id<MTLTexture> metalTexture); Texture(id<MTLTexture> metalTexture);
Texture(ContextMtl *context, Texture(ContextMtl *context,
MTLTextureDescriptor *desc, MTLTextureDescriptor *desc,
uint32_t mips, uint32_t mips,
bool renderTargetOnly, bool renderTargetOnly,
bool supportTextureView); bool allowFormatView);
// Create a texture view // Create a texture view
Texture(Texture *original, MTLPixelFormat format); Texture(Texture *original, MTLPixelFormat format);
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "libANGLE/renderer/metal/DisplayMtl.h" #include "libANGLE/renderer/metal/DisplayMtl.h"
#include "libANGLE/renderer/metal/mtl_command_buffer.h" #include "libANGLE/renderer/metal/mtl_command_buffer.h"
#include "libANGLE/renderer/metal/mtl_format_utils.h" #include "libANGLE/renderer/metal/mtl_format_utils.h"
#include "libANGLE/renderer/metal/mtl_utils.h"
namespace rx namespace rx
{ {
...@@ -35,21 +36,12 @@ void SetTextureSwizzle(ContextMtl *context, ...@@ -35,21 +36,12 @@ void SetTextureSwizzle(ContextMtl *context,
MTLTextureDescriptor *textureDescOut) MTLTextureDescriptor *textureDescOut)
{ {
// Texture swizzle functions's declarations are only available if macos 10.15 sdk is present // Texture swizzle functions's declarations are only available if macos 10.15 sdk is present
#if defined(__MAC_10_15) #if defined(__IPHONE_13_0) || defined(__MAC_10_15)
if (context->getDisplay()->getFeatures().hasTextureSwizzle.enabled) if (context->getDisplay()->getFeatures().hasTextureSwizzle.enabled && format.swizzled)
{ {
// Work around Metal doesn't have native support for DXT1 without alpha. textureDescOut.swizzle = MTLTextureSwizzleChannelsMake(
switch (format.intendedFormatId) GetTextureSwizzle(format.swizzle[0]), GetTextureSwizzle(format.swizzle[1]),
{ GetTextureSwizzle(format.swizzle[2]), GetTextureSwizzle(format.swizzle[3]));
case angle::FormatID::BC1_RGB_UNORM_BLOCK:
case angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK:
textureDescOut.swizzle =
MTLTextureSwizzleChannelsMake(MTLTextureSwizzleRed, MTLTextureSwizzleGreen,
MTLTextureSwizzleBlue, MTLTextureSwizzleOne);
break;
default:
break;
}
} }
#endif #endif
} }
...@@ -97,7 +89,7 @@ angle::Result Texture::Make2DTexture(ContextMtl *context, ...@@ -97,7 +89,7 @@ angle::Result Texture::Make2DTexture(ContextMtl *context,
uint32_t height, uint32_t height,
uint32_t mips, uint32_t mips,
bool renderTargetOnly, bool renderTargetOnly,
bool allowTextureView, bool allowFormatView,
TextureRef *refOut) TextureRef *refOut)
{ {
ANGLE_MTL_OBJC_SCOPE ANGLE_MTL_OBJC_SCOPE
...@@ -108,16 +100,8 @@ angle::Result Texture::Make2DTexture(ContextMtl *context, ...@@ -108,16 +100,8 @@ angle::Result Texture::Make2DTexture(ContextMtl *context,
height:height height:height
mipmapped:mips == 0 || mips > 1]; mipmapped:mips == 0 || mips > 1];
SetTextureSwizzle(context, format, desc); return MakeTexture(context, format, desc, mips, renderTargetOnly, allowFormatView, refOut);
refOut->reset(new Texture(context, desc, mips, renderTargetOnly, allowTextureView));
} // ANGLE_MTL_OBJC_SCOPE } // ANGLE_MTL_OBJC_SCOPE
if (!refOut || !refOut->get())
{
ANGLE_MTL_CHECK(context, false, GL_OUT_OF_MEMORY);
}
return angle::Result::Continue;
} }
/** static */ /** static */
...@@ -126,7 +110,7 @@ angle::Result Texture::MakeCubeTexture(ContextMtl *context, ...@@ -126,7 +110,7 @@ angle::Result Texture::MakeCubeTexture(ContextMtl *context,
uint32_t size, uint32_t size,
uint32_t mips, uint32_t mips,
bool renderTargetOnly, bool renderTargetOnly,
bool allowTextureView, bool allowFormatView,
TextureRef *refOut) TextureRef *refOut)
{ {
ANGLE_MTL_OBJC_SCOPE ANGLE_MTL_OBJC_SCOPE
...@@ -135,16 +119,9 @@ angle::Result Texture::MakeCubeTexture(ContextMtl *context, ...@@ -135,16 +119,9 @@ angle::Result Texture::MakeCubeTexture(ContextMtl *context,
[MTLTextureDescriptor textureCubeDescriptorWithPixelFormat:format.metalFormat [MTLTextureDescriptor textureCubeDescriptorWithPixelFormat:format.metalFormat
size:size size:size
mipmapped:mips == 0 || mips > 1]; mipmapped:mips == 0 || mips > 1];
SetTextureSwizzle(context, format, desc);
refOut->reset(new Texture(context, desc, mips, renderTargetOnly, allowTextureView));
} // ANGLE_MTL_OBJC_SCOPE
if (!refOut || !refOut->get())
{
ANGLE_MTL_CHECK(context, false, GL_OUT_OF_MEMORY);
}
return angle::Result::Continue; return MakeTexture(context, format, desc, mips, renderTargetOnly, allowFormatView, refOut);
} // ANGLE_MTL_OBJC_SCOPE
} }
/** static */ /** static */
...@@ -154,7 +131,7 @@ angle::Result Texture::Make2DMSTexture(ContextMtl *context, ...@@ -154,7 +131,7 @@ angle::Result Texture::Make2DMSTexture(ContextMtl *context,
uint32_t height, uint32_t height,
uint32_t samples, uint32_t samples,
bool renderTargetOnly, bool renderTargetOnly,
bool allowTextureView, bool allowFormatView,
TextureRef *refOut) TextureRef *refOut)
{ {
ANGLE_MTL_OBJC_SCOPE ANGLE_MTL_OBJC_SCOPE
...@@ -167,14 +144,31 @@ angle::Result Texture::Make2DMSTexture(ContextMtl *context, ...@@ -167,14 +144,31 @@ angle::Result Texture::Make2DMSTexture(ContextMtl *context,
desc.mipmapLevelCount = 1; desc.mipmapLevelCount = 1;
desc.sampleCount = samples; desc.sampleCount = samples;
SetTextureSwizzle(context, format, desc); return MakeTexture(context, format, desc, 1, renderTargetOnly, allowFormatView, refOut);
refOut->reset(new Texture(context, desc, 1, renderTargetOnly, allowTextureView));
} // ANGLE_MTL_OBJC_SCOPE } // ANGLE_MTL_OBJC_SCOPE
}
/** static */
angle::Result Texture::MakeTexture(ContextMtl *context,
const Format &mtlFormat,
MTLTextureDescriptor *desc,
uint32_t mips,
bool renderTargetOnly,
bool allowFormatView,
TextureRef *refOut)
{
SetTextureSwizzle(context, mtlFormat, desc);
refOut->reset(new Texture(context, desc, mips, renderTargetOnly, allowFormatView));
if (!refOut || !refOut->get()) if (!refOut || !refOut->get())
{ {
ANGLE_MTL_CHECK(context, false, GL_OUT_OF_MEMORY); ANGLE_MTL_CHECK(context, false, GL_OUT_OF_MEMORY);
} }
if (!mtlFormat.hasDepthAndStencilBits())
{
refOut->get()->setColorWritableMask(GetEmulatedColorWriteMask(mtlFormat));
}
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -195,7 +189,7 @@ Texture::Texture(ContextMtl *context, ...@@ -195,7 +189,7 @@ Texture::Texture(ContextMtl *context,
MTLTextureDescriptor *desc, MTLTextureDescriptor *desc,
uint32_t mips, uint32_t mips,
bool renderTargetOnly, bool renderTargetOnly,
bool supportTextureView) bool allowFormatView)
: mColorWritableMask(std::make_shared<MTLColorWriteMask>(MTLColorWriteMaskAll)) : mColorWritableMask(std::make_shared<MTLColorWriteMask>(MTLColorWriteMaskAll))
{ {
ANGLE_MTL_OBJC_SCOPE ANGLE_MTL_OBJC_SCOPE
...@@ -210,14 +204,15 @@ Texture::Texture(ContextMtl *context, ...@@ -210,14 +204,15 @@ Texture::Texture(ContextMtl *context,
// Every texture will support being rendered for now // Every texture will support being rendered for now
desc.usage = 0; desc.usage = 0;
if (Format::FormatRenderable(desc.pixelFormat)) if (context->getNativeFormatCaps(desc.pixelFormat).isRenderable())
{ {
desc.usage |= MTLTextureUsageRenderTarget; desc.usage |= MTLTextureUsageRenderTarget;
} }
if (!Format::FormatCPUReadable(desc.pixelFormat) || if (context->getNativeFormatCaps(desc.pixelFormat).depthRenderable ||
desc.textureType == MTLTextureType2DMultisample) desc.textureType == MTLTextureType2DMultisample)
{ {
// Metal doesn't support host access to depth stencil texture's data
desc.resourceOptions = MTLResourceStorageModePrivate; desc.resourceOptions = MTLResourceStorageModePrivate;
} }
...@@ -226,7 +221,7 @@ Texture::Texture(ContextMtl *context, ...@@ -226,7 +221,7 @@ Texture::Texture(ContextMtl *context,
desc.usage = desc.usage | MTLTextureUsageShaderRead; desc.usage = desc.usage | MTLTextureUsageShaderRead;
} }
if (supportTextureView) if (allowFormatView)
{ {
desc.usage = desc.usage | MTLTextureUsagePixelFormatView; desc.usage = desc.usage | MTLTextureUsagePixelFormatView;
} }
...@@ -299,6 +294,11 @@ bool Texture::isCPUAccessible() const ...@@ -299,6 +294,11 @@ bool Texture::isCPUAccessible() const
return get().storageMode == MTLStorageModeShared; return get().storageMode == MTLStorageModeShared;
} }
bool Texture::supportFormatView() const
{
return get().usage & MTLTextureUsagePixelFormatView;
}
void Texture::replaceRegion(ContextMtl *context, void Texture::replaceRegion(ContextMtl *context,
MTLRegion region, MTLRegion region,
uint32_t mipmapLevel, uint32_t mipmapLevel,
...@@ -391,6 +391,12 @@ TextureRef Texture::createSliceMipView(uint32_t slice, uint32_t level) ...@@ -391,6 +391,12 @@ TextureRef Texture::createSliceMipView(uint32_t slice, uint32_t level)
TextureRef Texture::createViewWithDifferentFormat(MTLPixelFormat format) TextureRef Texture::createViewWithDifferentFormat(MTLPixelFormat format)
{ {
ASSERT(supportFormatView());
return TextureRef(new Texture(this, format));
}
TextureRef Texture::createViewWithCompatibleFormat(MTLPixelFormat format)
{
// No need for ASSERT(supportFormatView());
return TextureRef(new Texture(this, format)); return TextureRef(new Texture(this, format));
} }
...@@ -453,10 +459,10 @@ TextureRef Texture::getLinearColorView() ...@@ -453,10 +459,10 @@ TextureRef Texture::getLinearColorView()
switch (pixelFormat()) switch (pixelFormat())
{ {
case MTLPixelFormatRGBA8Unorm_sRGB: case MTLPixelFormatRGBA8Unorm_sRGB:
mLinearColorView = createViewWithDifferentFormat(MTLPixelFormatRGBA8Unorm); mLinearColorView = createViewWithCompatibleFormat(MTLPixelFormatRGBA8Unorm);
break; break;
case MTLPixelFormatBGRA8Unorm_sRGB: case MTLPixelFormatBGRA8Unorm_sRGB:
mLinearColorView = createViewWithDifferentFormat(MTLPixelFormatBGRA8Unorm); mLinearColorView = createViewWithCompatibleFormat(MTLPixelFormatBGRA8Unorm);
break; break;
default: default:
// NOTE(hqle): Not all sRGB formats are supported yet. // NOTE(hqle): Not all sRGB formats are supported yet.
......
...@@ -99,6 +99,10 @@ PrimitiveTopologyClass GetPrimitiveTopologyClass(gl::PrimitiveMode mode); ...@@ -99,6 +99,10 @@ 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)
MTLTextureSwizzle GetTextureSwizzle(GLenum swizzle);
#endif
// Get color write mask for a specified format. Some formats such as RGB565 doesn't have alpha // 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. // 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. // - isFormatEmulated: if the format is emulated, this pointer will store a true value.
......
...@@ -44,36 +44,52 @@ angle::Result InitializeTextureContents(const gl::Context *context, ...@@ -44,36 +44,52 @@ angle::Result InitializeTextureContents(const gl::Context *context,
gl::Extents size = texture->size(index); gl::Extents size = texture->size(index);
// Intialize the content to black // Initialize the content to black
const angle::Format &srcFormat = if (texture->isCPUAccessible() && index.getType() != gl::TextureType::_2DMultisample &&
angle::Format::Get(intendedInternalFormat.alphaBits > 0 ? angle::FormatID::R8G8B8A8_UNORM index.getType() != gl::TextureType::_2DMultisampleArray)
: angle::FormatID::R8G8B8_UNORM);
const size_t srcRowPitch = srcFormat.pixelBytes * size.width;
angle::MemoryBuffer srcRow;
ANGLE_CHECK_GL_ALLOC(contextMtl, srcRow.resize(srcRowPitch));
memset(srcRow.data(), 0, srcRowPitch);
const angle::Format &dstFormat = angle::Format::Get(textureObjFormat.actualFormatId);
const size_t dstRowPitch = dstFormat.pixelBytes * size.width;
angle::MemoryBuffer conversionRow;
ANGLE_CHECK_GL_ALLOC(contextMtl, conversionRow.resize(dstRowPitch));
CopyImageCHROMIUM(srcRow.data(), srcRowPitch, srcFormat.pixelBytes, 0,
srcFormat.pixelReadFunction, conversionRow.data(), dstRowPitch,
dstFormat.pixelBytes, 0, dstFormat.pixelWriteFunction,
intendedInternalFormat.format, dstFormat.componentType, size.width, 1, 1,
false, false, false);
auto mtlRowRegion = MTLRegionMake2D(0, 0, size.width, 1);
for (NSUInteger r = 0; r < static_cast<NSUInteger>(size.height); ++r)
{ {
mtlRowRegion.origin.y = r;
// Upload to texture const angle::Format &dstFormat = angle::Format::Get(textureObjFormat.actualFormatId);
texture->replaceRegion(contextMtl, mtlRowRegion, index.getLevelIndex(), const size_t dstRowPitch = dstFormat.pixelBytes * size.width;
index.hasLayer() ? index.cubeMapFaceIndex() : 0, angle::MemoryBuffer conversionRow;
conversionRow.data(), dstRowPitch); ANGLE_CHECK_GL_ALLOC(contextMtl, conversionRow.resize(dstRowPitch));
if (textureObjFormat.initFunction)
{
textureObjFormat.initFunction(size.width, 1, 1, conversionRow.data(), dstRowPitch, 0);
}
else
{
const angle::Format &srcFormat = angle::Format::Get(
intendedInternalFormat.alphaBits > 0 ? angle::FormatID::R8G8B8A8_UNORM
: angle::FormatID::R8G8B8_UNORM);
const size_t srcRowPitch = srcFormat.pixelBytes * size.width;
angle::MemoryBuffer srcRow;
ANGLE_CHECK_GL_ALLOC(contextMtl, srcRow.resize(srcRowPitch));
memset(srcRow.data(), 0, srcRowPitch);
CopyImageCHROMIUM(srcRow.data(), srcRowPitch, srcFormat.pixelBytes, 0,
srcFormat.pixelReadFunction, conversionRow.data(), dstRowPitch,
dstFormat.pixelBytes, 0, dstFormat.pixelWriteFunction,
intendedInternalFormat.format, dstFormat.componentType, size.width, 1,
1, false, false, false);
}
auto mtlRowRegion = MTLRegionMake2D(0, 0, size.width, 1);
for (NSUInteger r = 0; r < static_cast<NSUInteger>(size.height); ++r)
{
mtlRowRegion.origin.y = r;
// Upload to texture
texture->replaceRegion(contextMtl, mtlRowRegion, index.getLevelIndex(),
index.hasLayer() ? index.cubeMapFaceIndex() : 0,
conversionRow.data(), dstRowPitch);
}
}
else
{
ANGLE_TRY(InitializeTextureContentsGPU(context, texture, index, MTLColorWriteMaskAll));
} }
return angle::Result::Continue; return angle::Result::Continue;
...@@ -476,6 +492,30 @@ MTLIndexType GetIndexType(gl::DrawElementsType type) ...@@ -476,6 +492,30 @@ MTLIndexType GetIndexType(gl::DrawElementsType type)
} }
} }
#if defined(__IPHONE_13_0) || defined(__MAC_10_15)
MTLTextureSwizzle GetTextureSwizzle(GLenum swizzle)
{
switch (swizzle)
{
case GL_RED:
return MTLTextureSwizzleRed;
case GL_GREEN:
return MTLTextureSwizzleGreen;
case GL_BLUE:
return MTLTextureSwizzleBlue;
case GL_ALPHA:
return MTLTextureSwizzleAlpha;
case GL_ZERO:
return MTLTextureSwizzleZero;
case GL_ONE:
return MTLTextureSwizzleOne;
default:
UNREACHABLE();
return MTLTextureSwizzleZero;
}
}
#endif
MTLColorWriteMask GetEmulatedColorWriteMask(const mtl::Format &mtlFormat, bool *isEmulatedOut) MTLColorWriteMask GetEmulatedColorWriteMask(const mtl::Format &mtlFormat, bool *isEmulatedOut)
{ {
const angle::Format &intendedFormat = mtlFormat.intendedAngleFormat(); const angle::Format &intendedFormat = mtlFormat.intendedAngleFormat();
......
...@@ -110,6 +110,47 @@ TEST_P(DXT1CompressedTextureTest, CompressedTexImage) ...@@ -110,6 +110,47 @@ TEST_P(DXT1CompressedTextureTest, CompressedTexImage)
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
// Verify that DXT1 RGB textures have 1.0 alpha when sampled
TEST_P(DXT1CompressedTextureTest, DXT1Alpha)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
// http://anglebug.com/4917
ANGLE_SKIP_TEST_IF(IsD3D());
GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Image using pixels with the code for transparent black:
// "BLACK, if color0 <= color1 and code(x,y) == 3"
constexpr uint8_t CompressedImageDXT1[] = {0, 0, 0, 0, 51, 204, 51, 204};
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
sizeof(CompressedImageDXT1), CompressedImageDXT1);
EXPECT_GL_NO_ERROR();
glUseProgram(mTextureProgram);
glUniform1i(mTextureUniformLocation, 0);
constexpr GLint kDrawSize = 4;
// The image is one 4x4 block, make the viewport only 4x4.
glViewport(0, 0, kDrawSize, kDrawSize);
drawQuad(mTextureProgram, "position", 0.5f);
EXPECT_GL_NO_ERROR();
for (GLint y = 0; y < kDrawSize; y++)
{
for (GLint x = 0; x < kDrawSize; x++)
{
EXPECT_PIXEL_EQ(x, y, 0, 0, 0, 255) << "at (" << x << ", " << y << ")";
}
}
}
TEST_P(DXT1CompressedTextureTest, CompressedTexStorage) TEST_P(DXT1CompressedTextureTest, CompressedTexStorage)
{ {
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1")); ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
......
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