From 73f9a22e2ef8af906a116ad67f1054cc964ae3f0 Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Sat, 26 Jul 2014 01:10:44 +0200 Subject: [PATCH] VertexLoader: Remove global state dependency on g_nativeVertexFmt --- .../Core/VideoBackends/D3D/VertexManager.cpp | 17 ++-- .../Core/VideoBackends/OGL/VertexManager.cpp | 12 +-- Source/Core/VideoCommon/VertexLoader.cpp | 80 ++++++++----------- Source/Core/VideoCommon/VertexLoader.h | 8 +- .../Core/VideoCommon/VertexLoaderManager.cpp | 38 ++++++--- Source/Core/VideoCommon/VertexLoaderManager.h | 2 +- 6 files changed, 83 insertions(+), 74 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/VertexManager.cpp b/Source/Core/VideoBackends/D3D/VertexManager.cpp index 6ae5f17a3f..f6d7685a52 100644 --- a/Source/Core/VideoBackends/D3D/VertexManager.cpp +++ b/Source/Core/VideoBackends/D3D/VertexManager.cpp @@ -16,7 +16,7 @@ #include "VideoCommon/RenderBase.h" #include "VideoCommon/Statistics.h" #include "VideoCommon/TextureCacheBase.h" -#include "VideoCommon/VertexLoader.h" +#include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VertexShaderManager.h" #include "VideoCommon/VideoConfig.h" @@ -136,6 +136,7 @@ static const float LINE_PT_TEX_OFFSETS[8] = { void VertexManager::Draw(UINT stride) { + u32 components = VertexLoaderManager::GetCurrentVertexFormat()->m_components; D3D::context->IASetVertexBuffers(0, 1, &m_vertex_buffers[m_current_vertex_buffer], &stride, &m_vertex_draw_offset); D3D::context->IASetIndexBuffer(m_index_buffers[m_current_index_buffer], DXGI_FORMAT_R16_UINT, 0); @@ -157,7 +158,7 @@ void VertexManager::Draw(UINT stride) for (int i = 0; i < 8; ++i) texOffsetEnable[i] = bpmem.texcoords[i].s.line_offset; - if (m_lineShader.SetShader(g_nativeVertexFmt->m_components, lineWidth, + if (m_lineShader.SetShader(components, lineWidth, texOffset, vpWidth, vpHeight, texOffsetEnable)) { ((DX11::Renderer*)g_renderer)->ApplyCullDisable(); // Disable culling for lines and points @@ -181,7 +182,7 @@ void VertexManager::Draw(UINT stride) for (int i = 0; i < 8; ++i) texOffsetEnable[i] = bpmem.texcoords[i].s.point_offset; - if (m_pointShader.SetShader(g_nativeVertexFmt->m_components, pointSize, + if (m_pointShader.SetShader(components, pointSize, texOffset, vpWidth, vpHeight, texOffsetEnable)) { ((DX11::Renderer*)g_renderer)->ApplyCullDisable(); // Disable culling for lines and points @@ -197,21 +198,21 @@ void VertexManager::Draw(UINT stride) void VertexManager::vFlush(bool useDstAlpha) { + u32 components = VertexLoaderManager::GetCurrentVertexFormat()->m_components; if (!PixelShaderCache::SetShader( - useDstAlpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE, - g_nativeVertexFmt->m_components)) + useDstAlpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE, components)) { GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); return; } - if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components)) + if (!VertexShaderCache::SetShader(components)) { GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); return; } PrepareDrawBuffers(); - unsigned int stride = g_nativeVertexFmt->GetVertexStride(); - g_nativeVertexFmt->SetupVertexPointers(); + unsigned int stride = VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride(); + VertexLoaderManager::GetCurrentVertexFormat()->SetupVertexPointers(); g_renderer->ApplyState(useDstAlpha); Draw(stride); diff --git a/Source/Core/VideoBackends/OGL/VertexManager.cpp b/Source/Core/VideoBackends/OGL/VertexManager.cpp index 0ac59041b7..6dce46c239 100644 --- a/Source/Core/VideoBackends/OGL/VertexManager.cpp +++ b/Source/Core/VideoBackends/OGL/VertexManager.cpp @@ -24,7 +24,7 @@ #include "VideoCommon/IndexGenerator.h" #include "VideoCommon/PixelShaderManager.h" #include "VideoCommon/Statistics.h" -#include "VideoCommon/VertexLoader.h" +#include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VertexShaderGen.h" #include "VideoCommon/VertexShaderManager.h" #include "VideoCommon/VideoConfig.h" @@ -126,7 +126,7 @@ void VertexManager::Draw(u32 stride) void VertexManager::vFlush(bool useDstAlpha) { - GLVertexFormat *nativeVertexFmt = (GLVertexFormat*)g_nativeVertexFmt; + GLVertexFormat *nativeVertexFmt = (GLVertexFormat*)VertexLoaderManager::GetCurrentVertexFormat(); u32 stride = nativeVertexFmt->GetVertexStride(); if (m_last_vao != nativeVertexFmt->VAO) { @@ -144,18 +144,18 @@ void VertexManager::vFlush(bool useDstAlpha) // the same pass as regular rendering. if (useDstAlpha && dualSourcePossible) { - ProgramShaderCache::SetShader(DSTALPHA_DUAL_SOURCE_BLEND, g_nativeVertexFmt->m_components); + ProgramShaderCache::SetShader(DSTALPHA_DUAL_SOURCE_BLEND, nativeVertexFmt->m_components); } else { - ProgramShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components); + ProgramShaderCache::SetShader(DSTALPHA_NONE, nativeVertexFmt->m_components); } // upload global constants ProgramShaderCache::UploadConstants(); // setup the pointers - g_nativeVertexFmt->SetupVertexPointers(); + nativeVertexFmt->SetupVertexPointers(); GL_REPORT_ERRORD(); Draw(stride); @@ -163,7 +163,7 @@ void VertexManager::vFlush(bool useDstAlpha) // run through vertex groups again to set alpha if (useDstAlpha && !dualSourcePossible) { - ProgramShaderCache::SetShader(DSTALPHA_ALPHA_PASS,g_nativeVertexFmt->m_components); + ProgramShaderCache::SetShader(DSTALPHA_ALPHA_PASS, nativeVertexFmt->m_components); // only update alpha glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); diff --git a/Source/Core/VideoCommon/VertexLoader.cpp b/Source/Core/VideoCommon/VertexLoader.cpp index bb73193c04..9417b7e78f 100644 --- a/Source/Core/VideoCommon/VertexLoader.cpp +++ b/Source/Core/VideoCommon/VertexLoader.cpp @@ -22,7 +22,6 @@ #include "VideoCommon/VertexLoader_Position.h" #include "VideoCommon/VertexLoader_TextCoord.h" #include "VideoCommon/VertexLoaderManager.h" -#include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VideoCommon.h" #include "VideoCommon/VideoConfig.h" @@ -31,8 +30,6 @@ #define COMPILED_CODE_SIZE 4096 -NativeVertexFormat *g_nativeVertexFmt; - #ifndef _WIN32 #undef inline #define inline @@ -539,8 +536,7 @@ void VertexLoader::CompileVertexTranslator() // Position in pc vertex format. int nat_offset = 0; - PortableVertexDeclaration vtx_decl; - memset(&vtx_decl, 0, sizeof(vtx_decl)); + memset(&m_native_vtx_decl, 0, sizeof(m_native_vtx_decl)); // Position Matrix Index if (m_VtxDesc.PosMatIdx) @@ -572,11 +568,11 @@ void VertexLoader::CompileVertexTranslator() } m_VertexSize += VertexLoader_Position::GetSize(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements); nat_offset += 12; - vtx_decl.position.components = 3; - vtx_decl.position.enable = true; - vtx_decl.position.offset = 0; - vtx_decl.position.type = VAR_FLOAT; - vtx_decl.position.integer = false; + m_native_vtx_decl.position.components = 3; + m_native_vtx_decl.position.enable = true; + m_native_vtx_decl.position.offset = 0; + m_native_vtx_decl.position.type = VAR_FLOAT; + m_native_vtx_decl.position.integer = false; // Normals if (m_VtxDesc.Normal != NOT_PRESENT) @@ -598,11 +594,11 @@ void VertexLoader::CompileVertexTranslator() for (int i = 0; i < (vtx_attr.NormalElements ? 3 : 1); i++) { - vtx_decl.normals[i].components = 3; - vtx_decl.normals[i].enable = true; - vtx_decl.normals[i].offset = nat_offset; - vtx_decl.normals[i].type = VAR_FLOAT; - vtx_decl.normals[i].integer = false; + m_native_vtx_decl.normals[i].components = 3; + m_native_vtx_decl.normals[i].enable = true; + m_native_vtx_decl.normals[i].offset = nat_offset; + m_native_vtx_decl.normals[i].type = VAR_FLOAT; + m_native_vtx_decl.normals[i].integer = false; nat_offset += 12; } @@ -613,9 +609,9 @@ void VertexLoader::CompileVertexTranslator() for (int i = 0; i < 2; i++) { - vtx_decl.colors[i].components = 4; - vtx_decl.colors[i].type = VAR_UNSIGNED_BYTE; - vtx_decl.colors[i].integer = false; + m_native_vtx_decl.colors[i].components = 4; + m_native_vtx_decl.colors[i].type = VAR_UNSIGNED_BYTE; + m_native_vtx_decl.colors[i].integer = false; switch (col[i]) { case NOT_PRESENT: @@ -663,8 +659,8 @@ void VertexLoader::CompileVertexTranslator() if (col[i] != NOT_PRESENT) { components |= VB_HAS_COL0 << i; - vtx_decl.colors[i].offset = nat_offset; - vtx_decl.colors[i].enable = true; + m_native_vtx_decl.colors[i].offset = nat_offset; + m_native_vtx_decl.colors[i].enable = true; nat_offset += 4; } } @@ -672,9 +668,9 @@ void VertexLoader::CompileVertexTranslator() // Texture matrix indices (remove if corresponding texture coordinate isn't enabled) for (int i = 0; i < 8; i++) { - vtx_decl.texcoords[i].offset = nat_offset; - vtx_decl.texcoords[i].type = VAR_FLOAT; - vtx_decl.texcoords[i].integer = false; + m_native_vtx_decl.texcoords[i].offset = nat_offset; + m_native_vtx_decl.texcoords[i].type = VAR_FLOAT; + m_native_vtx_decl.texcoords[i].integer = false; const int format = m_VtxAttr.texCoord[i].Format; const int elements = m_VtxAttr.texCoord[i].Elements; @@ -696,18 +692,18 @@ void VertexLoader::CompileVertexTranslator() if (components & (VB_HAS_TEXMTXIDX0 << i)) { - vtx_decl.texcoords[i].enable = true; + m_native_vtx_decl.texcoords[i].enable = true; if (tc[i] != NOT_PRESENT) { // if texmtx is included, texcoord will always be 3 floats, z will be the texmtx index - vtx_decl.texcoords[i].components = 3; + m_native_vtx_decl.texcoords[i].components = 3; nat_offset += 12; WriteCall(m_VtxAttr.texCoord[i].Elements ? TexMtx_Write_Float : TexMtx_Write_Float2); } else { components |= VB_HAS_UV0 << i; // have to include since using now - vtx_decl.texcoords[i].components = 4; + m_native_vtx_decl.texcoords[i].components = 4; nat_offset += 16; // still include the texture coordinate, but this time as 6 + 2 bytes WriteCall(TexMtx_Write_Float4); } @@ -716,8 +712,8 @@ void VertexLoader::CompileVertexTranslator() { if (tc[i] != NOT_PRESENT) { - vtx_decl.texcoords[i].enable = true; - vtx_decl.texcoords[i].components = vtx_attr.texCoord[i].Elements ? 2 : 1; + m_native_vtx_decl.texcoords[i].enable = true; + m_native_vtx_decl.texcoords[i].components = vtx_attr.texCoord[i].Elements ? 2 : 1; nat_offset += 4 * (vtx_attr.texCoord[i].Elements ? 2 : 1); } } @@ -746,16 +742,16 @@ void VertexLoader::CompileVertexTranslator() if (m_VtxDesc.PosMatIdx) { WriteCall(PosMtx_Write); - vtx_decl.posmtx.components = 4; - vtx_decl.posmtx.enable = true; - vtx_decl.posmtx.offset = nat_offset; - vtx_decl.posmtx.type = VAR_UNSIGNED_BYTE; - vtx_decl.posmtx.integer = true; + m_native_vtx_decl.posmtx.components = 4; + m_native_vtx_decl.posmtx.enable = true; + m_native_vtx_decl.posmtx.offset = nat_offset; + m_native_vtx_decl.posmtx.type = VAR_UNSIGNED_BYTE; + m_native_vtx_decl.posmtx.integer = true; nat_offset += 4; } - native_stride = nat_offset; - vtx_decl.stride = native_stride; + m_native_components = components; + m_native_vtx_decl.stride = nat_offset; #ifdef USE_VERTEX_LOADER_JIT // End loop here @@ -770,7 +766,6 @@ void VertexLoader::CompileVertexTranslator() ABI_PopAllCalleeSavedRegsAndAdjustStack(); RET(); #endif - m_NativeFmt = VertexLoaderManager::GetNativeVertexFormat(vtx_decl, components); } void VertexLoader::WriteCall(TPipelineFunction func) @@ -817,14 +812,6 @@ void VertexLoader::SetupRunVertices(const VAT& vat, int primitive, int const cou { m_numLoadedVertices += count; - // Flush if our vertex format is different from the currently set. - if (g_nativeVertexFmt != nullptr && g_nativeVertexFmt != m_NativeFmt) - { - VertexManager::Flush(); - // Also move the Set() here? - } - g_nativeVertexFmt = m_NativeFmt; - // Load position and texcoord scale factors. m_VtxAttr.PosFrac = vat.g0.PosFrac; m_VtxAttr.texCoord[0].Frac = vat.g0.Tex0Frac; @@ -837,7 +824,7 @@ void VertexLoader::SetupRunVertices(const VAT& vat, int primitive, int const cou m_VtxAttr.texCoord[7].Frac = vat.g2.Tex7Frac; posScale = fractionTable[m_VtxAttr.PosFrac]; - if (m_NativeFmt->m_components & VB_HAS_UVALL) + if (m_native_components & VB_HAS_UVALL) for (int i = 0; i < 8; i++) tcScale[i] = fractionTable[m_VtxAttr.texCoord[i].Frac]; for (int i = 0; i < 2; i++) @@ -879,7 +866,8 @@ void VertexLoader::RunVertices(const VAT& vat, int primitive, int const count) return; } SetupRunVertices(vat, primitive, count); - VertexManager::PrepareForAdditionalData(primitive, count, native_stride); + VertexManager::PrepareForAdditionalData(primitive, count, + m_native_vtx_decl.stride); ConvertVertices(count); IndexGenerator::AddIndices(primitive, count); diff --git a/Source/Core/VideoCommon/VertexLoader.h b/Source/Core/VideoCommon/VertexLoader.h index a438ba8933..8738b99963 100644 --- a/Source/Core/VideoCommon/VertexLoader.h +++ b/Source/Core/VideoCommon/VertexLoader.h @@ -24,7 +24,6 @@ #endif // They are used for the communication with the loader functions -extern NativeVertexFormat *g_nativeVertexFmt; extern int tcIndex; extern int colIndex; extern int colElements[2]; @@ -106,6 +105,9 @@ public: ~VertexLoader(); int GetVertexSize() const {return m_VertexSize;} + u32 GetNativeComponents() const { return m_native_components; } + const PortableVertexDeclaration& GetNativeVertexDeclaration() const + { return m_native_vtx_decl; } void SetupRunVertices(const VAT& vat, int primitive, int const count); void RunVertices(const VAT& vat, int primitive, int count); @@ -122,8 +124,8 @@ private: TVtxDesc m_VtxDesc; // Not really used currently - or well it is, but could be easily avoided. // PC vertex format - NativeVertexFormat *m_NativeFmt; - int native_stride; + u32 m_native_components; + PortableVertexDeclaration m_native_vtx_decl; #ifndef USE_VERTEX_LOADER_JIT // Pipeline. diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp index 16bb4689ac..d5e74a0e11 100644 --- a/Source/Core/VideoCommon/VertexLoaderManager.cpp +++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp @@ -12,11 +12,13 @@ #include "VideoCommon/Statistics.h" #include "VideoCommon/VertexLoader.h" #include "VideoCommon/VertexLoaderManager.h" +#include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VertexShaderManager.h" #include "VideoCommon/VideoCommon.h" static int s_attr_dirty; // bitfield +static NativeVertexFormat* s_current_vtx_fmt; static VertexLoader *g_VertexLoaders[8]; namespace std @@ -122,10 +124,34 @@ static VertexLoader* RefreshLoader(int vtx_attr_group) return g_VertexLoaders[vtx_attr_group]; } +static NativeVertexFormat* GetNativeVertexFormat(const PortableVertexDeclaration& format, + u32 components) +{ + auto& native = s_native_vertex_map[format]; + if (!native) + { + auto raw_pointer = g_vertex_manager->CreateNativeVertexFormat(); + native = std::unique_ptr(raw_pointer); + native->Initialize(format); + native->m_components = components; + } + return native.get(); +} + void RunVertices(int vtx_attr_group, int primitive, int count) { if (!count) return; + VertexLoader* loader = RefreshLoader(vtx_attr_group); + + // If the native vertex format changed, force a flush. + NativeVertexFormat* required_vtx_fmt = GetNativeVertexFormat( + loader->GetNativeVertexDeclaration(), + loader->GetNativeComponents()); + if (required_vtx_fmt != s_current_vtx_fmt) + VertexManager::Flush(); + s_current_vtx_fmt = required_vtx_fmt; + RefreshLoader(vtx_attr_group)->RunVertices(g_VtxAttr[vtx_attr_group], primitive, count); } @@ -134,17 +160,9 @@ int GetVertexSize(int vtx_attr_group) return RefreshLoader(vtx_attr_group)->GetVertexSize(); } -NativeVertexFormat* GetNativeVertexFormat(const PortableVertexDeclaration& format, u32 components) +NativeVertexFormat* GetCurrentVertexFormat() { - auto& native = s_native_vertex_map[format]; - if (!native) - { - auto raw_pointer = g_vertex_manager->CreateNativeVertexFormat(); - native = std::unique_ptr(raw_pointer); - native->m_components = components; - native->Initialize(format); - } - return native.get(); + return s_current_vtx_fmt; } } // namespace diff --git a/Source/Core/VideoCommon/VertexLoaderManager.h b/Source/Core/VideoCommon/VertexLoaderManager.h index 909701bf6d..17bf13c3ba 100644 --- a/Source/Core/VideoCommon/VertexLoaderManager.h +++ b/Source/Core/VideoCommon/VertexLoaderManager.h @@ -22,7 +22,7 @@ namespace VertexLoaderManager // For debugging void AppendListToString(std::string *dest); - NativeVertexFormat* GetNativeVertexFormat(const PortableVertexDeclaration& format, u32 components); + NativeVertexFormat* GetCurrentVertexFormat(); }; void RecomputeCachedArraybases();