diff options
Diffstat (limited to '')
-rw-r--r-- | gfx/angle/checkout/src/common/angleutils.h | 601 |
1 files changed, 601 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/common/angleutils.h b/gfx/angle/checkout/src/common/angleutils.h new file mode 100644 index 0000000000..bcbcabc782 --- /dev/null +++ b/gfx/angle/checkout/src/common/angleutils.h @@ -0,0 +1,601 @@ +// +// Copyright 2002 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. +// + +// angleutils.h: Common ANGLE utilities. + +#ifndef COMMON_ANGLEUTILS_H_ +#define COMMON_ANGLEUTILS_H_ + +#include "common/platform.h" + +#if defined(ANGLE_USE_ABSEIL) +# include "absl/container/flat_hash_map.h" +# include "absl/container/flat_hash_set.h" +#endif // defined(ANGLE_USE_ABSEIL) + +#if defined(ANGLE_WITH_LSAN) +# include <sanitizer/lsan_interface.h> +#endif // defined(ANGLE_WITH_LSAN) + +#include <climits> +#include <cstdarg> +#include <cstddef> +#include <fstream> +#include <mutex> +#include <set> +#include <sstream> +#include <string> +#include <unordered_map> +#include <unordered_set> +#include <vector> + +// A helper class to disallow copy and assignment operators +namespace angle +{ + +#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) +using Microsoft::WRL::ComPtr; +#endif // defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) + +#if defined(ANGLE_USE_ABSEIL) +template <typename Key, typename T, class Hash = absl::container_internal::hash_default_hash<Key>> +using HashMap = absl::flat_hash_map<Key, T, Hash>; +template <typename Key, class Hash = absl::container_internal::hash_default_hash<Key>> +using HashSet = absl::flat_hash_set<Key, Hash>; +#else +template <typename Key, typename T, class Hash = std::hash<Key>> +using HashMap = std::unordered_map<Key, T, Hash>; +template <typename Key, class Hash = std::hash<Key>> +using HashSet = std::unordered_set<Key, Hash>; +#endif // defined(ANGLE_USE_ABSEIL) + +class NonCopyable +{ + protected: + constexpr NonCopyable() = default; + ~NonCopyable() = default; + + private: + NonCopyable(const NonCopyable &) = delete; + void operator=(const NonCopyable &) = delete; +}; + +extern const uintptr_t DirtyPointer; + +struct SaveFileHelper +{ + public: + // We always use ios::binary to avoid inconsistent line endings when captured on Linux vs Win. + SaveFileHelper(const std::string &filePathIn); + ~SaveFileHelper(); + + template <typename T> + SaveFileHelper &operator<<(const T &value) + { + mOfs << value; + checkError(); + return *this; + } + + void write(const uint8_t *data, size_t size); + + private: + void checkError(); + + std::ofstream mOfs; + std::string mFilePath; +}; + +// AMD_performance_monitor helpers. +constexpr char kPerfMonitorExtensionName[] = "GL_AMD_performance_monitor"; + +struct PerfMonitorCounter +{ + PerfMonitorCounter(); + ~PerfMonitorCounter(); + + std::string name; + uint64_t value; +}; +using PerfMonitorCounters = std::vector<PerfMonitorCounter>; + +struct PerfMonitorCounterGroup +{ + PerfMonitorCounterGroup(); + ~PerfMonitorCounterGroup(); + + std::string name; + PerfMonitorCounters counters; +}; +using PerfMonitorCounterGroups = std::vector<PerfMonitorCounterGroup>; + +uint32_t GetPerfMonitorCounterIndex(const PerfMonitorCounters &counters, const std::string &name); +const PerfMonitorCounter &GetPerfMonitorCounter(const PerfMonitorCounters &counters, + const std::string &name); +PerfMonitorCounter &GetPerfMonitorCounter(PerfMonitorCounters &counters, const std::string &name); +uint32_t GetPerfMonitorCounterGroupIndex(const PerfMonitorCounterGroups &groups, + const std::string &name); +const PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(const PerfMonitorCounterGroups &groups, + const std::string &name); +PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(PerfMonitorCounterGroups &groups, + const std::string &name); + +struct PerfMonitorTriplet +{ + uint32_t group; + uint32_t counter; + uint64_t value; +}; + +#define ANGLE_VK_PERF_COUNTERS_X(FN) \ + FN(commandQueueSubmitCallsTotal) \ + FN(commandQueueSubmitCallsPerFrame) \ + FN(vkQueueSubmitCallsTotal) \ + FN(vkQueueSubmitCallsPerFrame) \ + FN(renderPasses) \ + FN(writeDescriptorSets) \ + FN(flushedOutsideRenderPassCommandBuffers) \ + FN(swapchainResolveInSubpass) \ + FN(swapchainResolveOutsideSubpass) \ + FN(resolveImageCommands) \ + FN(colorLoadOpClears) \ + FN(colorLoadOpLoads) \ + FN(colorLoadOpNones) \ + FN(colorStoreOpStores) \ + FN(colorStoreOpNones) \ + FN(colorClearAttachments) \ + FN(depthLoadOpClears) \ + FN(depthLoadOpLoads) \ + FN(depthLoadOpNones) \ + FN(depthStoreOpStores) \ + FN(depthStoreOpNones) \ + FN(depthClearAttachments) \ + FN(stencilLoadOpClears) \ + FN(stencilLoadOpLoads) \ + FN(stencilLoadOpNones) \ + FN(stencilStoreOpStores) \ + FN(stencilStoreOpNones) \ + FN(stencilClearAttachments) \ + FN(colorAttachmentUnresolves) \ + FN(depthAttachmentUnresolves) \ + FN(stencilAttachmentUnresolves) \ + FN(colorAttachmentResolves) \ + FN(depthAttachmentResolves) \ + FN(stencilAttachmentResolves) \ + FN(readOnlyDepthStencilRenderPasses) \ + FN(pipelineCreationCacheHits) \ + FN(pipelineCreationCacheMisses) \ + FN(pipelineCreationTotalCacheHitsDurationNs) \ + FN(pipelineCreationTotalCacheMissesDurationNs) \ + FN(descriptorSetAllocations) \ + FN(descriptorSetCacheTotalSize) \ + FN(descriptorSetCacheKeySizeBytes) \ + FN(uniformsAndXfbDescriptorSetCacheHits) \ + FN(uniformsAndXfbDescriptorSetCacheMisses) \ + FN(uniformsAndXfbDescriptorSetCacheTotalSize) \ + FN(textureDescriptorSetCacheHits) \ + FN(textureDescriptorSetCacheMisses) \ + FN(textureDescriptorSetCacheTotalSize) \ + FN(shaderResourcesDescriptorSetCacheHits) \ + FN(mutableTexturesUploaded) \ + FN(shaderResourcesDescriptorSetCacheMisses) \ + FN(shaderResourcesDescriptorSetCacheTotalSize) \ + FN(buffersGhosted) \ + FN(vertexArraySyncStateCalls) \ + FN(allocateNewBufferBlockCalls) \ + FN(dynamicBufferAllocations) \ + FN(framebufferCacheSize) + +#define ANGLE_DECLARE_PERF_COUNTER(COUNTER) uint64_t COUNTER; + +struct VulkanPerfCounters +{ + ANGLE_VK_PERF_COUNTERS_X(ANGLE_DECLARE_PERF_COUNTER) +}; + +#undef ANGLE_DECLARE_PERF_COUNTER + +} // namespace angle + +template <typename T, size_t N> +constexpr inline size_t ArraySize(T (&)[N]) +{ + return N; +} + +template <typename T> +class WrappedArray final : angle::NonCopyable +{ + public: + template <size_t N> + constexpr WrappedArray(const T (&data)[N]) : mArray(&data[0]), mSize(N) + {} + + constexpr WrappedArray() : mArray(nullptr), mSize(0) {} + constexpr WrappedArray(const T *data, size_t size) : mArray(data), mSize(size) {} + + WrappedArray(WrappedArray &&other) : WrappedArray() + { + std::swap(mArray, other.mArray); + std::swap(mSize, other.mSize); + } + + ~WrappedArray() {} + + constexpr const T *get() const { return mArray; } + constexpr size_t size() const { return mSize; } + + private: + const T *mArray; + size_t mSize; +}; + +template <typename T, unsigned int N> +void SafeRelease(T (&resourceBlock)[N]) +{ + for (unsigned int i = 0; i < N; i++) + { + SafeRelease(resourceBlock[i]); + } +} + +template <typename T> +void SafeRelease(T &resource) +{ + if (resource) + { + resource->Release(); + resource = nullptr; + } +} + +template <typename T> +void SafeDelete(T *&resource) +{ + delete resource; + resource = nullptr; +} + +template <typename T> +void SafeDeleteContainer(T &resource) +{ + for (auto &element : resource) + { + SafeDelete(element); + } + resource.clear(); +} + +template <typename T> +void SafeDeleteArray(T *&resource) +{ + delete[] resource; + resource = nullptr; +} + +// Provide a less-than function for comparing structs +// Note: struct memory must be initialized to zero, because of packing gaps +template <typename T> +inline bool StructLessThan(const T &a, const T &b) +{ + return (memcmp(&a, &b, sizeof(T)) < 0); +} + +// Provide a less-than function for comparing structs +// Note: struct memory must be initialized to zero, because of packing gaps +template <typename T> +inline bool StructEquals(const T &a, const T &b) +{ + return (memcmp(&a, &b, sizeof(T)) == 0); +} + +template <typename T> +inline void StructZero(T *obj) +{ + memset(obj, 0, sizeof(T)); +} + +template <typename T> +inline bool IsMaskFlagSet(T mask, T flag) +{ + // Handles multibit flags as well + return (mask & flag) == flag; +} + +inline const char *MakeStaticString(const std::string &str) +{ + // On the heap so that no destructor runs on application exit. + static std::set<std::string> *strings = new std::set<std::string>; + std::set<std::string>::iterator it = strings->find(str); + if (it != strings->end()) + { + return it->c_str(); + } + + return strings->insert(str).first->c_str(); +} + +std::string ArrayString(unsigned int i); + +// Indices are stored in vectors with the outermost index in the back. In the output of the function +// the indices are reversed. +std::string ArrayIndexString(const std::vector<unsigned int> &indices); + +inline std::string Str(int i) +{ + std::stringstream strstr; + strstr << i; + return strstr.str(); +} + +template <typename T> +std::string ToString(const T &value) +{ + std::ostringstream o; + o << value; + return o.str(); +} + +inline bool IsLittleEndian() +{ + constexpr uint32_t kEndiannessTest = 1; + const bool isLittleEndian = *reinterpret_cast<const uint8_t *>(&kEndiannessTest) == 1; + return isLittleEndian; +} + +// Helper class to use a mutex with the control of boolean. +class ConditionalMutex final : angle::NonCopyable +{ + public: + ConditionalMutex() : mUseMutex(true) {} + void init(bool useMutex) { mUseMutex = useMutex; } + void lock() + { + if (mUseMutex) + { + mMutex.lock(); + } + } + void unlock() + { + if (mUseMutex) + { + mMutex.unlock(); + } + } + + private: + std::mutex mMutex; + bool mUseMutex; +}; + +// snprintf is not defined with MSVC prior to to msvc14 +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +#define GL_A1RGB5_ANGLEX 0x6AC5 +#define GL_BGRX8_ANGLEX 0x6ABA +#define GL_BGR565_ANGLEX 0x6ABB +#define GL_BGRA4_ANGLEX 0x6ABC +#define GL_BGR5_A1_ANGLEX 0x6ABD +#define GL_INT_64_ANGLEX 0x6ABE +#define GL_UINT_64_ANGLEX 0x6ABF +#define GL_BGRA8_SRGB_ANGLEX 0x6AC0 +#define GL_BGR10_A2_ANGLEX 0x6AF9 + +// These are fake formats used to fit typeless D3D textures that can be bound to EGL pbuffers into +// the format system (for extension EGL_ANGLE_d3d_texture_client_buffer): +#define GL_RGBA8_TYPELESS_ANGLEX 0x6AC1 +#define GL_RGBA8_TYPELESS_SRGB_ANGLEX 0x6AC2 +#define GL_BGRA8_TYPELESS_ANGLEX 0x6AC3 +#define GL_BGRA8_TYPELESS_SRGB_ANGLEX 0x6AC4 + +#define GL_R8_SSCALED_ANGLEX 0x6AC6 +#define GL_RG8_SSCALED_ANGLEX 0x6AC7 +#define GL_RGB8_SSCALED_ANGLEX 0x6AC8 +#define GL_RGBA8_SSCALED_ANGLEX 0x6AC9 +#define GL_R8_USCALED_ANGLEX 0x6ACA +#define GL_RG8_USCALED_ANGLEX 0x6ACB +#define GL_RGB8_USCALED_ANGLEX 0x6ACC +#define GL_RGBA8_USCALED_ANGLEX 0x6ACD + +#define GL_R16_SSCALED_ANGLEX 0x6ACE +#define GL_RG16_SSCALED_ANGLEX 0x6ACF +#define GL_RGB16_SSCALED_ANGLEX 0x6AD0 +#define GL_RGBA16_SSCALED_ANGLEX 0x6AD1 +#define GL_R16_USCALED_ANGLEX 0x6AD2 +#define GL_RG16_USCALED_ANGLEX 0x6AD3 +#define GL_RGB16_USCALED_ANGLEX 0x6AD4 +#define GL_RGBA16_USCALED_ANGLEX 0x6AD5 + +#define GL_R32_SSCALED_ANGLEX 0x6AD6 +#define GL_RG32_SSCALED_ANGLEX 0x6AD7 +#define GL_RGB32_SSCALED_ANGLEX 0x6AD8 +#define GL_RGBA32_SSCALED_ANGLEX 0x6AD9 +#define GL_R32_USCALED_ANGLEX 0x6ADA +#define GL_RG32_USCALED_ANGLEX 0x6ADB +#define GL_RGB32_USCALED_ANGLEX 0x6ADC +#define GL_RGBA32_USCALED_ANGLEX 0x6ADD + +#define GL_R32_SNORM_ANGLEX 0x6ADE +#define GL_RG32_SNORM_ANGLEX 0x6ADF +#define GL_RGB32_SNORM_ANGLEX 0x6AE0 +#define GL_RGBA32_SNORM_ANGLEX 0x6AE1 +#define GL_R32_UNORM_ANGLEX 0x6AE2 +#define GL_RG32_UNORM_ANGLEX 0x6AE3 +#define GL_RGB32_UNORM_ANGLEX 0x6AE4 +#define GL_RGBA32_UNORM_ANGLEX 0x6AE5 + +#define GL_R32_FIXED_ANGLEX 0x6AE6 +#define GL_RG32_FIXED_ANGLEX 0x6AE7 +#define GL_RGB32_FIXED_ANGLEX 0x6AE8 +#define GL_RGBA32_FIXED_ANGLEX 0x6AE9 + +#define GL_RGB10_A2_SINT_ANGLEX 0x6AEA +#define GL_RGB10_A2_SNORM_ANGLEX 0x6AEB +#define GL_RGB10_A2_SSCALED_ANGLEX 0x6AEC +#define GL_RGB10_A2_USCALED_ANGLEX 0x6AED + +// EXT_texture_type_2_10_10_10_REV +#define GL_RGB10_UNORM_ANGLEX 0x6AEE + +// These are fake formats for OES_vertex_type_10_10_10_2 +#define GL_A2_RGB10_UNORM_ANGLEX 0x6AEF +#define GL_A2_RGB10_SNORM_ANGLEX 0x6AF0 +#define GL_A2_RGB10_USCALED_ANGLEX 0x6AF1 +#define GL_A2_RGB10_SSCALED_ANGLEX 0x6AF2 +#define GL_X2_RGB10_UINT_ANGLEX 0x6AF3 +#define GL_X2_RGB10_SINT_ANGLEX 0x6AF4 +#define GL_X2_RGB10_USCALED_ANGLEX 0x6AF5 +#define GL_X2_RGB10_SSCALED_ANGLEX 0x6AF6 +#define GL_X2_RGB10_UNORM_ANGLEX 0x6AF7 +#define GL_X2_RGB10_SNORM_ANGLEX 0x6AF8 + +#define ANGLE_CHECK_GL_ALLOC(context, result) \ + ANGLE_CHECK(context, result, "Failed to allocate host memory", GL_OUT_OF_MEMORY) + +#define ANGLE_CHECK_GL_MATH(context, result) \ + ANGLE_CHECK(context, result, "Integer overflow.", GL_INVALID_OPERATION) + +#define ANGLE_GL_UNREACHABLE(context) \ + UNREACHABLE(); \ + ANGLE_CHECK(context, false, "Unreachable Code.", GL_INVALID_OPERATION) + +#if defined(ANGLE_WITH_LSAN) +# define ANGLE_SCOPED_DISABLE_LSAN() __lsan::ScopedDisabler lsanDisabler +#else +# define ANGLE_SCOPED_DISABLE_LSAN() +#endif + +#if defined(ANGLE_WITH_MSAN) +class MsanScopedDisableInterceptorChecks final : angle::NonCopyable +{ + public: + MsanScopedDisableInterceptorChecks() { __msan_scoped_disable_interceptor_checks(); } + ~MsanScopedDisableInterceptorChecks() { __msan_scoped_enable_interceptor_checks(); } +}; +# define ANGLE_SCOPED_DISABLE_MSAN() \ + MsanScopedDisableInterceptorChecks msanScopedDisableInterceptorChecks +#else +# define ANGLE_SCOPED_DISABLE_MSAN() +#endif + +// The ANGLE_NO_SANITIZE_MEMORY macro suppresses MemorySanitizer checks for +// use-of-uninitialized-data. It can be used to decorate functions with known +// false positives. +#ifdef __clang__ +# define ANGLE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) +#else +# define ANGLE_NO_SANITIZE_MEMORY +#endif + +// Similar to the above, but for thread sanitization. +#ifdef __clang__ +# define ANGLE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) +#else +# define ANGLE_NO_SANITIZE_THREAD +#endif + +// The below inlining code lifted from V8. +#if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute)) +# define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline)) +# define ANGLE_HAS___FORCEINLINE 0 +#elif defined(_MSC_VER) +# define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0 +# define ANGLE_HAS___FORCEINLINE 1 +#else +# define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0 +# define ANGLE_HAS___FORCEINLINE 0 +#endif + +#if defined(NDEBUG) && ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE +# define ANGLE_INLINE inline __attribute__((always_inline)) +#elif defined(NDEBUG) && ANGLE_HAS___FORCEINLINE +# define ANGLE_INLINE __forceinline +#else +# define ANGLE_INLINE inline +#endif + +#if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute)) +# if __has_attribute(noinline) +# define ANGLE_NOINLINE __attribute__((noinline)) +# else +# define ANGLE_NOINLINE +# endif +#elif defined(_MSC_VER) +# define ANGLE_NOINLINE __declspec(noinline) +#else +# define ANGLE_NOINLINE +#endif + +#if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute)) +# if __has_attribute(format) +# define ANGLE_FORMAT_PRINTF(fmt, args) __attribute__((format(__printf__, fmt, args))) +# else +# define ANGLE_FORMAT_PRINTF(fmt, args) +# endif +#else +# define ANGLE_FORMAT_PRINTF(fmt, args) +#endif + +ANGLE_FORMAT_PRINTF(1, 0) +size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char> &buffer); + +// Format messes up the # inside the macro. +// clang-format off +#ifndef ANGLE_STRINGIFY +# define ANGLE_STRINGIFY(x) #x +#endif +// clang-format on + +#ifndef ANGLE_MACRO_STRINGIFY +# define ANGLE_MACRO_STRINGIFY(x) ANGLE_STRINGIFY(x) +#endif + +#if __has_cpp_attribute(clang::require_constant_initialization) +# define ANGLE_REQUIRE_CONSTANT_INIT [[clang::require_constant_initialization]] +#else +# define ANGLE_REQUIRE_CONSTANT_INIT +#endif // __has_cpp_attribute(require_constant_initialization) + +// Compiler configs. +inline bool IsASan() +{ +#if defined(ANGLE_WITH_ASAN) + return true; +#else + return false; +#endif // defined(ANGLE_WITH_ASAN) +} + +inline bool IsMSan() +{ +#if defined(ANGLE_WITH_MSAN) + return true; +#else + return false; +#endif // defined(ANGLE_WITH_MSAN) +} + +inline bool IsTSan() +{ +#if defined(ANGLE_WITH_TSAN) + return true; +#else + return false; +#endif // defined(ANGLE_WITH_TSAN) +} + +inline bool IsUBSan() +{ +#if defined(ANGLE_WITH_UBSAN) + return true; +#else + return false; +#endif // defined(ANGLE_WITH_UBSAN) +} +#endif // COMMON_ANGLEUTILS_H_ |