summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/VertexManagerBase.cpp
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2023-08-22 02:18:40 +0200
committerGitHub <noreply@github.com>2023-08-22 02:18:40 +0200
commitdbe6a5f7e4caca71de9d9ba86916f82c0bc21683 (patch)
tree84fd8c6f664f1df62350f9d7b5aa9d110b6aee02 /Source/Core/VideoCommon/VertexManagerBase.cpp
parent3451cb1ca2583f9c2b02d0d216355047787c134b (diff)
parent55061216855af89f21eee1174fa81d927bc94991 (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.cpp102
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();
+}