From 63c62b277d6850279bd2a982535d5abde824e6e2 Mon Sep 17 00:00:00 2001 From: comex Date: Sun, 24 Aug 2014 23:53:28 -0400 Subject: Some changes to VertexLoaderManager: - Lazily create the native vertex format (which involves GL calls) from RunVertices rather than RefreshLoader itself, freeing the latter to be run from the CPU thread (hopefully). - In order to avoid useless allocations while doing so, store the native format inside the VertexLoader rather than using a cache entry. - Wrap the s_vertex_loader_map in a lock, for similar reasons. --- Source/Core/VideoCommon/VertexLoader.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'Source/Core/VideoCommon/VertexLoader.cpp') diff --git a/Source/Core/VideoCommon/VertexLoader.cpp b/Source/Core/VideoCommon/VertexLoader.cpp index 7f7dbc9030..7876e050c2 100644 --- a/Source/Core/VideoCommon/VertexLoader.cpp +++ b/Source/Core/VideoCommon/VertexLoader.cpp @@ -548,6 +548,7 @@ VertexLoader::VertexLoader(const TVtxDesc &vtx_desc, const VAT &vtx_attr) m_compiledCode = nullptr; m_numLoadedVertices = 0; m_VertexSize = 0; + m_native_vertex_format = nullptr; loop_counter = 0; VertexLoader_Normal::Init(); VertexLoader_Position::Init(); @@ -1035,3 +1036,22 @@ void VertexLoader::AppendToString(std::string *dest) const } dest->append(StringFromFormat(" - %i v\n", m_numLoadedVertices)); } + +NativeVertexFormat* VertexLoader::GetNativeVertexFormat() +{ + if (m_native_vertex_format) + return m_native_vertex_format; + auto& native = s_native_vertex_map[m_native_vtx_decl]; + if (!native) + { + auto raw_pointer = g_vertex_manager->CreateNativeVertexFormat(); + native = std::unique_ptr(raw_pointer); + native->Initialize(m_native_vtx_decl); + native->m_components = m_native_components; + } + m_native_vertex_format = native.get(); + return native.get(); + +} + +std::map> VertexLoader::s_native_vertex_map; -- cgit v1.2.3 From f8452ff50103a503546e57ec8c6fc7fd5fa92a29 Mon Sep 17 00:00:00 2001 From: comex Date: Tue, 26 Aug 2014 23:17:51 -0400 Subject: Fix threading issue with vertex loader JIT. VertexLoader::VertexLoader was setting loop_counter, a *static* variable, to 0. This was nonsensical, but harmless until I started to run it on a separate thread, where it had a chance of interfering with a running vertex translator. Switch to just using a register for the loop counter. --- Source/Core/VideoCommon/VertexLoader.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'Source/Core/VideoCommon/VertexLoader.cpp') diff --git a/Source/Core/VideoCommon/VertexLoader.cpp b/Source/Core/VideoCommon/VertexLoader.cpp index 7876e050c2..ebc57d8577 100644 --- a/Source/Core/VideoCommon/VertexLoader.cpp +++ b/Source/Core/VideoCommon/VertexLoader.cpp @@ -38,9 +38,6 @@ static u8 s_curtexmtx[8]; static int s_texmtxwrite = 0; static int s_texmtxread = 0; -static int loop_counter; - - // Vertex loaders read these. Although the scale ones should be baked into the shader. int tcIndex; int colIndex; @@ -549,7 +546,6 @@ VertexLoader::VertexLoader(const TVtxDesc &vtx_desc, const VAT &vtx_attr) m_numLoadedVertices = 0; m_VertexSize = 0; m_native_vertex_format = nullptr; - loop_counter = 0; VertexLoader_Normal::Init(); VertexLoader_Position::Init(); VertexLoader_TextCoord::Init(); @@ -585,8 +581,11 @@ void VertexLoader::CompileVertexTranslator() PanicAlert("Trying to recompile a vertex translator"); m_compiledCode = GetCodePtr(); - // We don't use any callee saved registers or anything but RAX. - ABI_PushRegistersAndAdjustStack(0, 8); + // We only use RAX (caller saved) and RBX (callee saved). + ABI_PushRegistersAndAdjustStack(1 << RBX, 8); + + // save count + MOV(64, R(RBX), R(ABI_PARAM1)); // Start loop here const u8 *loop_start = GetCodePtr(); @@ -843,11 +842,10 @@ void VertexLoader::CompileVertexTranslator() #ifdef USE_VERTEX_LOADER_JIT // End loop here - MOV(64, R(RAX), Imm64((u64)&loop_counter)); - SUB(32, MatR(RAX), Imm8(1)); + SUB(64, R(RBX), Imm8(1)); J_CC(CC_NZ, loop_start); - ABI_PopRegistersAndAdjustStack(0, 8); + ABI_PopRegistersAndAdjustStack(1 << RBX, 8); RET(); #endif } @@ -913,8 +911,7 @@ void VertexLoader::ConvertVertices ( int count ) #ifdef USE_VERTEX_LOADER_JIT if (count > 0) { - loop_counter = count; - ((void (*)())(void*)m_compiledCode)(); + ((void (*)(int))(void*)m_compiledCode)(count); } #else for (int s = 0; s < count; s++) -- cgit v1.2.3 From 90638c6806ac2c92b211e41b2abd257b4266f488 Mon Sep 17 00:00:00 2001 From: comex Date: Wed, 27 Aug 2014 22:37:08 -0400 Subject: Switch to an unordered_map as a micro-optimization. --- Source/Core/VideoCommon/VertexLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/VideoCommon/VertexLoader.cpp') diff --git a/Source/Core/VideoCommon/VertexLoader.cpp b/Source/Core/VideoCommon/VertexLoader.cpp index ebc57d8577..ab78e85f9e 100644 --- a/Source/Core/VideoCommon/VertexLoader.cpp +++ b/Source/Core/VideoCommon/VertexLoader.cpp @@ -1051,4 +1051,4 @@ NativeVertexFormat* VertexLoader::GetNativeVertexFormat() } -std::map> VertexLoader::s_native_vertex_map; +std::unordered_map> VertexLoader::s_native_vertex_map; -- cgit v1.2.3 From f0131c2e09faba0d65fa5b7360898e514e3636f5 Mon Sep 17 00:00:00 2001 From: comex Date: Wed, 27 Aug 2014 13:26:06 -0400 Subject: Mechanical changes to move most CP state to a struct rather than separate globals. The next commit will add a separate copy of the struct and the ability for LoadCPReg to work on it. --- Source/Core/VideoCommon/VertexLoader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Source/Core/VideoCommon/VertexLoader.cpp') diff --git a/Source/Core/VideoCommon/VertexLoader.cpp b/Source/Core/VideoCommon/VertexLoader.cpp index ab78e85f9e..b2f3cd7a4e 100644 --- a/Source/Core/VideoCommon/VertexLoader.cpp +++ b/Source/Core/VideoCommon/VertexLoader.cpp @@ -33,7 +33,7 @@ // Matrix components are first in GC format but later in PC format - we need to store it temporarily // when decoding each vertex. -static u8 s_curposmtx = MatrixIndexA.PosNormalMtxIdx; +static u8 s_curposmtx = g_main_cp_state.matrix_index_a.PosNormalMtxIdx; static u8 s_curtexmtx[8]; static int s_texmtxwrite = 0; static int s_texmtxread = 0; @@ -87,7 +87,7 @@ static void LOADERDECL PosMtx_Write() DataWrite(0); // Resetting current position matrix to default is needed for bbox to behave - s_curposmtx = (u8) MatrixIndexA.PosNormalMtxIdx; + s_curposmtx = (u8) g_main_cp_state.matrix_index_a.PosNormalMtxIdx; } static void LOADERDECL UpdateBoundingBoxPrepare() -- cgit v1.2.3