Hash :
5a77200b
Author :
Date :
2023-02-08T17:10:28
Metal: Implement parallel shader linking. Update the Metal library cache to be thread safe. Change absl::flat_hash_map back to std::unordered_map because the value types now contain a mutex which must not move. Only generate async compilation tasks for shaders that were not already compiled and in the cache. Collapse some of the link methods in ProgramMtl that only had one call site. All linking is now done in ProgramMtl::link and ProgramMtl::load. Support disabling parallel linking using the new enableParallelMtlLibraryCompilation feature. Bug: chromium:1385510 Change-Id: I71ba71a34d994066729df7e4170911f88c89de4a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4234153 Reviewed-by: Quyen Le <lehoangquyen@chromium.org> Reviewed-by: Jonah Ryan-Davis <jonahr@google.com> Commit-Queue: Geoff Lang <geofflang@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
//
// Copyright 2023 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// mtl_library_cache.h:
// Defines classes for caching of mtl libraries
//
#ifndef LIBANGLE_RENDERER_METAL_MTL_LIBRARY_CACHE_H_
#define LIBANGLE_RENDERER_METAL_MTL_LIBRARY_CACHE_H_
#include "libANGLE/renderer/metal/mtl_utils.h"
#include <type_traits>
namespace rx
{
namespace mtl
{
class LibraryCache
{
public:
LibraryCache() = default;
~LibraryCache() = default;
AutoObjCPtr<id<MTLLibrary>> get(const std::string &source,
const std::map<std::string, std::string> ¯os,
bool enableFastMath);
AutoObjCPtr<id<MTLLibrary>> getOrCompileShaderLibrary(
ContextMtl *context,
const std::string &source,
const std::map<std::string, std::string> ¯os,
bool enableFastMath,
AutoObjCPtr<NSError *> *errorOut);
private:
struct LibraryKey
{
std::string source;
std::map<std::string, std::string> macros;
bool enableFastMath;
using LValueTuple = decltype(std::tie(std::as_const(source),
std::as_const(macros),
std::as_const(enableFastMath)));
LibraryKey() = default;
explicit LibraryKey(const LValueTuple &fromTuple);
LValueTuple tie() const;
};
struct LibraryKeyCompare
{
// Mark this comparator as transparent. This allows types that are not LibraryKey to be used
// as a key for unordered_map::find. We can avoid the construction of a LibraryKey (which
// copies std::strings) when searching the cache.
using is_transparent = void;
// Hash functions for keys and lvalue tuples of keys
size_t operator()(const LibraryKey::LValueTuple &k) const;
size_t operator()(const LibraryKey &k) const;
// Comparison operators for all key/lvalue combinations need by a map
bool operator()(const LibraryKey &a, const LibraryKey &b) const;
bool operator()(const LibraryKey &a, const LibraryKey::LValueTuple &b) const;
bool operator()(const LibraryKey::LValueTuple &a, const LibraryKey &b) const;
};
struct LibraryCacheEntry
{
LibraryCacheEntry() = default;
// library can only go from the null -> not null state. It is safe to check if the library
// already exists without locking.
AutoObjCPtr<id<MTLLibrary>> library;
// Lock for this specific library to avoid multiple threads compiling the same shader at
// once.
std::mutex lock;
};
LibraryCacheEntry &getCacheEntry(const LibraryKey::LValueTuple &lValueKey);
// Lock for searching and adding new entries to the cache
std::mutex mCacheLock;
using CacheMap =
std::unordered_map<LibraryKey, LibraryCacheEntry, LibraryKeyCompare, LibraryKeyCompare>;
CacheMap mCache;
};
} // namespace mtl
} // namespace rx
#endif // LIBANGLE_RENDERER_METAL_MTL_LIBRARY_CACHE_H_