VideoCommon/IndexGenerator: Eliminate static state

Now that we've extracted all of the stateless functions that can be
hidden, it's time to make the index generator a regular class with
active data members.

This can just be a member that sits within the vertex manager base
class. By deglobalizing the state of the index generator we also get rid
of the wonky dual-initializing that was going on within the OpenGL
backend.

Since the renderer is always initialized before the vertex manager, we
now only call Init() once throughout the execution lifecycle.
This commit is contained in:
Lioncash 2019-12-05 10:01:33 -05:00
parent 159947ab68
commit 10f7674651
12 changed files with 69 additions and 64 deletions

View File

@ -210,7 +210,7 @@ void VertexManager::ResetBuffer(u32 vertex_stride)
m_base_buffer_pointer = m_cpu_vertex_buffer.data(); m_base_buffer_pointer = m_cpu_vertex_buffer.data();
m_cur_buffer_pointer = m_base_buffer_pointer; m_cur_buffer_pointer = m_base_buffer_pointer;
m_end_buffer_pointer = m_base_buffer_pointer + m_cpu_vertex_buffer.size(); m_end_buffer_pointer = m_base_buffer_pointer + m_cpu_vertex_buffer.size();
IndexGenerator::Start(m_cpu_index_buffer.data()); m_index_generator.Start(m_cpu_index_buffer.data());
} }
void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices,

View File

@ -96,7 +96,7 @@ void VertexManager::ResetBuffer(u32 vertex_stride)
m_base_buffer_pointer = m_vertex_stream_buffer.GetHostPointer(); m_base_buffer_pointer = m_vertex_stream_buffer.GetHostPointer();
m_end_buffer_pointer = m_vertex_stream_buffer.GetCurrentHostPointer() + MAXVBUFFERSIZE; m_end_buffer_pointer = m_vertex_stream_buffer.GetCurrentHostPointer() + MAXVBUFFERSIZE;
m_cur_buffer_pointer = m_vertex_stream_buffer.GetCurrentHostPointer(); m_cur_buffer_pointer = m_vertex_stream_buffer.GetCurrentHostPointer();
IndexGenerator::Start(reinterpret_cast<u16*>(m_index_stream_buffer.GetCurrentHostPointer())); m_index_generator.Start(reinterpret_cast<u16*>(m_index_stream_buffer.GetCurrentHostPointer()));
} }
void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices,

View File

@ -786,7 +786,6 @@ Renderer::Renderer(std::unique_ptr<GLContext> main_gl_context, float backbuffer_
if (g_ActiveConfig.backend_info.bSupportsPrimitiveRestart) if (g_ActiveConfig.backend_info.bSupportsPrimitiveRestart)
GLUtil::EnablePrimitiveRestart(m_main_gl_context.get()); GLUtil::EnablePrimitiveRestart(m_main_gl_context.get());
IndexGenerator::Init();
UpdateActiveConfig(); UpdateActiveConfig();
} }

View File

@ -165,7 +165,7 @@ void VertexManager::ResetBuffer(u32 vertex_stride)
m_end_buffer_pointer = buffer.first + MAXVBUFFERSIZE; m_end_buffer_pointer = buffer.first + MAXVBUFFERSIZE;
buffer = m_index_buffer->Map(MAXIBUFFERSIZE * sizeof(u16)); buffer = m_index_buffer->Map(MAXIBUFFERSIZE * sizeof(u16));
IndexGenerator::Start((u16*)buffer.first); m_index_generator.Start(reinterpret_cast<u16*>(buffer.first));
} }
void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices,

View File

@ -64,7 +64,7 @@ void SWVertexLoader::DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_
Rasterizer::SetTevReg(i, Tev::ALP_C, PixelShaderManager::constants.kcolors[i][3]); Rasterizer::SetTevReg(i, Tev::ALP_C, PixelShaderManager::constants.kcolors[i][3]);
} }
for (u32 i = 0; i < IndexGenerator::GetIndexLen(); i++) for (u32 i = 0; i < m_index_generator.GetIndexLen(); i++)
{ {
const u16 index = m_cpu_index_buffer[i]; const u16 index = m_cpu_index_buffer[i];
memset(static_cast<void*>(&m_vertex), 0, sizeof(m_vertex)); memset(static_cast<void*>(&m_vertex), 0, sizeof(m_vertex));

View File

@ -165,7 +165,7 @@ void VertexManager::ResetBuffer(u32 vertex_stride)
m_base_buffer_pointer = m_vertex_stream_buffer->GetHostPointer(); m_base_buffer_pointer = m_vertex_stream_buffer->GetHostPointer();
m_end_buffer_pointer = m_vertex_stream_buffer->GetCurrentHostPointer() + MAXVBUFFERSIZE; m_end_buffer_pointer = m_vertex_stream_buffer->GetCurrentHostPointer() + MAXVBUFFERSIZE;
m_cur_buffer_pointer = m_vertex_stream_buffer->GetCurrentHostPointer(); m_cur_buffer_pointer = m_vertex_stream_buffer->GetCurrentHostPointer();
IndexGenerator::Start(reinterpret_cast<u16*>(m_index_stream_buffer->GetCurrentHostPointer())); m_index_generator.Start(reinterpret_cast<u16*>(m_index_stream_buffer->GetCurrentHostPointer()));
} }
void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices,

View File

@ -17,9 +17,6 @@ namespace
{ {
constexpr u16 s_primitive_restart = UINT16_MAX; constexpr u16 s_primitive_restart = UINT16_MAX;
using PrimitiveFunction = u16*(*)(u16*, u32, u32);
std::array<PrimitiveFunction, 8> s_primitive_table;
template <bool pr> template <bool pr>
u16* WriteTriangle(u16* index_ptr, u32 index1, u32 index2, u32 index3) u16* WriteTriangle(u16* index_ptr, u32 index1, u32 index2, u32 index3)
{ {
@ -204,56 +201,54 @@ u16* AddPoints(u16* index_ptr, u32 num_verts, u32 index)
} }
} // Anonymous namespace } // Anonymous namespace
// Init
u16* IndexGenerator::index_buffer_current;
u16* IndexGenerator::BASEIptr;
u32 IndexGenerator::base_index;
void IndexGenerator::Init() void IndexGenerator::Init()
{ {
if (g_Config.backend_info.bSupportsPrimitiveRestart) if (g_Config.backend_info.bSupportsPrimitiveRestart)
{ {
s_primitive_table[OpcodeDecoder::GX_DRAW_QUADS] = AddQuads<true>; m_primitive_table[OpcodeDecoder::GX_DRAW_QUADS] = AddQuads<true>;
s_primitive_table[OpcodeDecoder::GX_DRAW_QUADS_2] = AddQuads_nonstandard<true>; m_primitive_table[OpcodeDecoder::GX_DRAW_QUADS_2] = AddQuads_nonstandard<true>;
s_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLES] = AddList<true>; m_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLES] = AddList<true>;
s_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLE_STRIP] = AddStrip<true>; m_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLE_STRIP] = AddStrip<true>;
s_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLE_FAN] = AddFan<true>; m_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLE_FAN] = AddFan<true>;
} }
else else
{ {
s_primitive_table[OpcodeDecoder::GX_DRAW_QUADS] = AddQuads<false>; m_primitive_table[OpcodeDecoder::GX_DRAW_QUADS] = AddQuads<false>;
s_primitive_table[OpcodeDecoder::GX_DRAW_QUADS_2] = AddQuads_nonstandard<false>; m_primitive_table[OpcodeDecoder::GX_DRAW_QUADS_2] = AddQuads_nonstandard<false>;
s_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLES] = AddList<false>; m_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLES] = AddList<false>;
s_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLE_STRIP] = AddStrip<false>; m_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLE_STRIP] = AddStrip<false>;
s_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLE_FAN] = AddFan<false>; m_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLE_FAN] = AddFan<false>;
} }
s_primitive_table[OpcodeDecoder::GX_DRAW_LINES] = AddLineList; m_primitive_table[OpcodeDecoder::GX_DRAW_LINES] = AddLineList;
s_primitive_table[OpcodeDecoder::GX_DRAW_LINE_STRIP] = AddLineStrip; m_primitive_table[OpcodeDecoder::GX_DRAW_LINE_STRIP] = AddLineStrip;
s_primitive_table[OpcodeDecoder::GX_DRAW_POINTS] = AddPoints; m_primitive_table[OpcodeDecoder::GX_DRAW_POINTS] = AddPoints;
} }
void IndexGenerator::Start(u16* Indexptr) void IndexGenerator::Start(u16* index_ptr)
{ {
index_buffer_current = Indexptr; m_index_buffer_current = index_ptr;
BASEIptr = Indexptr; m_base_index_ptr = index_ptr;
base_index = 0; m_base_index = 0;
} }
void IndexGenerator::AddIndices(int primitive, u32 numVerts) void IndexGenerator::AddIndices(int primitive, u32 num_vertices)
{ {
index_buffer_current = s_primitive_table[primitive](index_buffer_current, numVerts, base_index); m_index_buffer_current =
base_index += numVerts; m_primitive_table[primitive](m_index_buffer_current, num_vertices, m_base_index);
m_base_index += num_vertices;
} }
void IndexGenerator::AddExternalIndices(const u16* indices, u32 num_indices, u32 num_vertices) void IndexGenerator::AddExternalIndices(const u16* indices, u32 num_indices, u32 num_vertices)
{ {
std::memcpy(index_buffer_current, indices, sizeof(u16) * num_indices); std::memcpy(m_index_buffer_current, indices, sizeof(u16) * num_indices);
index_buffer_current += num_indices; m_index_buffer_current += num_indices;
base_index += num_vertices; m_base_index += num_vertices;
} }
u32 IndexGenerator::GetRemainingIndices() u32 IndexGenerator::GetRemainingIndices() const
{ {
u32 max_index = 65534; // -1 is reserved for primitive restart (ogl + dx11) // -1 is reserved for primitive restart (OGL + DX11)
return max_index - base_index; constexpr u32 max_index = 65534;
return max_index - m_base_index;
} }

View File

@ -7,26 +7,29 @@
#pragma once #pragma once
#include <array>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
class IndexGenerator class IndexGenerator
{ {
public: public:
// Init void Init();
static void Init(); void Start(u16* index_ptr);
static void Start(u16* Indexptr);
static void AddIndices(int primitive, u32 numVertices); void AddIndices(int primitive, u32 num_vertices);
static void AddExternalIndices(const u16* indices, u32 num_indices, u32 num_vertices); void AddExternalIndices(const u16* indices, u32 num_indices, u32 num_vertices);
// returns numprimitives // returns numprimitives
static u32 GetNumVerts() { return base_index; } u32 GetNumVerts() const { return m_base_index; }
static u32 GetIndexLen() { return (u32)(index_buffer_current - BASEIptr); } u32 GetIndexLen() const { return static_cast<u32>(m_index_buffer_current - m_base_index_ptr); }
static u32 GetRemainingIndices(); u32 GetRemainingIndices() const;
private: private:
static u16* index_buffer_current; u16* m_index_buffer_current = nullptr;
static u16* BASEIptr; u16* m_base_index_ptr = nullptr;
static u32 base_index; u32 m_base_index = 0;
using PrimitiveFunction = u16* (*)(u16*, u32, u32);
std::array<PrimitiveFunction, 8> m_primitive_table{};
}; };

View File

@ -283,8 +283,7 @@ int RunVertices(int vtx_attr_group, int primitive, int count, DataReader src, bo
count = loader->RunVertices(src, dst, count); count = loader->RunVertices(src, dst, count);
IndexGenerator::AddIndices(primitive, count); g_vertex_manager->AddIndices(primitive, count);
g_vertex_manager->FlushData(count, loader->m_native_vtx_decl.stride); g_vertex_manager->FlushData(count, loader->m_native_vtx_decl.stride);
ADDSTAT(g_stats.this_frame.num_prims, count); ADDSTAT(g_stats.this_frame.num_prims, count);

View File

@ -88,6 +88,7 @@ VertexManagerBase::~VertexManagerBase() = default;
bool VertexManagerBase::Initialize() bool VertexManagerBase::Initialize()
{ {
m_index_generator.Init();
return true; return true;
} }
@ -96,6 +97,11 @@ u32 VertexManagerBase::GetRemainingSize() const
return static_cast<u32>(m_end_buffer_pointer - m_cur_buffer_pointer); return static_cast<u32>(m_end_buffer_pointer - m_cur_buffer_pointer);
} }
void VertexManagerBase::AddIndices(int primitive, u32 num_vertices)
{
m_index_generator.AddIndices(primitive, num_vertices);
}
DataReader VertexManagerBase::PrepareForAdditionalData(int primitive, u32 count, u32 stride, DataReader VertexManagerBase::PrepareForAdditionalData(int primitive, u32 count, u32 stride,
bool cullall) bool cullall)
{ {
@ -120,12 +126,12 @@ DataReader VertexManagerBase::PrepareForAdditionalData(int primitive, u32 count,
// Check for size in buffer, if the buffer gets full, call Flush() // Check for size in buffer, if the buffer gets full, call Flush()
if (!m_is_flushed && if (!m_is_flushed &&
(count > IndexGenerator::GetRemainingIndices() || count > GetRemainingIndices(primitive) || (count > m_index_generator.GetRemainingIndices() || count > GetRemainingIndices(primitive) ||
needed_vertex_bytes > GetRemainingSize())) needed_vertex_bytes > GetRemainingSize()))
{ {
Flush(); Flush();
if (count > IndexGenerator::GetRemainingIndices()) if (count > m_index_generator.GetRemainingIndices())
ERROR_LOG(VIDEO, "Too little remaining index values. Use 32-bit or reset them on flush."); ERROR_LOG(VIDEO, "Too little remaining index values. Use 32-bit or reset them on flush.");
if (count > GetRemainingIndices(primitive)) if (count > GetRemainingIndices(primitive))
ERROR_LOG(VIDEO, "VertexManager: Buffer not large enough for all indices! " ERROR_LOG(VIDEO, "VertexManager: Buffer not large enough for all indices! "
@ -145,7 +151,7 @@ DataReader VertexManagerBase::PrepareForAdditionalData(int primitive, u32 count,
// This buffer isn't getting sent to the GPU. Just allocate it on the cpu. // This buffer isn't getting sent to the GPU. Just allocate it on the cpu.
m_cur_buffer_pointer = m_base_buffer_pointer = m_cpu_vertex_buffer.data(); m_cur_buffer_pointer = m_base_buffer_pointer = m_cpu_vertex_buffer.data();
m_end_buffer_pointer = m_base_buffer_pointer + m_cpu_vertex_buffer.size(); m_end_buffer_pointer = m_base_buffer_pointer + m_cpu_vertex_buffer.size();
IndexGenerator::Start(m_cpu_index_buffer.data()); m_index_generator.Start(m_cpu_index_buffer.data());
} }
else else
{ {
@ -163,9 +169,9 @@ void VertexManagerBase::FlushData(u32 count, u32 stride)
m_cur_buffer_pointer += count * stride; m_cur_buffer_pointer += count * stride;
} }
u32 VertexManagerBase::GetRemainingIndices(int primitive) u32 VertexManagerBase::GetRemainingIndices(int primitive) const
{ {
u32 index_len = MAXIBUFFERSIZE - IndexGenerator::GetIndexLen(); const u32 index_len = MAXIBUFFERSIZE - m_index_generator.GetIndexLen();
if (g_Config.backend_info.bSupportsPrimitiveRestart) if (g_Config.backend_info.bSupportsPrimitiveRestart)
{ {
@ -234,7 +240,7 @@ void VertexManagerBase::ResetBuffer(u32 vertex_stride)
m_base_buffer_pointer = m_cpu_vertex_buffer.data(); m_base_buffer_pointer = m_cpu_vertex_buffer.data();
m_cur_buffer_pointer = m_cpu_vertex_buffer.data(); m_cur_buffer_pointer = m_cpu_vertex_buffer.data();
m_end_buffer_pointer = m_base_buffer_pointer + m_cpu_vertex_buffer.size(); m_end_buffer_pointer = m_base_buffer_pointer + m_cpu_vertex_buffer.size();
IndexGenerator::Start(m_cpu_index_buffer.data()); m_index_generator.Start(m_cpu_index_buffer.data());
} }
void VertexManagerBase::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, void VertexManagerBase::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices,
@ -288,7 +294,7 @@ void VertexManagerBase::UploadUtilityVertices(const void* vertices, u32 vertex_s
m_cur_buffer_pointer += copy_size; m_cur_buffer_pointer += copy_size;
} }
if (indices) if (indices)
IndexGenerator::AddExternalIndices(indices, num_indices, num_vertices); m_index_generator.AddExternalIndices(indices, num_indices, num_vertices);
CommitBuffer(num_vertices, vertex_stride, num_indices, out_base_vertex, out_base_index); CommitBuffer(num_vertices, vertex_stride, num_indices, out_base_vertex, out_base_index);
} }
@ -413,9 +419,9 @@ void VertexManagerBase::Flush()
{ {
// Now the vertices can be flushed to the GPU. Everything following the CommitBuffer() call // Now the vertices can be flushed to the GPU. Everything following the CommitBuffer() call
// must be careful to not upload any utility vertices, as the binding will be lost otherwise. // must be careful to not upload any utility vertices, as the binding will be lost otherwise.
const u32 num_indices = IndexGenerator::GetIndexLen(); const u32 num_indices = m_index_generator.GetIndexLen();
u32 base_vertex, base_index; u32 base_vertex, base_index;
CommitBuffer(IndexGenerator::GetNumVerts(), CommitBuffer(m_index_generator.GetNumVerts(),
VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride(), num_indices, VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride(), num_indices,
&base_vertex, &base_index); &base_vertex, &base_index);

View File

@ -9,6 +9,7 @@
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/MathUtil.h" #include "Common/MathUtil.h"
#include "VideoCommon/IndexGenerator.h"
#include "VideoCommon/RenderState.h" #include "VideoCommon/RenderState.h"
#include "VideoCommon/ShaderCache.h" #include "VideoCommon/ShaderCache.h"
@ -65,6 +66,7 @@ public:
virtual bool Initialize(); virtual bool Initialize();
PrimitiveType GetCurrentPrimitiveType() const { return m_current_primitive_type; } PrimitiveType GetCurrentPrimitiveType() const { return m_current_primitive_type; }
void AddIndices(int primitive, u32 num_vertices);
DataReader PrepareForAdditionalData(int primitive, u32 count, u32 stride, bool cullall); DataReader PrepareForAdditionalData(int primitive, u32 count, u32 stride, bool cullall);
void FlushData(u32 count, u32 stride); void FlushData(u32 count, u32 stride);
@ -134,7 +136,7 @@ protected:
virtual void DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_vertex); virtual void DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_vertex);
u32 GetRemainingSize() const; u32 GetRemainingSize() const;
static u32 GetRemainingIndices(int primitive); u32 GetRemainingIndices(int primitive) const;
void CalculateZSlope(NativeVertexFormat* format); void CalculateZSlope(NativeVertexFormat* format);
void LoadTextures(); void LoadTextures();
@ -159,6 +161,8 @@ protected:
bool m_blending_state_changed = true; bool m_blending_state_changed = true;
bool m_cull_all = false; bool m_cull_all = false;
IndexGenerator m_index_generator;
private: private:
// Minimum number of draws per command buffer when attempting to preempt a readback operation. // 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; static constexpr u32 MINIMUM_DRAW_CALLS_PER_COMMAND_BUFFER_FOR_READBACK = 10;

View File

@ -270,7 +270,6 @@ void VideoBackendBase::InitializeShared()
PixelEngine::Init(); PixelEngine::Init();
BPInit(); BPInit();
VertexLoaderManager::Init(); VertexLoaderManager::Init();
IndexGenerator::Init();
VertexShaderManager::Init(); VertexShaderManager::Init();
GeometryShaderManager::Init(); GeometryShaderManager::Init();
PixelShaderManager::Init(); PixelShaderManager::Init();