Commit 5b7c5b34 by Le Hoang Quyen Committed by Commit Bot

Metal: don't precompile default shaders.

Default shaders will be compiled from source at runtime, this is because they depend on ANGLE format table and there is currently no way to pre-compile metal shaders in a cross-platform manner. Using default shaders' source instead of pre-compiled form seems to reduce the libGLESv2's binary size. However, the startup time will be increased due to runtime cost of compilation, thus the compilation now will be done asynchronously. Bug: angleproject:5186 Change-Id: I0e1987d6c76692d5169255736fbb8e215185c33b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2482405Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Le Hoang Quyen <le.hoang.q@gmail.com>
parent 9047954c
...@@ -6,49 +6,25 @@ ...@@ -6,49 +6,25 @@
"src/libANGLE/renderer/gen_angle_format_table.py": "src/libANGLE/renderer/gen_angle_format_table.py":
"34ab57bb88958e320f509bd5fbd04495", "34ab57bb88958e320f509bd5fbd04495",
"src/libANGLE/renderer/metal/shaders/blit.metal": "src/libANGLE/renderer/metal/shaders/blit.metal":
"502660301ee21e5cd4a5dd42a8a24e82", "2f6286729703039d41d0f6a109a23ac2",
"src/libANGLE/renderer/metal/shaders/clear.metal": "src/libANGLE/renderer/metal/shaders/clear.metal":
"37ef05208eb5d12110a7d277a4bbcbe1", "37ef05208eb5d12110a7d277a4bbcbe1",
"src/libANGLE/renderer/metal/shaders/common.h": "src/libANGLE/renderer/metal/shaders/common.h":
"0cadef47fb785aa3102acb2a6eae94bb", "ac1bdd21a1cee65d88cfc4e0e61894da",
"src/libANGLE/renderer/metal/shaders/compiled/compiled_default_metallib_2_1_debug_ios_autogen.inc":
"2dfc9dc2496c93fe6c4d46661d77a14b",
"src/libANGLE/renderer/metal/shaders/compiled/compiled_default_metallib_2_1_debug_ios_sim_autogen.inc":
"e4d6ce5e3081e18908b8c95f7ed372b2",
"src/libANGLE/renderer/metal/shaders/compiled/compiled_default_metallib_2_1_debug_mac_autogen.inc":
"79cb485ee377adac2632adaa21e2c8ac",
"src/libANGLE/renderer/metal/shaders/compiled/compiled_default_metallib_2_1_ios_autogen.inc":
"55abd74424bdd88b5523534ec867f715",
"src/libANGLE/renderer/metal/shaders/compiled/compiled_default_metallib_2_1_ios_sim_autogen.inc":
"1cf20c8cb47ed5990c8c165b7faa1c0d",
"src/libANGLE/renderer/metal/shaders/compiled/compiled_default_metallib_2_1_mac_autogen.inc":
"a4b9067e64c6d0dcfcff3422f833779c",
"src/libANGLE/renderer/metal/shaders/compiled/compiled_default_metallib_debug_ios_autogen.inc":
"af51783bbc7dc7d6ad17f88cc5409222",
"src/libANGLE/renderer/metal/shaders/compiled/compiled_default_metallib_debug_ios_sim_autogen.inc":
"25e0ecdaf8829af2ebed1738bf57b2d9",
"src/libANGLE/renderer/metal/shaders/compiled/compiled_default_metallib_debug_mac_autogen.inc":
"34885f0482b73513f1736eb8be340d66",
"src/libANGLE/renderer/metal/shaders/compiled/compiled_default_metallib_ios_autogen.inc":
"f22b1f09a53bc5d1f9a462f4552aa116",
"src/libANGLE/renderer/metal/shaders/compiled/compiled_default_metallib_ios_sim_autogen.inc":
"7de301390d329a1493a557c60ac9888c",
"src/libANGLE/renderer/metal/shaders/compiled/compiled_default_metallib_mac_autogen.inc":
"cd1dbbd9b961aaef467cc24c5c1abcb0",
"src/libANGLE/renderer/metal/shaders/compiled/mtl_default_shaders_autogen.inc":
"634a127f4e94f6bc3123e89850d010ee",
"src/libANGLE/renderer/metal/shaders/constants.h": "src/libANGLE/renderer/metal/shaders/constants.h":
"dad1a869a1095be669b7da5651901d38", "dad1a869a1095be669b7da5651901d38",
"src/libANGLE/renderer/metal/shaders/copy_buffer.metal": "src/libANGLE/renderer/metal/shaders/copy_buffer.metal":
"97b258edbade1ed088e4c03a1102f974", "813e16a38d6e3ba858b62a712b1b316d",
"src/libANGLE/renderer/metal/shaders/format_autogen.h": "src/libANGLE/renderer/metal/shaders/format_autogen.h":
"b1d6512b904a7eb151b0095b7898b0e5", "b1d6512b904a7eb151b0095b7898b0e5",
"src/libANGLE/renderer/metal/shaders/gen_indices.metal": "src/libANGLE/renderer/metal/shaders/gen_indices.metal":
"87a76d5e12825111c0595f69e79f5d20", "add45aa44305b1a64c4bb8ece1e3d2fc",
"src/libANGLE/renderer/metal/shaders/gen_mipmap.metal": "src/libANGLE/renderer/metal/shaders/gen_mipmap.metal":
"54dca94c48bead446624079070b9b309", "54dca94c48bead446624079070b9b309",
"src/libANGLE/renderer/metal/shaders/gen_mtl_internal_shaders.py": "src/libANGLE/renderer/metal/shaders/gen_mtl_internal_shaders.py":
"d5f23d645c0cb9d487e40d490414a772", "9f538745533b6bb14fbbc9e4252f31e0",
"src/libANGLE/renderer/metal/shaders/mtl_default_shaders_src_autogen.inc":
"2a0b015ebec36ee1304ae64a7187abb8",
"src/libANGLE/renderer/metal/shaders/visibility.metal": "src/libANGLE/renderer/metal/shaders/visibility.metal":
"998d705656c63849edd0187cd8062fc7" "b82aa740cf4b0aed606aacef1024beea"
} }
\ No newline at end of file
...@@ -62,21 +62,9 @@ _metal_backend_sources = [ ...@@ -62,21 +62,9 @@ _metal_backend_sources = [
"mtl_state_cache.mm", "mtl_state_cache.mm",
"mtl_utils.h", "mtl_utils.h",
"mtl_utils.mm", "mtl_utils.mm",
"shaders/compiled/compiled_default_metallib_2_1_debug_ios_autogen.inc",
"shaders/compiled/compiled_default_metallib_2_1_debug_ios_sim_autogen.inc",
"shaders/compiled/compiled_default_metallib_2_1_debug_mac_autogen.inc",
"shaders/compiled/compiled_default_metallib_2_1_ios_autogen.inc",
"shaders/compiled/compiled_default_metallib_2_1_ios_sim_autogen.inc",
"shaders/compiled/compiled_default_metallib_2_1_mac_autogen.inc",
"shaders/compiled/compiled_default_metallib_debug_ios_autogen.inc",
"shaders/compiled/compiled_default_metallib_debug_ios_sim_autogen.inc",
"shaders/compiled/compiled_default_metallib_debug_mac_autogen.inc",
"shaders/compiled/compiled_default_metallib_ios_autogen.inc",
"shaders/compiled/compiled_default_metallib_ios_sim_autogen.inc",
"shaders/compiled/compiled_default_metallib_mac_autogen.inc",
"shaders/compiled/mtl_default_shaders_autogen.inc",
"shaders/constants.h", "shaders/constants.h",
"shaders/format_autogen.h", "shaders/format_autogen.h",
"shaders/mtl_default_shaders_src_autogen.inc",
] ]
config("angle_metal_backend_config") { config("angle_metal_backend_config") {
......
...@@ -32,6 +32,8 @@ class ShareGroupMtl : public ShareGroupImpl ...@@ -32,6 +32,8 @@ class ShareGroupMtl : public ShareGroupImpl
class ContextMtl; class ContextMtl;
struct DefaultShaderAsyncInfoMtl;
class DisplayMtl : public DisplayImpl class DisplayMtl : public DisplayImpl
{ {
public: public:
...@@ -123,7 +125,7 @@ class DisplayMtl : public DisplayImpl ...@@ -123,7 +125,7 @@ class DisplayMtl : public DisplayImpl
mtl::RenderUtils &getUtils() { return mUtils; } mtl::RenderUtils &getUtils() { return mUtils; }
mtl::StateCache &getStateCache() { return mStateCache; } mtl::StateCache &getStateCache() { return mStateCache; }
id<MTLLibrary> getDefaultShadersLib() const { return mDefaultShaders; } id<MTLLibrary> getDefaultShadersLib();
id<MTLDepthStencilState> getDepthStencilState(const mtl::DepthStencilDesc &desc) id<MTLDepthStencilState> getDepthStencilState(const mtl::DepthStencilDesc &desc)
{ {
...@@ -175,7 +177,7 @@ class DisplayMtl : public DisplayImpl ...@@ -175,7 +177,7 @@ class DisplayMtl : public DisplayImpl
mtl::RenderUtils mUtils; mtl::RenderUtils mUtils;
// Built-in Shaders // Built-in Shaders
mtl::AutoObjCPtr<id<MTLLibrary>> mDefaultShaders = nil; std::shared_ptr<DefaultShaderAsyncInfoMtl> mDefaultShadersAsyncInfo;
#if ANGLE_MTL_EVENT_AVAILABLE #if ANGLE_MTL_EVENT_AVAILABLE
mtl::AutoObjCObj<MTLSharedEventListener> mSharedEventListener; mtl::AutoObjCObj<MTLSharedEventListener> mSharedEventListener;
#endif #endif
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include "libANGLE/renderer/metal/SurfaceMtl.h" #include "libANGLE/renderer/metal/SurfaceMtl.h"
#include "libANGLE/renderer/metal/SyncMtl.h" #include "libANGLE/renderer/metal/SyncMtl.h"
#include "libANGLE/renderer/metal/mtl_common.h" #include "libANGLE/renderer/metal/mtl_common.h"
#include "libANGLE/renderer/metal/shaders/compiled/mtl_default_shaders_autogen.inc" #include "libANGLE/renderer/metal/shaders/mtl_default_shaders_src_autogen.inc"
#include "platform/Platform.h" #include "platform/Platform.h"
#include "EGL/eglext.h" #include "EGL/eglext.h"
...@@ -44,6 +44,18 @@ DisplayImpl *CreateMetalDisplay(const egl::DisplayState &state) ...@@ -44,6 +44,18 @@ DisplayImpl *CreateMetalDisplay(const egl::DisplayState &state)
return new DisplayMtl(state); return new DisplayMtl(state);
} }
struct DefaultShaderAsyncInfoMtl
{
mtl::AutoObjCPtr<id<MTLLibrary>> defaultShaders;
mtl::AutoObjCPtr<NSError *> defaultShadersCompileError;
// Synchronization primitives for compiling default shaders in back-ground
std::condition_variable cv;
std::mutex lock;
bool compiled = false;
};
DisplayMtl::DisplayMtl(const egl::DisplayState &state) DisplayMtl::DisplayMtl(const egl::DisplayState &state)
: DisplayImpl(state), mUtils(this), mGlslangInitialized(false) : DisplayImpl(state), mUtils(this), mGlslangInitialized(false)
{} {}
...@@ -100,8 +112,8 @@ void DisplayMtl::terminate() ...@@ -100,8 +112,8 @@ void DisplayMtl::terminate()
{ {
mUtils.onDestroy(); mUtils.onDestroy();
mCmdQueue.reset(); mCmdQueue.reset();
mDefaultShaders = nil; mDefaultShadersAsyncInfo = nullptr;
mMetalDevice = nil; mMetalDevice = nil;
#if ANGLE_MTL_EVENT_AVAILABLE #if ANGLE_MTL_EVENT_AVAILABLE
mSharedEventListener = nil; mSharedEventListener = nil;
#endif #endif
...@@ -751,48 +763,62 @@ void DisplayMtl::initializeFeatures() ...@@ -751,48 +763,62 @@ void DisplayMtl::initializeFeatures()
angle::Result DisplayMtl::initializeShaderLibrary() angle::Result DisplayMtl::initializeShaderLibrary()
{ {
mtl::AutoObjCObj<NSError> err = nil; mDefaultShadersAsyncInfo.reset(new DefaultShaderAsyncInfoMtl);
const uint8_t *compiled_shader_binary; // Create references to async info struct since it might be released in terminate(), but the
size_t compiled_shader_binary_len; // callback might still not be fired yet.
std::shared_ptr<DefaultShaderAsyncInfoMtl> asyncRef = mDefaultShadersAsyncInfo;
#if !defined(NDEBUG) // Compile the default shaders asynchronously
if (getFeatures().hasStencilOutput.enabled) ANGLE_MTL_OBJC_SCOPE
{
compiled_shader_binary = compiled_default_metallib_2_1_debug;
compiled_shader_binary_len = compiled_default_metallib_2_1_debug_len;
}
else
{
compiled_shader_binary = compiled_default_metallib_debug;
compiled_shader_binary_len = compiled_default_metallib_debug_len;
}
#else
if (getFeatures().hasStencilOutput.enabled)
{ {
compiled_shader_binary = compiled_default_metallib_2_1; auto nsSource = [[NSString alloc] initWithBytesNoCopy:gDefaultMetallibSrc
compiled_shader_binary_len = compiled_default_metallib_2_1_len; length:sizeof(gDefaultMetallibSrc)
encoding:NSUTF8StringEncoding
freeWhenDone:NO];
auto options = [[[MTLCompileOptions alloc] init] ANGLE_MTL_AUTORELEASE];
[getMetalDevice() newLibraryWithSource:nsSource
options:options
completionHandler:^(id<MTLLibrary> library, NSError *error) {
std::unique_lock<std::mutex> lg(asyncRef->lock);
asyncRef->defaultShaders = std::move(library);
asyncRef->defaultShadersCompileError = std::move(error);
asyncRef->compiled = true;
asyncRef->cv.notify_one();
}];
[nsSource ANGLE_MTL_AUTORELEASE];
} }
else
return angle::Result::Continue;
}
id<MTLLibrary> DisplayMtl::getDefaultShadersLib()
{
std::unique_lock<std::mutex> lg(mDefaultShadersAsyncInfo->lock);
if (!mDefaultShadersAsyncInfo->compiled)
{ {
compiled_shader_binary = compiled_default_metallib; // Wait for async compilation
compiled_shader_binary_len = compiled_default_metallib_len; mDefaultShadersAsyncInfo->cv.wait(lg,
[this] { return mDefaultShadersAsyncInfo->compiled; });
} }
#endif
mDefaultShaders = CreateShaderLibraryFromBinary(getMetalDevice(), compiled_shader_binary, if (mDefaultShadersAsyncInfo->defaultShadersCompileError &&
compiled_shader_binary_len, &err); !mDefaultShadersAsyncInfo->defaultShaders)
if (err && !mDefaultShaders)
{ {
ANGLE_MTL_OBJC_SCOPE ANGLE_MTL_OBJC_SCOPE
{ {
ERR() << "Internal error: " << err.get().localizedDescription.UTF8String; ERR() << "Internal error: "
<< mDefaultShadersAsyncInfo->defaultShadersCompileError.get()
.localizedDescription.UTF8String;
} }
return angle::Result::Stop; // This is not supposed to happen
UNREACHABLE();
} }
return angle::Result::Continue; return mDefaultShadersAsyncInfo->defaultShaders;
} }
bool DisplayMtl::supportsIOSGPUFamily(uint8_t iOSFamily) const bool DisplayMtl::supportsIOSGPUFamily(uint8_t iOSFamily) const
......
...@@ -334,7 +334,7 @@ kernel void blitStencilToBufferCS(ushort2 gIndices [[thread_position_in_grid]], ...@@ -334,7 +334,7 @@ kernel void blitStencilToBufferCS(ushort2 gIndices [[thread_position_in_grid]],
} }
// Fragment's stencil output is only available since Metal 2.1 // Fragment's stencil output is only available since Metal 2.1
#if __METAL_VERSION__ >= 210 @@#if __METAL_VERSION__ >= 210
struct FragmentStencilOut struct FragmentStencilOut
{ {
...@@ -397,4 +397,4 @@ fragment FragmentDepthStencilOut blitDepthStencilFS( ...@@ -397,4 +397,4 @@ fragment FragmentDepthStencilOut blitDepthStencilFS(
srcStencilTextureCube, input.texCoords, options.srcLevel, options.srcLayer); srcStencilTextureCube, input.texCoords, options.srcLevel, options.srcLayer);
return re; return re;
} }
#endif // __METAL_VERSION__ >= 210 @@#endif // __METAL_VERSION__ >= 210
...@@ -8,9 +8,10 @@ ...@@ -8,9 +8,10 @@
#ifndef LIBANGLE_RENDERER_METAL_SHADERS_COMMON_H_ #ifndef LIBANGLE_RENDERER_METAL_SHADERS_COMMON_H_
#define LIBANGLE_RENDERER_METAL_SHADERS_COMMON_H_ #define LIBANGLE_RENDERER_METAL_SHADERS_COMMON_H_
// clang-format off
#ifndef SKIP_STD_HEADERS #ifndef SKIP_STD_HEADERS
# include <simd/simd.h> @@# include <simd/simd.h>
# include <metal_stdlib> @@# include <metal_stdlib>
#endif #endif
#include "constants.h" #include "constants.h"
...@@ -22,6 +23,7 @@ ...@@ -22,6 +23,7 @@
} }
using namespace metal; using namespace metal;
// clang-format on
// Common constant defined number of color outputs // Common constant defined number of color outputs
constant uint32_t kNumColorOutputs [[function_constant(0)]]; constant uint32_t kNumColorOutputs [[function_constant(0)]];
......
...@@ -9,17 +9,17 @@ ...@@ -9,17 +9,17 @@
// be a pain to implement without the use of macros. // be a pain to implement without the use of macros.
// //
#include <metal_pack> @@#include <metal_pack>
#include "common.h" #include "common.h"
#include "format_autogen.h" #include "format_autogen.h"
using namespace rx::mtl_shader; using namespace rx::mtl_shader;
constant int kCopyFormatType [[function_constant(1)]]; constant int kCopyFormatType [[function_constant(10)]];
/* -------- copy pixel data between buffer and texture ---------*/ /* -------- copy pixel data between buffer and texture ---------*/
constant int kCopyTextureType [[function_constant(2)]]; constant int kCopyTextureType [[function_constant(20)]];
constant bool kCopyTextureType2D = kCopyTextureType == kTextureType2D; constant bool kCopyTextureType2D = kCopyTextureType == kTextureType2D;
constant bool kCopyTextureType2DArray = kCopyTextureType == kTextureType2DArray; constant bool kCopyTextureType2DArray = kCopyTextureType == kTextureType2DArray;
constant bool kCopyTextureType2DMS = kCopyTextureType == kTextureType2DMultisample; constant bool kCopyTextureType2DMS = kCopyTextureType == kTextureType2DMultisample;
......
...@@ -9,10 +9,10 @@ ...@@ -9,10 +9,10 @@
using namespace rx::mtl_shader; using namespace rx::mtl_shader;
// function_constant(0) is already used by common.h // function_constant(0) is already used by common.h
constant bool kSourceBufferAligned[[function_constant(1)]]; constant bool kSourceBufferAligned[[function_constant(100)]];
constant bool kSourceIndexIsU8[[function_constant(2)]]; constant bool kSourceIndexIsU8[[function_constant(200)]];
constant bool kSourceIndexIsU16[[function_constant(3)]]; constant bool kSourceIndexIsU16[[function_constant(300)]];
constant bool kSourceIndexIsU32[[function_constant(4)]]; constant bool kSourceIndexIsU32[[function_constant(400)]];
constant bool kSourceBufferUnaligned = !kSourceBufferAligned; constant bool kSourceBufferUnaligned = !kSourceBufferAligned;
constant bool kUseSourceBufferU8 = kSourceIndexIsU8 || kSourceBufferUnaligned; constant bool kUseSourceBufferU8 = kSourceIndexIsU8 || kSourceBufferUnaligned;
constant bool kUseSourceBufferU16 = kSourceIndexIsU16 && kSourceBufferAligned; constant bool kUseSourceBufferU16 = kSourceIndexIsU16 && kSourceBufferAligned;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include "common.h" #include "common.h"
constant bool kCombineWithExistingResult [[function_constant(1)]]; constant bool kCombineWithExistingResult [[function_constant(1000)]];
// Combine the visibility result of current render pass with previous value from previous render // Combine the visibility result of current render pass with previous value from previous render
// pass // pass
......
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