summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/VertexManagerBase.cpp
diff options
context:
space:
mode:
authoriwubcode <iwubcode@users.noreply.github.com>2024-01-27 14:21:42 -0600
committeriwubcode <iwubcode@users.noreply.github.com>2024-01-27 14:45:34 -0600
commitc34b3ae3900280a23630c07ee6e7e3018d48ee04 (patch)
tree2a5492996ebbf3a4dd7bf09822a2dadccd224417 /Source/Core/VideoCommon/VertexManagerBase.cpp
parente740e32562b842135264f9bcac7906bd43544944 (diff)
VideoCommon: refactor drawing into its own function
Diffstat (limited to 'Source/Core/VideoCommon/VertexManagerBase.cpp')
-rw-r--r--Source/Core/VideoCommon/VertexManagerBase.cpp221
1 files changed, 127 insertions, 94 deletions
diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp
index e4f6ef9921..92ff2a861f 100644
--- a/Source/Core/VideoCommon/VertexManagerBase.cpp
+++ b/Source/Core/VideoCommon/VertexManagerBase.cpp
@@ -615,8 +615,6 @@ void VertexManagerBase::Flush()
}
custom_pixel_shader = std::nullopt;
}
- if (skip == true)
- return;
}
// Now the vertices can be flushed to the GPU. Everything following the CommitBuffer() call
@@ -624,116 +622,47 @@ void VertexManagerBase::Flush()
const u32 num_indices = m_index_generator.GetIndexLen();
if (num_indices == 0)
return;
- u32 base_vertex, base_index;
- CommitBuffer(m_index_generator.GetNumVerts(),
- VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride(), num_indices,
- &base_vertex, &base_index);
-
- if (g_ActiveConfig.backend_info.api_type != APIType::D3D &&
- g_ActiveConfig.UseVSForLinePointExpand() &&
- (m_current_primitive_type == PrimitiveType::Points ||
- m_current_primitive_type == PrimitiveType::Lines))
- {
- // VS point/line expansion puts the vertex id at gl_VertexID << 2
- // That means the base vertex has to be adjusted to match
- // (The shader adds this after shifting right on D3D, so no need to do this)
- base_vertex <<= 2;
- }
// Texture loading can cause palettes to be applied (-> uniforms -> draws).
// Palette application does not use vertices, only a full-screen quad, so this is okay.
// Same with GPU texture decoding, which uses compute shaders.
g_texture_cache->BindTextures(used_textures);
- // Now we can upload uniforms, as nothing else will override them.
- geometry_shader_manager.SetConstants(m_current_primitive_type);
- pixel_shader_manager.SetConstants();
- if (!custom_pixel_shader_uniforms.empty() &&
- pixel_shader_manager.custom_constants.data() != custom_pixel_shader_uniforms.data())
- {
- pixel_shader_manager.custom_constants_dirty = true;
- }
- pixel_shader_manager.custom_constants = custom_pixel_shader_uniforms;
- UploadUniforms();
+ if (PerfQueryBase::ShouldEmulate())
+ g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
- // Update the pipeline, or compile one if needed.
- UpdatePipelineConfig();
- UpdatePipelineObject();
- if (m_current_pipeline_object)
+ if (!skip)
{
- const AbstractPipeline* current_pipeline = m_current_pipeline_object;
- if (!custom_pixel_shader_contents.shaders.empty())
+ UpdatePipelineConfig();
+ UpdatePipelineObject();
+ if (m_current_pipeline_object)
{
- 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:
+ const AbstractPipeline* pipeline_object = m_current_pipeline_object;
+ if (!custom_pixel_shader_contents.shaders.empty())
{
- 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))
+ if (const auto custom_pipeline =
+ GetCustomPipeline(custom_pixel_shader_contents, m_current_pipeline_config,
+ m_current_uber_pipeline_config, m_current_pipeline_object))
{
- current_pipeline = *uber_pipeline;
+ pipeline_object = custom_pipeline;
}
}
- break;
- };
+ RenderDrawCall(pixel_shader_manager, geometry_shader_manager, custom_pixel_shader_contents,
+ custom_pixel_shader_uniforms, m_current_primitive_type, pipeline_object);
}
- g_gfx->SetPipeline(current_pipeline);
- if (PerfQueryBase::ShouldEmulate())
- g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
+ }
- DrawCurrentBatch(base_index, num_indices, base_vertex);
- INCSTAT(g_stats.this_frame.num_draw_calls);
+ // Track the total emulated state draws
+ INCSTAT(g_stats.this_frame.num_draw_calls);
- if (PerfQueryBase::ShouldEmulate())
- g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
+ // Even if we skip the draw, emulated state should still be impacted
+ OnDraw();
- OnDraw();
+ if (PerfQueryBase::ShouldEmulate())
+ g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
- // The EFB cache is now potentially stale.
- g_framebuffer_manager->FlagPeekCacheAsOutOfDate();
- }
+ // The EFB cache is now potentially stale.
+ g_framebuffer_manager->FlagPeekCacheAsOutOfDate();
}
if (xfmem.numTexGen.numTexGens != bpmem.genMode.numtexgens)
@@ -1122,3 +1051,107 @@ void VertexManagerBase::NotifyCustomShaderCacheOfHostChange(const ShaderHostConf
m_custom_shader_cache->SetHostConfig(host_config);
m_custom_shader_cache->Reload();
}
+
+void VertexManagerBase::RenderDrawCall(
+ PixelShaderManager& pixel_shader_manager, GeometryShaderManager& geometry_shader_manager,
+ const CustomPixelShaderContents& custom_pixel_shader_contents,
+ std::span<u8> custom_pixel_shader_uniforms, PrimitiveType primitive_type,
+ const AbstractPipeline* current_pipeline)
+{
+ // Now we can upload uniforms, as nothing else will override them.
+ geometry_shader_manager.SetConstants(primitive_type);
+ pixel_shader_manager.SetConstants();
+ if (!custom_pixel_shader_uniforms.empty() &&
+ pixel_shader_manager.custom_constants.data() != custom_pixel_shader_uniforms.data())
+ {
+ pixel_shader_manager.custom_constants_dirty = true;
+ }
+ pixel_shader_manager.custom_constants = custom_pixel_shader_uniforms;
+ UploadUniforms();
+
+ g_gfx->SetPipeline(current_pipeline);
+
+ u32 base_vertex, base_index;
+ CommitBuffer(m_index_generator.GetNumVerts(),
+ VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride(),
+ m_index_generator.GetIndexLen(), &base_vertex, &base_index);
+
+ if (g_ActiveConfig.backend_info.api_type != APIType::D3D &&
+ g_ActiveConfig.UseVSForLinePointExpand() &&
+ (primitive_type == PrimitiveType::Points || primitive_type == PrimitiveType::Lines))
+ {
+ // VS point/line expansion puts the vertex id at gl_VertexID << 2
+ // That means the base vertex has to be adjusted to match
+ // (The shader adds this after shifting right on D3D, so no need to do this)
+ base_vertex <<= 2;
+ }
+
+ DrawCurrentBatch(base_index, m_index_generator.GetIndexLen(), base_vertex);
+}
+
+const AbstractPipeline* VertexManagerBase::GetCustomPipeline(
+ const CustomPixelShaderContents& custom_pixel_shader_contents,
+ const VideoCommon::GXPipelineUid& current_pipeline_config,
+ const VideoCommon::GXUberPipelineUid& current_uber_pipeline_config,
+ const AbstractPipeline* current_pipeline) const
+{
+ if (current_pipeline)
+ {
+ if (!custom_pixel_shader_contents.shaders.empty())
+ {
+ CustomShaderInstance custom_shaders;
+ custom_shaders.pixel_contents = custom_pixel_shader_contents;
+ switch (g_ActiveConfig.iShaderCompilationMode)
+ {
+ case ShaderCompilationMode::Synchronous:
+ case ShaderCompilationMode::AsynchronousSkipRendering:
+ {
+ if (auto pipeline = m_custom_shader_cache->GetPipelineAsync(
+ current_pipeline_config, custom_shaders, current_pipeline->m_config))
+ {
+ return *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(
+ current_pipeline_config, custom_shaders, current_pipeline->m_config))
+ {
+ return *pipeline;
+ }
+ }
+ else
+ {
+ if (auto pipeline = m_custom_shader_cache->GetPipelineAsync(
+ current_uber_pipeline_config, custom_shaders, current_pipeline->m_config))
+ {
+ return *pipeline;
+ }
+ }
+ }
+ break;
+ case ShaderCompilationMode::AsynchronousUberShaders:
+ {
+ if (auto pipeline = m_custom_shader_cache->GetPipelineAsync(
+ current_pipeline_config, custom_shaders, current_pipeline->m_config))
+ {
+ return *pipeline;
+ }
+ else if (auto uber_pipeline = m_custom_shader_cache->GetPipelineAsync(
+ current_uber_pipeline_config, custom_shaders, current_pipeline->m_config))
+ {
+ return *uber_pipeline;
+ }
+ }
+ break;
+ };
+ }
+ }
+
+ return nullptr;
+}