yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Gangzheng TongAdd RHI Device Caching and Test Prefix Exclusion (#8448)ba8132345

master
2.6 KiB97 linesraw
1#pragma once
2
3#include <mutex>
4#include <slang-rhi.h>
5#include <string>
6#include <unordered_map>
7#include <vector>
8
9// Device Cache for preventing NVIDIA Tegra driver state corruption
10// This cache reuses Vulkan instances and devices to avoid the VK_ERROR_INCOMPATIBLE_DRIVER
11// issue that occurs after ~19 device creation/destruction cycles on Tegra platforms.
12// Uses ComPtr for automatic device lifecycle management - devices are released when removed from
13// cache.
14class DeviceCache
15{
16public:
17    struct DeviceCacheKey
18    {
19        rhi::DeviceType deviceType;
20        bool enableValidation;
21        bool enableRayTracingValidation;
22        std::string profileName;
23        std::vector<std::string> requiredFeatures;
24
25        bool operator==(const DeviceCacheKey& other) const;
26    };
27
28    struct DeviceCacheKeyHash
29    {
30        std::size_t operator()(const DeviceCacheKey& key) const;
31    };
32
33    struct CachedDevice
34    {
35        Slang::ComPtr<rhi::IDevice> device;
36        uint64_t creationOrder;
37
38        CachedDevice();
39    };
40
41private:
42    static constexpr int MAX_CACHED_DEVICES = 10;
43
44    // Use function-local statics to control destruction order (Meyer's singleton pattern)
45    static std::mutex& getMutex();
46    static std::unordered_map<DeviceCacheKey, CachedDevice, DeviceCacheKeyHash>& getDeviceCache();
47    static uint64_t& getNextCreationOrder();
48
49    static void evictOldestDeviceIfNeeded();
50
51public:
52    static SlangResult acquireDevice(const rhi::DeviceDesc& desc, rhi::IDevice** outDevice);
53    static void cleanCache();
54};
55
56// RAII wrapper for cached devices to ensure proper cleanup
57class CachedDeviceWrapper
58{
59private:
60    Slang::ComPtr<rhi::IDevice> m_device;
61
62public:
63    CachedDeviceWrapper() = default;
64
65    CachedDeviceWrapper(Slang::ComPtr<rhi::IDevice> device)
66        : m_device(device)
67    {
68    }
69
70    ~CachedDeviceWrapper() {}
71
72    // Move constructor
73    CachedDeviceWrapper(CachedDeviceWrapper&& other) noexcept
74        : m_device(std::move(other.m_device))
75    {
76    }
77
78    // Move assignment
79    CachedDeviceWrapper& operator=(CachedDeviceWrapper&& other) noexcept
80    {
81        if (this != &other)
82        {
83            m_device = std::move(other.m_device);
84        }
85        return *this;
86    }
87
88    // Delete copy constructor and assignment
89    CachedDeviceWrapper(const CachedDeviceWrapper&) = delete;
90    CachedDeviceWrapper& operator=(const CachedDeviceWrapper&) = delete;
91
92    rhi::IDevice* get() const { return m_device.get(); }
93    rhi::IDevice* operator->() const { return m_device.get(); }
94    operator bool() const { return m_device != nullptr; }
95
96    Slang::ComPtr<rhi::IDevice>& getComPtr() { return m_device; }
97};