diff options
| author | Admiral H. Curtiss <pikachu025@gmail.com> | 2023-08-22 02:18:40 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-08-22 02:18:40 +0200 |
| commit | dbe6a5f7e4caca71de9d9ba86916f82c0bc21683 (patch) | |
| tree | 84fd8c6f664f1df62350f9d7b5aa9d110b6aee02 /Source/Core/VideoCommon/VertexManagerBase.cpp | |
| parent | 3451cb1ca2583f9c2b02d0d216355047787c134b (diff) | |
| parent | 55061216855af89f21eee1174fa81d927bc94991 (diff) | |
Merge pull request #11300 from iwubcode/custom-shaders
VideoCommon: add a graphics mod action that allows you to modify the game's base rendering
Diffstat (limited to 'Source/Core/VideoCommon/VertexManagerBase.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/VertexManagerBase.cpp | 102 |
1 files changed, 98 insertions, 4 deletions
diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp index 0b184e1da9..564eb684dc 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/VertexManagerBase.cpp @@ -15,6 +15,7 @@ #include "Core/ConfigManager.h" #include "Core/DolphinAnalytics.h" +#include "Core/HW/SystemTimers.h" #include "Core/System.h" #include "VideoCommon/AbstractGfx.h" @@ -23,12 +24,14 @@ #include "VideoCommon/DataReader.h" #include "VideoCommon/FramebufferManager.h" #include "VideoCommon/GeometryShaderManager.h" +#include "VideoCommon/GraphicsModSystem/Runtime/CustomShaderCache.h" #include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModActionData.h" #include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h" #include "VideoCommon/IndexGenerator.h" #include "VideoCommon/NativeVertexFormat.h" #include "VideoCommon/OpcodeDecoding.h" #include "VideoCommon/PerfQueryBase.h" +#include "VideoCommon/PixelShaderGen.h" #include "VideoCommon/PixelShaderManager.h" #include "VideoCommon/Statistics.h" #include "VideoCommon/TextureCacheBase.h" @@ -105,7 +108,10 @@ VertexManagerBase::~VertexManagerBase() = default; bool VertexManagerBase::Initialize() { m_frame_end_event = AfterFrameEvent::Register([this] { OnEndFrame(); }, "VertexManagerBase"); + m_after_present_event = AfterPresentEvent::Register( + [this](PresentInfo& pi) { m_ticks_elapsed = pi.emulated_timestamp; }, "VertexManagerBase"); m_index_generator.Init(); + m_custom_shader_cache = std::make_unique<CustomShaderCache>(); m_cpu_cull.Init(); return true; } @@ -523,10 +529,18 @@ void VertexManagerBase::Flush() auto& geometry_shader_manager = system.GetGeometryShaderManager(); auto& vertex_shader_manager = system.GetVertexShaderManager(); + if (g_ActiveConfig.bGraphicMods) + { + const double seconds_elapsed = + static_cast<double>(m_ticks_elapsed) / SystemTimers::GetTicksPerSecond(); + pixel_shader_manager.constants.time_ms = seconds_elapsed * 1000; + } + CalculateBinormals(VertexLoaderManager::GetCurrentVertexFormat()); // Calculate ZSlope for zfreeze const auto used_textures = UsedTextures(); std::vector<std::string> texture_names; + std::vector<u32> texture_units; if (!m_cull_all) { if (!g_ActiveConfig.bGraphicMods) @@ -543,7 +557,12 @@ void VertexManagerBase::Flush() const auto cache_entry = g_texture_cache->Load(TextureInfo::FromStage(i)); if (cache_entry) { - texture_names.push_back(cache_entry->texture_info_name); + if (std::find(texture_names.begin(), texture_names.end(), + cache_entry->texture_info_name) == texture_names.end()) + { + texture_names.push_back(cache_entry->texture_info_name); + texture_units.push_back(i); + } } } } @@ -562,13 +581,24 @@ void VertexManagerBase::Flush() if (!m_cull_all) { - for (const auto& texture_name : texture_names) + CustomPixelShaderContents custom_pixel_shader_contents; + std::optional<CustomPixelShader> custom_pixel_shader; + std::vector<std::string> custom_pixel_texture_names; + for (int i = 0; i < texture_names.size(); i++) { + const std::string& texture_name = texture_names[i]; + const u32 texture_unit = texture_units[i]; bool skip = false; - GraphicsModActionData::DrawStarted draw_started{&skip}; + GraphicsModActionData::DrawStarted draw_started{texture_unit, &skip, &custom_pixel_shader}; for (const auto& action : g_graphics_mod_manager->GetDrawStartedActions(texture_name)) { action->OnDrawStarted(&draw_started); + if (custom_pixel_shader) + { + custom_pixel_shader_contents.shaders.push_back(*custom_pixel_shader); + custom_pixel_texture_names.push_back(texture_name); + } + custom_pixel_shader = std::nullopt; } if (skip == true) return; @@ -610,7 +640,65 @@ void VertexManagerBase::Flush() UpdatePipelineObject(); if (m_current_pipeline_object) { - g_gfx->SetPipeline(m_current_pipeline_object); + const AbstractPipeline* current_pipeline = m_current_pipeline_object; + if (!custom_pixel_shader_contents.shaders.empty()) + { + CustomShaderInstance custom_shaders; + custom_shaders.pixel_contents = std::move(custom_pixel_shader_contents); + + switch (g_ActiveConfig.iShaderCompilationMode) + { + case ShaderCompilationMode::Synchronous: + case ShaderCompilationMode::AsynchronousSkipRendering: + { + if (auto pipeline = m_custom_shader_cache->GetPipelineAsync( + m_current_pipeline_config, custom_shaders, m_current_pipeline_object->m_config)) + { + current_pipeline = *pipeline; + } + } + break; + case ShaderCompilationMode::SynchronousUberShaders: + { + // D3D has issues compiling large custom ubershaders + // use specialized shaders instead + if (g_ActiveConfig.backend_info.api_type == APIType::D3D) + { + if (auto pipeline = m_custom_shader_cache->GetPipelineAsync( + m_current_pipeline_config, custom_shaders, m_current_pipeline_object->m_config)) + { + current_pipeline = *pipeline; + } + } + else + { + if (auto pipeline = m_custom_shader_cache->GetPipelineAsync( + m_current_uber_pipeline_config, custom_shaders, + m_current_pipeline_object->m_config)) + { + current_pipeline = *pipeline; + } + } + } + break; + case ShaderCompilationMode::AsynchronousUberShaders: + { + if (auto pipeline = m_custom_shader_cache->GetPipelineAsync( + m_current_pipeline_config, custom_shaders, m_current_pipeline_object->m_config)) + { + current_pipeline = *pipeline; + } + else if (auto uber_pipeline = m_custom_shader_cache->GetPipelineAsync( + m_current_uber_pipeline_config, custom_shaders, + m_current_pipeline_object->m_config)) + { + current_pipeline = *uber_pipeline; + } + } + break; + }; + } + g_gfx->SetPipeline(current_pipeline); if (PerfQueryBase::ShouldEmulate()) g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); @@ -1006,3 +1094,9 @@ void VertexManagerBase::OnEndFrame() // state changes the specialized shader will not take over. InvalidatePipelineObject(); } + +void VertexManagerBase::NotifyCustomShaderCacheOfHostChange(const ShaderHostConfig& host_config) +{ + m_custom_shader_cache->SetHostConfig(host_config); + m_custom_shader_cache->Reload(); +} |
