mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-25 16:30:15 +00:00
fix: add VkSampler cache to prevent sampler exhaustion crash
Validation layers revealed 9965 VkSamplers allocated against a device limit of 4000 — every VkTexture created its own sampler even when configurations were identical. This exhausted NVIDIA's sampler pool and caused intermittent SIGSEGV in vkCmdBeginRenderPass. Add a thread-safe sampler cache in VkContext that deduplicates samplers by FNV-1a hash of all 14 VkSamplerCreateInfo fields. All texture, render target, renderer, water, and loading screen sampler creation now goes through getOrCreateSampler(). Textures set ownsSampler_=false so shared samplers aren't double-freed. Also auto-disable anisotropy in the cache when the physical device doesn't support the samplerAnisotropy feature, fixing the validation error VUID-VkSamplerCreateInfo-anisotropyEnable-01070.
This commit is contained in:
parent
1556559211
commit
a152023e5e
10 changed files with 194 additions and 40 deletions
|
|
@ -8,6 +8,8 @@
|
|||
#include <vector>
|
||||
#include <functional>
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
|
||||
namespace wowee {
|
||||
namespace rendering {
|
||||
|
|
@ -119,6 +121,18 @@ public:
|
|||
VkImageView getDepthResolveImageView() const { return depthResolveImageView; }
|
||||
VkImageView getDepthImageView() const { return depthImageView; }
|
||||
|
||||
// Sampler cache: returns a shared VkSampler matching the given create info.
|
||||
// Callers must NOT destroy the returned sampler — it is owned by VkContext.
|
||||
// Automatically clamps anisotropy if the device doesn't support it.
|
||||
VkSampler getOrCreateSampler(const VkSamplerCreateInfo& info);
|
||||
|
||||
// Whether the physical device supports sampler anisotropy.
|
||||
bool isSamplerAnisotropySupported() const { return samplerAnisotropySupported_; }
|
||||
|
||||
// Global sampler cache accessor (set during VkContext::initialize, cleared on shutdown).
|
||||
// Used by VkTexture and other code that only has a VkDevice handle.
|
||||
static VkContext* globalInstance() { return sInstance_; }
|
||||
|
||||
// UI texture upload: creates a Vulkan texture from RGBA data and returns
|
||||
// a VkDescriptorSet suitable for use as ImTextureID.
|
||||
// The caller does NOT need to free the result — resources are tracked and
|
||||
|
|
@ -239,6 +253,13 @@ private:
|
|||
};
|
||||
std::vector<UiTexture> uiTextures_;
|
||||
|
||||
// Sampler cache — deduplicates VkSamplers by configuration hash.
|
||||
std::mutex samplerCacheMutex_;
|
||||
std::unordered_map<uint64_t, VkSampler> samplerCache_;
|
||||
bool samplerAnisotropySupported_ = false;
|
||||
|
||||
static VkContext* sInstance_;
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool enableValidation = true;
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ private:
|
|||
bool hasDepth_ = false;
|
||||
VkSampleCountFlagBits msaaSamples_ = VK_SAMPLE_COUNT_1_BIT;
|
||||
VkSampler sampler_ = VK_NULL_HANDLE;
|
||||
bool ownsSampler_ = true;
|
||||
VkRenderPass renderPass_ = VK_NULL_HANDLE;
|
||||
VkFramebuffer framebuffer_ = VK_NULL_HANDLE;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ private:
|
|||
AllocatedImage image_{};
|
||||
VkSampler sampler_ = VK_NULL_HANDLE;
|
||||
uint32_t mipLevels_ = 1;
|
||||
bool ownsSampler_ = true; // false when sampler comes from VkContext cache
|
||||
};
|
||||
|
||||
} // namespace rendering
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue