summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/VideoBackends/D3D/D3DVertexManager.cpp3
-rw-r--r--Source/Core/VideoBackends/D3D/D3DVertexManager.h1
-rw-r--r--Source/Core/VideoBackends/D3D12/D3D12VertexManager.cpp3
-rw-r--r--Source/Core/VideoBackends/D3D12/D3D12VertexManager.h1
-rw-r--r--Source/Core/VideoBackends/OGL/OGLVertexManager.cpp6
-rw-r--r--Source/Core/VideoBackends/OGL/OGLVertexManager.h1
-rw-r--r--Source/Core/VideoBackends/Vulkan/VKVertexManager.cpp3
-rw-r--r--Source/Core/VideoBackends/Vulkan/VKVertexManager.h1
-rw-r--r--Source/Core/VideoCommon/VertexManagerBase.cpp71
-rw-r--r--Source/Core/VideoCommon/VertexManagerBase.h40
10 files changed, 111 insertions, 19 deletions
diff --git a/Source/Core/VideoBackends/D3D/D3DVertexManager.cpp b/Source/Core/VideoBackends/D3D/D3DVertexManager.cpp
index c88fee33ee..d9be7faf2f 100644
--- a/Source/Core/VideoBackends/D3D/D3DVertexManager.cpp
+++ b/Source/Core/VideoBackends/D3D/D3DVertexManager.cpp
@@ -255,7 +255,10 @@ void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_in
ADDSTAT(g_stats.this_frame.bytes_vertex_streamed, vertexBufferSize);
ADDSTAT(g_stats.this_frame.bytes_index_streamed, indexBufferSize);
+}
+void VertexManager::BindCommittedBuffer(u32 vertex_stride)
+{
D3D::stateman->SetVertexBuffer(m_buffers[m_current_buffer].Get(), vertex_stride, 0);
D3D::stateman->SetIndexBuffer(m_buffers[m_current_buffer].Get());
}
diff --git a/Source/Core/VideoBackends/D3D/D3DVertexManager.h b/Source/Core/VideoBackends/D3D/D3DVertexManager.h
index ef7c4a9191..37374f6ec3 100644
--- a/Source/Core/VideoBackends/D3D/D3DVertexManager.h
+++ b/Source/Core/VideoBackends/D3D/D3DVertexManager.h
@@ -51,6 +51,7 @@ protected:
void ResetBuffer(u32 vertex_stride) override;
void CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, u32* out_base_vertex,
u32* out_base_index) override;
+ void BindCommittedBuffer(u32 vertex_stride) override;
void UploadUniforms() override;
private:
diff --git a/Source/Core/VideoBackends/D3D12/D3D12VertexManager.cpp b/Source/Core/VideoBackends/D3D12/D3D12VertexManager.cpp
index 4565db29bd..5366110ecc 100644
--- a/Source/Core/VideoBackends/D3D12/D3D12VertexManager.cpp
+++ b/Source/Core/VideoBackends/D3D12/D3D12VertexManager.cpp
@@ -128,7 +128,10 @@ void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_in
ADDSTAT(g_stats.this_frame.bytes_vertex_streamed, static_cast<int>(vertex_data_size));
ADDSTAT(g_stats.this_frame.bytes_index_streamed, static_cast<int>(index_data_size));
+}
+void VertexManager::BindCommittedBuffer(u32 vertex_stride)
+{
Gfx::GetInstance()->SetVertexBuffer(m_vertex_stream_buffer.GetGPUPointer(),
m_vertex_srv.cpu_handle, vertex_stride,
m_vertex_stream_buffer.GetSize());
diff --git a/Source/Core/VideoBackends/D3D12/D3D12VertexManager.h b/Source/Core/VideoBackends/D3D12/D3D12VertexManager.h
index 76c0c6d7cb..d7479b0c56 100644
--- a/Source/Core/VideoBackends/D3D12/D3D12VertexManager.h
+++ b/Source/Core/VideoBackends/D3D12/D3D12VertexManager.h
@@ -30,6 +30,7 @@ protected:
void ResetBuffer(u32 vertex_stride) override;
void CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, u32* out_base_vertex,
u32* out_base_index) override;
+ void BindCommittedBuffer(u32 vertex_stride) override;
void UploadUniforms() override;
void UpdateVertexShaderConstants();
diff --git a/Source/Core/VideoBackends/OGL/OGLVertexManager.cpp b/Source/Core/VideoBackends/OGL/OGLVertexManager.cpp
index c5382cf358..614d066a5b 100644
--- a/Source/Core/VideoBackends/OGL/OGLVertexManager.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLVertexManager.cpp
@@ -177,7 +177,6 @@ void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_in
*out_base_vertex = vertex_stride > 0 ? (m_vertex_buffer->GetCurrentOffset() / vertex_stride) : 0;
*out_base_index = m_index_buffer->GetCurrentOffset() / sizeof(u16);
- CheckBufferBinding();
m_vertex_buffer->Unmap(vertex_data_size);
m_index_buffer->Unmap(index_data_size);
@@ -185,6 +184,11 @@ void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_in
ADDSTAT(g_stats.this_frame.bytes_index_streamed, index_data_size);
}
+void VertexManager::BindCommittedBuffer(u32 /*vertex_stride*/)
+{
+ CheckBufferBinding();
+}
+
void VertexManager::UploadUniforms()
{
ProgramShaderCache::UploadConstants();
diff --git a/Source/Core/VideoBackends/OGL/OGLVertexManager.h b/Source/Core/VideoBackends/OGL/OGLVertexManager.h
index 55a3ef14ad..14111693f4 100644
--- a/Source/Core/VideoBackends/OGL/OGLVertexManager.h
+++ b/Source/Core/VideoBackends/OGL/OGLVertexManager.h
@@ -47,6 +47,7 @@ protected:
void ResetBuffer(u32 vertex_stride) override;
void CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, u32* out_base_vertex,
u32* out_base_index) override;
+ void BindCommittedBuffer(u32 vertex_stride) override;
void UploadUniforms() override;
private:
diff --git a/Source/Core/VideoBackends/Vulkan/VKVertexManager.cpp b/Source/Core/VideoBackends/Vulkan/VKVertexManager.cpp
index 18c5ad560c..ea8a1d090a 100644
--- a/Source/Core/VideoBackends/Vulkan/VKVertexManager.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VKVertexManager.cpp
@@ -184,7 +184,10 @@ void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_in
ADDSTAT(g_stats.this_frame.bytes_vertex_streamed, static_cast<int>(vertex_data_size));
ADDSTAT(g_stats.this_frame.bytes_index_streamed, static_cast<int>(index_data_size));
+}
+void VertexManager::BindCommittedBuffer(u32 /*vertex_stride*/)
+{
StateTracker::GetInstance()->SetVertexBuffer(m_vertex_stream_buffer->GetBuffer(), 0,
VERTEX_STREAM_BUFFER_SIZE);
StateTracker::GetInstance()->SetIndexBuffer(m_index_stream_buffer->GetBuffer(), 0,
diff --git a/Source/Core/VideoBackends/Vulkan/VKVertexManager.h b/Source/Core/VideoBackends/Vulkan/VKVertexManager.h
index 75d35c0d32..f00ac47e93 100644
--- a/Source/Core/VideoBackends/Vulkan/VKVertexManager.h
+++ b/Source/Core/VideoBackends/Vulkan/VKVertexManager.h
@@ -33,6 +33,7 @@ protected:
void ResetBuffer(u32 vertex_stride) override;
void CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, u32* out_base_vertex,
u32* out_base_index) override;
+ void BindCommittedBuffer(u32 vertex_stride) override;
void UploadUniforms() override;
void DestroyTexelBufferViews();
diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp
index f3f27518bf..7c1f9166ce 100644
--- a/Source/Core/VideoCommon/VertexManagerBase.cpp
+++ b/Source/Core/VideoCommon/VertexManagerBase.cpp
@@ -343,6 +343,10 @@ void VertexManagerBase::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 nu
*out_base_index = 0;
}
+void VertexManagerBase::BindCommittedBuffer(u32)
+{
+}
+
void VertexManagerBase::DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_vertex)
{
// If bounding box is enabled, we need to flush any changes first, then invalidate what we have.
@@ -393,6 +397,7 @@ void VertexManagerBase::UploadUtilityVertices(const void* vertices, u32 vertex_s
m_index_generator.AddExternalIndices(indices, num_indices, num_vertices);
CommitBuffer(num_vertices, vertex_stride, num_indices, out_base_vertex, out_base_index);
+ BindCommittedBuffer(vertex_stride);
}
u32 VertexManagerBase::GetTexelBufferElementSize(TexelBufferFormat buffer_format)
@@ -560,6 +565,7 @@ void VertexManagerBase::Flush()
std::vector<std::string> texture_names;
Common::SmallVector<u32, 8> texture_units;
std::array<SamplerState, 8> samplers;
+ Common::SmallVector<SubmittedSampledTexture, 8> sampled_textures;
if (!m_cull_all)
{
if (!g_ActiveConfig.bGraphicMods)
@@ -572,6 +578,9 @@ void VertexManagerBase::Flush()
const float custom_tex_scale = cache_entry->GetWidth() / float(cache_entry->native_width);
samplers[i] = TextureCacheBase::GetSamplerState(
i, custom_tex_scale, cache_entry->is_custom_tex, cache_entry->has_arbitrary_mips);
+
+ sampled_textures.push_back(
+ SubmittedSampledTexture{.entry = cache_entry, .sampler = samplers[i], .index = i});
}
}
else
@@ -590,6 +599,9 @@ void VertexManagerBase::Flush()
const float custom_tex_scale = cache_entry->GetWidth() / float(cache_entry->native_width);
samplers[i] = TextureCacheBase::GetSamplerState(
i, custom_tex_scale, cache_entry->is_custom_tex, cache_entry->has_arbitrary_mips);
+
+ sampled_textures.push_back(
+ SubmittedSampledTexture{.entry = cache_entry, .sampler = samplers[i], .index = i});
}
}
}
@@ -633,8 +645,8 @@ void VertexManagerBase::Flush()
UpdatePipelineObject();
if (m_current_pipeline_object)
{
- RenderDrawCall(pixel_shader_manager, geometry_shader_manager, m_current_primitive_type,
- m_current_pipeline_object);
+ ProcessEmulatedMesh(pixel_shader_manager, geometry_shader_manager,
+ m_current_pipeline_object, sampled_textures);
}
}
@@ -1023,25 +1035,54 @@ void VertexManagerBase::OnEndFrame()
InvalidatePipelineObject();
}
-void VertexManagerBase::RenderDrawCall(PixelShaderManager& pixel_shader_manager,
- GeometryShaderManager& geometry_shader_manager,
- PrimitiveType primitive_type,
- const AbstractPipeline* current_pipeline)
+void VertexManagerBase::ProcessEmulatedMesh(
+ PixelShaderManager& pixel_shader_manager, GeometryShaderManager& geometry_shader_manager,
+ const AbstractPipeline* pipeline, std::span<const SubmittedSampledTexture> sampled_textures)
{
- // Now we can upload uniforms, as nothing else will override them.
- geometry_shader_manager.SetConstants(primitive_type);
+ geometry_shader_manager.SetConstants(m_current_primitive_type);
pixel_shader_manager.SetConstants();
- UploadUniforms();
- g_gfx->SetPipeline(current_pipeline);
+ const u32 vertex_stride = VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride();
+ const u32 index_size = m_index_generator.GetIndexLen();
u32 base_vertex, base_index;
- CommitBuffer(m_index_generator.GetNumVerts(),
- VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride(),
- m_index_generator.GetIndexLen(), &base_vertex, &base_index);
+ CommitBuffer(m_index_generator.GetNumVerts(), vertex_stride, index_size, &base_vertex,
+ &base_index);
+
+ SubmittedDrawCallData draw_call_data;
+ draw_call_data.pipeline = pipeline;
+ draw_call_data.frame_buffer = g_gfx->GetCurrentFramebuffer();
+ draw_call_data.base_index = base_index;
+ draw_call_data.base_vertex = base_vertex;
+ draw_call_data.index_size = index_size;
+ draw_call_data.vertex_stride = vertex_stride;
+ draw_call_data.primitive_type = m_current_primitive_type;
+ for (const SubmittedSampledTexture& texture : sampled_textures)
+ draw_call_data.textures.emplace_back(texture);
+
+ DrawSubmittedDrawData(g_framebuffer_manager.get(), draw_call_data);
+}
+
+void VertexManagerBase::DrawSubmittedDrawData(FramebufferManager* /*framebuffer_manager*/,
+ const SubmittedDrawCallData& draw_call_data)
+{
+ BindCommittedBuffer(draw_call_data.vertex_stride);
+
+ // Now we can upload uniforms, as nothing else will override them.
+ UploadUniforms();
+
+ g_gfx->SetPipeline(draw_call_data.pipeline);
+
+ for (const SubmittedSampledTexture& texture : draw_call_data.textures)
+ {
+ g_gfx->SetTexture(texture.index, texture.entry->texture.get());
+ g_gfx->SetSamplerState(texture.index, texture.sampler);
+ }
+ u32 base_vertex = draw_call_data.base_vertex;
if (g_backend_info.api_type != APIType::D3D && g_ActiveConfig.UseVSForLinePointExpand() &&
- (primitive_type == PrimitiveType::Points || primitive_type == PrimitiveType::Lines))
+ (draw_call_data.primitive_type == PrimitiveType::Points ||
+ draw_call_data.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
@@ -1052,7 +1093,7 @@ void VertexManagerBase::RenderDrawCall(PixelShaderManager& pixel_shader_manager,
if (PerfQueryBase::ShouldEmulate())
g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
- DrawCurrentBatch(base_index, m_index_generator.GetIndexLen(), base_vertex);
+ DrawCurrentBatch(draw_call_data.base_index, draw_call_data.index_size, base_vertex);
// Track the total emulated state draws
INCSTAT(g_stats.this_frame.num_draw_calls);
diff --git a/Source/Core/VideoCommon/VertexManagerBase.h b/Source/Core/VideoCommon/VertexManagerBase.h
index 8397efe707..84d0c54460 100644
--- a/Source/Core/VideoCommon/VertexManagerBase.h
+++ b/Source/Core/VideoCommon/VertexManagerBase.h
@@ -4,18 +4,23 @@
#pragma once
#include <memory>
+#include <span>
#include <vector>
#include "Common/BitSet.h"
#include "Common/CommonTypes.h"
#include "Common/MathUtil.h"
+#include "Common/SmallVector.h"
#include "VideoCommon/CPUCull.h"
#include "VideoCommon/IndexGenerator.h"
#include "VideoCommon/RenderState.h"
#include "VideoCommon/ShaderCache.h"
+#include "VideoCommon/TextureCacheBase.h"
#include "VideoCommon/VideoEvents.h"
+class AbstractFramebuffer;
class DataReader;
+class FramebufferManager;
class GeometryShaderManager;
class NativeVertexFormat;
class PixelShaderManager;
@@ -168,6 +173,29 @@ public:
// Call at the end of a frame.
void OnEndFrame();
+ struct SubmittedSampledTexture
+ {
+ RcTcacheEntry entry;
+ SamplerState sampler;
+ u32 index = 0;
+ };
+
+ struct SubmittedDrawCallData
+ {
+ const AbstractPipeline* pipeline = nullptr;
+ AbstractFramebuffer* frame_buffer = nullptr;
+ u32 base_index = 0;
+ u32 base_vertex = 0;
+ u32 index_size = 0;
+ u32 vertex_stride = 0;
+ PrimitiveType primitive_type = PrimitiveType::Points;
+ Common::SmallVector<SubmittedSampledTexture, 8> textures;
+ };
+
+ // Executes a previously captured draw call.
+ void DrawSubmittedDrawData(FramebufferManager* framebuffer_manager,
+ const SubmittedDrawCallData& draw_call_data);
+
protected:
// When utility uniforms are used, the GX uniforms need to be re-written afterwards.
static void InvalidateConstants();
@@ -179,6 +207,11 @@ protected:
virtual void CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices,
u32* out_base_vertex, u32* out_base_index);
+ // Binds the buffers most recently committed, so that a draw can be issued against them.
+ // Separated from CommitBuffer so that draws can rebind the buffers if the draws
+ // are triggered independently
+ virtual void BindCommittedBuffer(u32 vertex_stride);
+
// Uploads uniform buffers for GX draws.
virtual void UploadUniforms();
@@ -220,9 +253,10 @@ private:
// Minimum number of draws per command buffer when attempting to preempt a readback operation.
static constexpr u32 MINIMUM_DRAW_CALLS_PER_COMMAND_BUFFER_FOR_READBACK = 10;
- void RenderDrawCall(PixelShaderManager& pixel_shader_manager,
- GeometryShaderManager& geometry_shader_manager, PrimitiveType primitive_type,
- const AbstractPipeline* current_pipeline);
+ void ProcessEmulatedMesh(PixelShaderManager& pixel_shader_manager,
+ GeometryShaderManager& geometry_shader_manager,
+ const AbstractPipeline* pipeline,
+ std::span<const SubmittedSampledTexture> sampled_textures);
void UpdatePipelineConfig();
void UpdatePipelineObject();