diff --git a/CMakeLists.txt b/CMakeLists.txt index 9736b0347b..402a7900f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2087,6 +2087,7 @@ set(GPU_SOURCES GPU/GPUCommonHW.h GPU/GPUState.cpp GPU/GPUState.h + GPU/GPUStateSIMDUtil.h GPU/Math3D.cpp GPU/Math3D.h GPU/Software/BinManager.cpp diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index cbfe5b7c66..930eaf5c16 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -21,10 +21,12 @@ #include "Common/CPUDetect.h" #include "Common/Math/math_util.h" #include "Common/GPU/OpenGL/GLFeatures.h" +#include "Common/Math/CrossSIMD.h" #include "Core/Config.h" #include "Core/System.h" #include "GPU/GPUState.h" #include "GPU/Math3D.h" +#include "GPU/GPUStateSIMDUtil.h" #include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/GPUStateUtils.h" #include "GPU/Common/SoftwareTransformCommon.h" @@ -398,6 +400,7 @@ SoftwareTransformAction SoftwareTransform::Transform(const float projMtx[16], Li // Modifies the vertices in-place. Applies viewport and projection. // TODO: SIMD. void SoftwareTransform::ProjectVertices(TransformedVertex *transformed, int vertexCount) { +#if 0 Lin::Vec3 vpOffset(gstate.getViewportXCenter(), gstate.getViewportYCenter(), gstate.getViewportZCenter()); Lin::Vec3 vpScale(gstate.getViewportXScale(), gstate.getViewportYScale(), gstate.getViewportZScale()); @@ -411,6 +414,18 @@ void SoftwareTransform::ProjectVertices(TransformedVertex *transformed, int vert transformed[i].y = xyz.y; transformed[i].z = xyz.z; } +#else + const Vec4F32 vpOffset = GetViewportOffsetVec(gstate); + const Vec4F32 vpScale = GetViewportScaleVec(gstate); + // CrossSIMD implementation. + for (int i = 0; i < vertexCount; i++) { + Vec4F32 xyzw = Vec4F32::Load(&transformed[i].x); + Vec4F32 wRecip = Vec4F32::Splat(1.0f / transformed[i].pos_w); + Vec4F32 projected = xyzw * wRecip * vpScale + vpOffset; + // Now, we need to restore the W value as we'll still need it later. + projected.WithLane3From(xyzw).Store(&transformed[i].x); + } +#endif } SoftwareTransformAction SoftwareTransform::ProjectClipAndExpand(int prim, int vertexCount, u32 vertType, u16 *&inds, int indsSize, int &numDecodedVerts, int vertsSize, SoftwareTransformResult *result) { @@ -1065,7 +1080,7 @@ u32 NormalizeVertices(SimpleVertex *sverts, u8 *bufPtr, const u8 *inPtr, int low } // clip space to screen space -Vec3f ClipToScreen(const Vec4f& coords) { +static Vec3f ClipToScreen(const Vec4f& coords) { float xScale = gstate.getViewportXScale(); float xCenter = gstate.getViewportXCenter(); float yScale = gstate.getViewportYScale(); diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index 1ae4f38491..41f1384e4a 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -333,6 +333,7 @@ + diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index 389b88b0b5..585a95dfde 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -264,6 +264,9 @@ Common + + Common + diff --git a/GPU/GPUStateSIMDUtil.h b/GPU/GPUStateSIMDUtil.h new file mode 100644 index 0000000000..6dfd110b0b --- /dev/null +++ b/GPU/GPUStateSIMDUtil.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Common/Math/CrossSIMD.h" +#include "GPU/GPUState.h" + +inline Vec4F32 GetViewportOffsetVec(const GPUgstate &gstate) { + return Vec4F32::LoadF24x3_DontCare(&gstate.viewportxcenter); +} +inline Vec4F32 GetViewportScaleVec(const GPUgstate &gstate) { + return Vec4F32::LoadF24x3_DontCare(&gstate.viewportxscale); +}