summaryrefslogtreecommitdiff
path: root/tools/render-test/slang-test-device-cache.h
diff options
context:
space:
mode:
authorGangzheng Tong <tonggangzheng@gmail.com>2025-09-22 15:46:42 -0700
committerGitHub <noreply@github.com>2025-09-22 22:46:42 +0000
commitba8132345cbae5b749b4a01deda732ad6f8251a0 (patch)
treef00ad0dd2d26f49112e430615106c9f6d22de032 /tools/render-test/slang-test-device-cache.h
parentbd24cc271c5d151dbaa7e4da674cbc219aef8153 (diff)
Add RHI Device Caching and Test Prefix Exclusion (#8448)
# Add RHI Device Caching and Test Prefix Exclusion ## Summary This PR introduces two key improvements to the Slang test infrastructure: 1. **RHI Device Caching**: Implements device caching to significantly speed up test execution by reusing graphics devices across tests, **RHI Device Caching reduces slang-test execution time from ~15 minutes to ~5 minutes in Windows release builds** 2. **Test Prefix Exclusion**: Adds `-exclude-prefix` option to skip tests matching specified path prefixes ## Changes ### RHI Device Caching - **New `DeviceCache` class** (`slang-test-device-cache.h/cpp`): Thread-safe device cache with LRU eviction (max 10 devices) - **Cache control option**: `-cache-rhi-device` flag in both `slang-test` and `render-test` - Default: **enabled** in slang-test, **disabled** in render-test when run standalone - Automatically skips caching for CUDA devices (due to driver issues) - **Performance benefit**: Eliminates expensive device creation/destruction cycles, especially beneficial for Vulkan on Tegra platforms ### Test Prefix Exclusion - **New `-exclude-prefix <prefix>` option** in slang-test - Allows excluding entire test directories or patterns from execution - Complements existing `-category` and individual test filtering options ### Usage Examples ```bash # Enable device caching (default) slang-test # Disable device caching slang-test -cache-rhi-device false # Exclude tests from specific directories slang-test -exclude-prefix tests/problematic/ slang-test -exclude-prefix tests/slow/ -exclude-prefix tests/experimental/ ``` This change should significantly improve test execution performance, particularly in CI environments with frequent device operations. This is needed for running the GPU test in aarch64, where repeated device creation/destroy is causing driver issues. Needed by: https://github.com/shader-slang/slang/issues/8346 --------- Co-authored-by: slangbot <ellieh+slangbot@nvidia.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'tools/render-test/slang-test-device-cache.h')
-rw-r--r--tools/render-test/slang-test-device-cache.h97
1 files changed, 97 insertions, 0 deletions
diff --git a/tools/render-test/slang-test-device-cache.h b/tools/render-test/slang-test-device-cache.h
new file mode 100644
index 000000000..752d03ff1
--- /dev/null
+++ b/tools/render-test/slang-test-device-cache.h
@@ -0,0 +1,97 @@
+#pragma once
+
+#include <mutex>
+#include <slang-rhi.h>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+// Device Cache for preventing NVIDIA Tegra driver state corruption
+// This cache reuses Vulkan instances and devices to avoid the VK_ERROR_INCOMPATIBLE_DRIVER
+// issue that occurs after ~19 device creation/destruction cycles on Tegra platforms.
+// Uses ComPtr for automatic device lifecycle management - devices are released when removed from
+// cache.
+class DeviceCache
+{
+public:
+ struct DeviceCacheKey
+ {
+ rhi::DeviceType deviceType;
+ bool enableValidation;
+ bool enableRayTracingValidation;
+ std::string profileName;
+ std::vector<std::string> requiredFeatures;
+
+ bool operator==(const DeviceCacheKey& other) const;
+ };
+
+ struct DeviceCacheKeyHash
+ {
+ std::size_t operator()(const DeviceCacheKey& key) const;
+ };
+
+ struct CachedDevice
+ {
+ Slang::ComPtr<rhi::IDevice> device;
+ uint64_t creationOrder;
+
+ CachedDevice();
+ };
+
+private:
+ static constexpr int MAX_CACHED_DEVICES = 10;
+
+ // Use function-local statics to control destruction order (Meyer's singleton pattern)
+ static std::mutex& getMutex();
+ static std::unordered_map<DeviceCacheKey, CachedDevice, DeviceCacheKeyHash>& getDeviceCache();
+ static uint64_t& getNextCreationOrder();
+
+ static void evictOldestDeviceIfNeeded();
+
+public:
+ static SlangResult acquireDevice(const rhi::DeviceDesc& desc, rhi::IDevice** outDevice);
+ static void cleanCache();
+};
+
+// RAII wrapper for cached devices to ensure proper cleanup
+class CachedDeviceWrapper
+{
+private:
+ Slang::ComPtr<rhi::IDevice> m_device;
+
+public:
+ CachedDeviceWrapper() = default;
+
+ CachedDeviceWrapper(Slang::ComPtr<rhi::IDevice> device)
+ : m_device(device)
+ {
+ }
+
+ ~CachedDeviceWrapper() {}
+
+ // Move constructor
+ CachedDeviceWrapper(CachedDeviceWrapper&& other) noexcept
+ : m_device(std::move(other.m_device))
+ {
+ }
+
+ // Move assignment
+ CachedDeviceWrapper& operator=(CachedDeviceWrapper&& other) noexcept
+ {
+ if (this != &other)
+ {
+ m_device = std::move(other.m_device);
+ }
+ return *this;
+ }
+
+ // Delete copy constructor and assignment
+ CachedDeviceWrapper(const CachedDeviceWrapper&) = delete;
+ CachedDeviceWrapper& operator=(const CachedDeviceWrapper&) = delete;
+
+ rhi::IDevice* get() const { return m_device.get(); }
+ rhi::IDevice* operator->() const { return m_device.get(); }
+ operator bool() const { return m_device != nullptr; }
+
+ Slang::ComPtr<rhi::IDevice>& getComPtr() { return m_device; }
+};