diff options
Diffstat (limited to 'Source/Core/VideoCommon/VertexLoaderX64.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/VertexLoaderX64.cpp | 77 |
1 files changed, 48 insertions, 29 deletions
diff --git a/Source/Core/VideoCommon/VertexLoaderX64.cpp b/Source/Core/VideoCommon/VertexLoaderX64.cpp index 7a4929361d..aebba7680d 100644 --- a/Source/Core/VideoCommon/VertexLoaderX64.cpp +++ b/Source/Core/VideoCommon/VertexLoaderX64.cpp @@ -26,7 +26,9 @@ static const X64Reg dst_reg = ABI_PARAM2; static const X64Reg scratch1 = RAX; static const X64Reg scratch2 = ABI_PARAM3; static const X64Reg scratch3 = ABI_PARAM4; -static const X64Reg count_reg = R10; +// The remaining number of vertices to be processed. Starts at count - 1, and the final loop has it +// at 0. +static const X64Reg remaining_reg = R10; static const X64Reg skipped_reg = R11; static const X64Reg base_reg = RBX; @@ -114,6 +116,35 @@ int VertexLoaderX64::ReadVertex(OpArg data, VertexComponentFormat attribute, Com X64Reg coords = XMM0; + const auto write_zfreeze = [&]() { // zfreeze + if (native_format == &m_native_vtx_decl.position) + { + CMP(32, R(remaining_reg), Imm8(3)); + FixupBranch dont_store = J_CC(CC_AE); + // The position cache is composed of 3 rows of 4 floats each; since each float is 4 bytes, + // we need to scale by 4 twice to cover the 4 floats. + LEA(32, scratch3, MScaled(remaining_reg, SCALE_4, 0)); + MOVUPS(MPIC(VertexLoaderManager::position_cache.data(), scratch3, SCALE_4), coords); + SetJumpTarget(dont_store); + } + else if (native_format == &m_native_vtx_decl.normals[1]) + { + TEST(32, R(remaining_reg), R(remaining_reg)); + FixupBranch dont_store = J_CC(CC_NZ); + // For similar reasons, the cached tangent and binormal are 4 floats each + MOVUPS(MPIC(VertexLoaderManager::tangent_cache.data()), coords); + SetJumpTarget(dont_store); + } + else if (native_format == &m_native_vtx_decl.normals[2]) + { + CMP(32, R(remaining_reg), R(remaining_reg)); + FixupBranch dont_store = J_CC(CC_NZ); + // For similar reasons, the cached tangent and binormal are 4 floats each + MOVUPS(MPIC(VertexLoaderManager::binormal_cache.data()), coords); + SetJumpTarget(dont_store); + } + }; + int elem_size = GetElementSize(format); int load_bytes = elem_size * count_in; OpArg dest = MDisp(dst_reg, m_dst_ofs); @@ -202,7 +233,9 @@ int VertexLoaderX64::ReadVertex(OpArg data, VertexComponentFormat attribute, Com dest.AddMemOffset(sizeof(float)); // zfreeze - if (native_format == &m_native_vtx_decl.position) + if (native_format == &m_native_vtx_decl.position || + native_format == &m_native_vtx_decl.normals[1] || + native_format == &m_native_vtx_decl.normals[2]) { if (cpu_info.bSSE4_1) { @@ -217,16 +250,7 @@ int VertexLoaderX64::ReadVertex(OpArg data, VertexComponentFormat attribute, Com } } - // zfreeze - if (native_format == &m_native_vtx_decl.position) - { - CMP(32, R(count_reg), Imm8(3)); - FixupBranch dont_store = J_CC(CC_A); - LEA(32, scratch3, MScaled(count_reg, SCALE_4, -4)); - MOVUPS(MPIC(VertexLoaderManager::position_cache, scratch3, SCALE_4), coords); - SetJumpTarget(dont_store); - } - return load_bytes; + write_zfreeze(); } } @@ -251,15 +275,7 @@ int VertexLoaderX64::ReadVertex(OpArg data, VertexComponentFormat attribute, Com break; } - // zfreeze - if (native_format == &m_native_vtx_decl.position) - { - CMP(32, R(count_reg), Imm8(3)); - FixupBranch dont_store = J_CC(CC_A); - LEA(32, scratch3, MScaled(count_reg, SCALE_4, -4)); - MOVUPS(MPIC(VertexLoaderManager::position_cache, scratch3, SCALE_4), coords); - SetJumpTarget(dont_store); - } + write_zfreeze(); return load_bytes; } @@ -385,8 +401,8 @@ void VertexLoaderX64::ReadColor(OpArg data, VertexComponentFormat attribute, Col void VertexLoaderX64::GenerateVertexLoader() { - BitSet32 regs = {src_reg, dst_reg, scratch1, scratch2, - scratch3, count_reg, skipped_reg, base_reg}; + BitSet32 regs = {src_reg, dst_reg, scratch1, scratch2, + scratch3, remaining_reg, skipped_reg, base_reg}; regs &= ABI_ALL_CALLEE_SAVED; ABI_PushRegistersAndAdjustStack(regs, 0); @@ -394,7 +410,9 @@ void VertexLoaderX64::GenerateVertexLoader() PUSH(32, R(ABI_PARAM3)); // ABI_PARAM3 is one of the lower registers, so free it for scratch2. - MOV(32, R(count_reg), R(ABI_PARAM3)); + // We also have it end at a value of 0, to simplify indexing for zfreeze; + // this requires subtracting 1 at the start. + LEA(32, remaining_reg, MDisp(ABI_PARAM3, -1)); MOV(64, R(base_reg), R(ABI_PARAM4)); @@ -412,9 +430,10 @@ void VertexLoaderX64::GenerateVertexLoader() MOV(32, MDisp(dst_reg, m_dst_ofs), R(scratch1)); // zfreeze - CMP(32, R(count_reg), Imm8(3)); - FixupBranch dont_store = J_CC(CC_A); - MOV(32, MPIC(VertexLoaderManager::position_matrix_index, count_reg, SCALE_4), R(scratch1)); + CMP(32, R(remaining_reg), Imm8(3)); + FixupBranch dont_store = J_CC(CC_AE); + MOV(32, MPIC(VertexLoaderManager::position_matrix_index_cache.data(), remaining_reg, SCALE_4), + R(scratch1)); SetJumpTarget(dont_store); m_native_vtx_decl.posmtx.components = 4; @@ -513,8 +532,8 @@ void VertexLoaderX64::GenerateVertexLoader() const u8* cont = GetCodePtr(); ADD(64, R(src_reg), Imm32(m_src_ofs)); - SUB(32, R(count_reg), Imm8(1)); - J_CC(CC_NZ, loop_start); + SUB(32, R(remaining_reg), Imm8(1)); + J_CC(CC_AE, loop_start); // Get the original count. POP(32, R(ABI_RETURN)); |
