diff --git a/extern/CommonLibSSE-NG b/extern/CommonLibSSE-NG index d50cd96b80..f343b8cf75 160000 --- a/extern/CommonLibSSE-NG +++ b/extern/CommonLibSSE-NG @@ -1 +1 @@ -Subproject commit d50cd96b8016a5ecf89c744abe860bfb0e23e98c +Subproject commit f343b8cf75cace4ff942ef744ea34c406aa7f8e2 diff --git a/src/FrameAnnotations.cpp b/src/FrameAnnotations.cpp index 8dc163535d..cd7bf06168 100644 --- a/src/FrameAnnotations.cpp +++ b/src/FrameAnnotations.cpp @@ -30,8 +30,13 @@ namespace FrameAnnotations static void thunk(RE::BSShader* shader, RE::BSRenderPass* pass, uint32_t renderFlags) { if (globals::state->frameAnnotations) { - const std::string passName = std::format("[{}:{:X}] <{}> {}", magic_enum::enum_name(ShaderType), pass->passEnum, - pass->accumulationHint, pass->geometry->name.c_str()); + uint32_t descriptor = 0; + if (globals::game::currentPixelShader && *globals::game::currentPixelShader) { + descriptor = (*globals::game::currentPixelShader)->id; + } + std::string diskPath = std::format("Data/ShaderCache/{}/{:X}.pso", shader->fxpFilename, descriptor); + const std::string passName = std::format("[{}:{:X}] ({:X}) <{}> {} -> {}", magic_enum::enum_name(ShaderType), descriptor, pass->passEnum, + pass->accumulationHint, pass->geometry->name.c_str(), diskPath); globals::state->BeginPerfEvent(passName); } @@ -916,6 +921,66 @@ namespace FrameAnnotations RE::VTABLE_BSImagespaceShaderISUnderwaterMask[0]); stl::write_vfunc<0xC, BSImagespaceShader_Dispatch>( RE::VTABLE_BSImagespaceShaderWaterFlow[0]); + // VR-only shaders + if (globals::game::isVR) { + stl::write_vfunc<0x1, BSImagespaceShader_Render>( + RE::VTABLE_BSImagespaceShaderCopyDepthBuffer[3]); + stl::write_vfunc<0x1, BSImagespaceShader_Render>( + RE::VTABLE_BSImagespaceShaderCopyDepthBuffer_DR[3]); + stl::write_vfunc<0x1, BSImagespaceShader_Render>( + RE::VTABLE_BSImagespaceShaderISDownsampleHierarchicalDepthBufferCS[3]); + stl::write_vfunc<0x1, BSImagespaceShader_Render>( + RE::VTABLE_BSImagespaceShaderISDiffScaleDownsampleDepthBufferCS[3]); + stl::write_vfunc<0x1, BSImagespaceShader_Render>( + RE::VTABLE_BSImagespaceShaderISFullScreenVR[3]); + stl::write_vfunc<0x1, BSImagespaceShader_Render>( + RE::VTABLE_BSImagespaceShaderTransformLvl7PreTest[3]); + stl::write_vfunc<0x1, BSImagespaceShader_Render>( + RE::VTABLE_BSImagespaceShaderLvl6PreTest[3]); + stl::write_vfunc<0x1, BSImagespaceShader_Render>( + RE::VTABLE_BSImagespaceShaderLvl5PreTest[3]); + stl::write_vfunc<0x1, BSImagespaceShader_Render>( + RE::VTABLE_BSImagespaceShaderLvl4PreTest[3]); + stl::write_vfunc<0x1, BSImagespaceShader_Render>( + RE::VTABLE_BSImagespaceShaderLvl3PreTest[3]); + stl::write_vfunc<0x1, BSImagespaceShader_Render>( + RE::VTABLE_BSImagespaceShaderLvl2PreTest[3]); + stl::write_vfunc<0x1, BSImagespaceShader_Render>( + RE::VTABLE_BSImagespaceShaderLvl1PreTest[3]); + stl::write_vfunc<0x1, BSImagespaceShader_Render>( + RE::VTABLE_BSImagespaceShaderLvl0PreTest[3]); + stl::write_vfunc<0x1, BSImagespaceShader_Render>( + RE::VTABLE_BSImagespaceShaderSetupPreTest[3]); + + stl::write_vfunc<0xC, BSImagespaceShader_Dispatch>( + RE::VTABLE_BSImagespaceShaderCopyDepthBuffer[0]); + stl::write_vfunc<0xC, BSImagespaceShader_Dispatch>( + RE::VTABLE_BSImagespaceShaderCopyDepthBuffer_DR[0]); + stl::write_vfunc<0xC, BSImagespaceShader_Dispatch>( + RE::VTABLE_BSImagespaceShaderISDownsampleHierarchicalDepthBufferCS[0]); + stl::write_vfunc<0xC, BSImagespaceShader_Dispatch>( + RE::VTABLE_BSImagespaceShaderISDiffScaleDownsampleDepthBufferCS[0]); + stl::write_vfunc<0xC, BSImagespaceShader_Dispatch>( + RE::VTABLE_BSImagespaceShaderISFullScreenVR[0]); + stl::write_vfunc<0xC, BSImagespaceShader_Dispatch>( + RE::VTABLE_BSImagespaceShaderTransformLvl7PreTest[0]); + stl::write_vfunc<0xC, BSImagespaceShader_Dispatch>( + RE::VTABLE_BSImagespaceShaderLvl6PreTest[0]); + stl::write_vfunc<0xC, BSImagespaceShader_Dispatch>( + RE::VTABLE_BSImagespaceShaderLvl5PreTest[0]); + stl::write_vfunc<0xC, BSImagespaceShader_Dispatch>( + RE::VTABLE_BSImagespaceShaderLvl4PreTest[0]); + stl::write_vfunc<0xC, BSImagespaceShader_Dispatch>( + RE::VTABLE_BSImagespaceShaderLvl3PreTest[0]); + stl::write_vfunc<0xC, BSImagespaceShader_Dispatch>( + RE::VTABLE_BSImagespaceShaderLvl2PreTest[0]); + stl::write_vfunc<0xC, BSImagespaceShader_Dispatch>( + RE::VTABLE_BSImagespaceShaderLvl1PreTest[0]); + stl::write_vfunc<0xC, BSImagespaceShader_Dispatch>( + RE::VTABLE_BSImagespaceShaderLvl0PreTest[0]); + stl::write_vfunc<0xC, BSImagespaceShader_Dispatch>( + RE::VTABLE_BSImagespaceShaderSetupPreTest[0]); + } stl::write_vfunc<0x2A, BSShaderAccumulator_FinishAccumulatingDispatch>( RE::VTABLE_BSShaderAccumulator[0]); diff --git a/src/ShaderCache.cpp b/src/ShaderCache.cpp index 68dedccc66..474130c1ad 100644 --- a/src/ShaderCache.cpp +++ b/src/ShaderCache.cpp @@ -13,6 +13,26 @@ namespace SIE { static void GetShaderDefines(const RE::BSShader&, uint32_t, D3D_SHADER_MACRO*); static std::string GetShaderString(ShaderClass, const RE::BSShader&, uint32_t, bool = false); + /** + * @brief Resolve image-space shader descriptor when applicable. + * + * If @p shader is an image-space shader, attempts to map it to a + * runtime image-space descriptor via GetImagespaceShaderDescriptor and + * returns true on success. If the shader is not image-space the + * function returns true and leaves @p descriptor unchanged. Returns + * false only when the shader is image-space and no valid descriptor + * could be resolved. + * + * This helper is used by the shader loading and caching code paths to + * determine whether an image-space shader can be loaded or cached. If + * this function returns false the caller should skip loading/compiling + * and caching that shader. + * + * @param shader The shader to resolve (may be an image-space shader). + * @param[out] descriptor Resolved descriptor for image-space shaders. + * @return True if descriptor is valid or not applicable, false on failure. + */ + static bool ResolveImageSpaceDescriptor(const RE::BSShader& shader, uint32_t& descriptor); /** @brief Get the BSShader::Type from the ShaderString @param a_key The key generated from GetShaderString @@ -1254,6 +1274,10 @@ namespace SIE static ID3DBlob* CompileShader(ShaderClass shaderClass, const RE::BSShader& shader, uint32_t descriptor, bool useDiskCache) { + if (!SShaderCache::ResolveImageSpaceDescriptor(shader, descriptor)) { + return nullptr; + } + // check hashmap auto& cache = ShaderCache::Instance(); ID3DBlob* shaderBlob = cache.GetCompletedShader(shaderClass, shader, descriptor); @@ -1647,8 +1671,11 @@ namespace SIE { "BSImagespaceShaderVolumetricLightingBlurVCS", RE::ImageSpaceManager::GetCurrentIndex(ISVolumetricLightingBlurVCS) }, // VR only shaders - { "BSImagespaceShaderCopyDepthBuffer", RE::ImageSpaceManager::GetCurrentIndex(ISCopyDepthBuffer) }, - { "BSImagespaceShaderTargetSize", RE::ImageSpaceManager::GetCurrentIndex(ISTargetSize) }, + // Disable BSImagespaceShaderCopyDepthBuffer since we don't have it REed and it causes issues with cache and upscaling + // https://github.com/doodlum/skyrim-community-shaders/issues/1552 + // { "BSImagespaceShaderCopyDepthBuffer", RE::ImageSpaceManager::GetCurrentIndex(ISCopyDepthBuffer) }, + // { "BSImagespaceShaderCopyDepthBuffer_DR", RE::ImageSpaceManager::GetCurrentIndex(ISCopyDepthBuffer_DR) }, + // { "BSImagespaceShaderCopyDepthBufferTargetSize", RE::ImageSpaceManager::GetCurrentIndex(ISCopyDepthBufferTargetSize) }, { "BSImagespaceShaderGraphicsTextureFilterMode", RE::ImageSpaceManager::GetCurrentIndex(ISGraphicsTextureFilterMode) }, { "BSImagespaceShaderISDownsampleHierarchicalDepthBufferCS", RE::ImageSpaceManager::GetCurrentIndex(ISDownsampleHierarchicalDepthBufferCS) }, { "BSImagespaceShaderISDiffScaleDownsampleDepthBufferCS", RE::ImageSpaceManager::GetCurrentIndex(ISDiffScaleDownsampleDepthBufferCS) }, @@ -1671,16 +1698,22 @@ namespace SIE descriptor = it->second; return true; } + + static bool ResolveImageSpaceDescriptor(const RE::BSShader& shader, uint32_t& descriptor) + { + if (shader.shaderType == RE::BSShader::Type::ImageSpace) { + const auto& isShader = static_cast(shader); + return GetImagespaceShaderDescriptor(isShader, descriptor); + } + return true; + } } RE::BSGraphics::VertexShader* ShaderCache::GetVertexShader(const RE::BSShader& shader, uint32_t descriptor) { - if (shader.shaderType == RE::BSShader::Type::ImageSpace) { - const auto& isShader = static_cast(shader); - if (!SShaderCache::GetImagespaceShaderDescriptor(isShader, descriptor)) { - return nullptr; - } + if (!SShaderCache::ResolveImageSpaceDescriptor(shader, descriptor)) { + return nullptr; } auto state = globals::state; @@ -1733,11 +1766,8 @@ namespace SIE return nullptr; } - if (shader.shaderType == RE::BSShader::Type::ImageSpace) { - const auto& isShader = static_cast(shader); - if (!SShaderCache::GetImagespaceShaderDescriptor(isShader, descriptor)) { - return nullptr; - } + if (!SShaderCache::ResolveImageSpaceDescriptor(shader, descriptor)) { + return nullptr; } if (state->IsDeveloperMode()) { @@ -1777,11 +1807,8 @@ namespace SIE return nullptr; } - if (shader.shaderType == RE::BSShader::Type::ImageSpace) { - const auto& isShader = static_cast(shader); - if (!SShaderCache::GetImagespaceShaderDescriptor(isShader, descriptor)) { - return nullptr; - } + if (!SShaderCache::ResolveImageSpaceDescriptor(shader, descriptor)) { + return nullptr; } if (state->IsDeveloperMode()) {