diff --git a/AGENTS.md b/AGENTS.md index 91cd398db5..1f48c19da8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -74,6 +74,14 @@ for it: to forget: put it last in the array even when alphabetical or NID order would put it elsewhere, and even when the array is otherwise tidily sorted. The same rule governs the order of `Register_*()` calls in `Core/HLE/HLETables.cpp` - new modules go at the very end. +4. **Changing a shader cache key means bumping `CACHE_VERSION`, in both the OpenGL and Vulkan + caches** (`GPU/GLES/ShaderManagerGLES.cpp` and `GPU/Vulkan/ShaderManagerVulkan.cpp`). Their + on-disk caches store raw key bits with nothing to tell an old layout from a new one. OpenGL + stores `VShaderID`/`FShaderID`, and Vulkan stores those plus `VulkanPipelineKey` (the raster + state key and the decoded vertex format ID). So adding, removing, moving or reinterpreting any + of those bits needs the bump, or an old cache precompiles shaders for keys that now mean + something else, including combinations the generators assert on. D3D11 doesn't store shader IDs + on disk. Keys that only live in memory, like `SamplerCacheKey`, don't need a bump. ## Build and validation diff --git a/GPU/Common/ShaderId.h b/GPU/Common/ShaderId.h index 439c7f3161..bb9a322ec5 100644 --- a/GPU/Common/ShaderId.h +++ b/GPU/Common/ShaderId.h @@ -21,6 +21,9 @@ inline bool needFragmentDepthClamp() { return (gstate.getDepthRangeMin() == 0 || gstate.getDepthRangeMax() == 0xFFFF) && gstate.isDepthClipEnabled(); } +// These IDs are stored in the OpenGL and Vulkan shader caches on disk. Changing the bit layout or meaning +// requires bumping CACHE_VERSION in both ShaderManagerGLES.cpp and ShaderManagerVulkan.cpp. + // VS_BIT_LIGHT_UBERSHADER indicates that some groups of these will be // sent to the shader and processed there. This cuts down the number of shaders ("ubershader approach"). enum VShaderBit : uint8_t { diff --git a/GPU/Vulkan/PipelineManagerVulkan.h b/GPU/Vulkan/PipelineManagerVulkan.h index 6d6c57095f..bd05b9b243 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.h +++ b/GPU/Vulkan/PipelineManagerVulkan.h @@ -40,6 +40,7 @@ class VulkanFragmentShader; class ShaderManagerVulkan; class DrawEngineCommon; +// Stored in the shader cache on disk: changing it requires bumping CACHE_VERSION in ShaderManagerVulkan.cpp. struct VulkanPipelineKey { VulkanPipelineRasterStateKey raster; // prim is included here VShaderID vid; diff --git a/GPU/Vulkan/StateMappingVulkan.h b/GPU/Vulkan/StateMappingVulkan.h index 52dde77ec4..8f706bb9ae 100644 --- a/GPU/Vulkan/StateMappingVulkan.h +++ b/GPU/Vulkan/StateMappingVulkan.h @@ -27,6 +27,8 @@ struct VulkanDynamicState { // also be set to 0. // ~64 bits. // Can't use enums unfortunately, they end up signed and breaking values above half their ranges. +// Stored in the shader cache on disk (as part of VulkanPipelineKey): changing it requires bumping +// CACHE_VERSION in ShaderManagerVulkan.cpp. struct VulkanPipelineRasterStateKey { // Blend unsigned int blendEnable : 1;