summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/common/angleutils.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/common/angleutils.h')
-rw-r--r--gfx/angle/checkout/src/common/angleutils.h601
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_