diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 3c61b5c93b5e..84315c74506d 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -102,6 +102,27 @@ static inline Vec4 Interpolate(const float &c0, const float &c1, const fl return Interpolate(c0, c1, c2, w0.Cast(), w1.Cast(), w2.Cast(), wsum_recip); } +void ComputeRasterizerState(RasterizerState *state) { + ComputePixelFuncID(&state->pixelID); + ComputeSamplerID(&state->samplerID); + state->drawPixel = Rasterizer::GetSingleFunc(state->pixelID); + state->linear = Sampler::GetLinearFunc(state->samplerID); + state->nearest = Sampler::GetNearestFunc(state->samplerID); + + int maxTexLevel = state->samplerID.hasAnyMips ? gstate.getTextureMaxLevel() : 0; + if (gstate.isTextureMapEnabled() && !state->pixelID.clearMode) { + GETextureFormat texfmt = state->samplerID.TexFmt(); + for (int i = 0; i <= maxTexLevel; i++) { + u32 texaddr = gstate.getTextureAddress(i); + state->texbufw[i] = GetTextureBufw(i, texaddr, texfmt); + if (Memory::IsValidAddress(texaddr)) + state->texptr[i] = Memory::GetPointerUnchecked(texaddr); + else + state->texptr[i] = nullptr; + } + } +} + static inline u8 ClampFogDepth(float fogdepth) { union FloatBits { float f; @@ -478,7 +499,7 @@ Vec3 AlphaBlendingResult(const PixelFuncID &pixelID, const Vec4 &sourc } } -static inline Vec4IntResult SOFTRAST_CALL ApplyTexturing(float s, float t, int x, int y, Vec4IntArg prim_color, u8 *texptr[], int texbufw[], int texlevel, int frac_texlevel, bool bilinear, const RasterizerState &state) { +static inline Vec4IntResult SOFTRAST_CALL ApplyTexturing(float s, float t, int x, int y, Vec4IntArg prim_color, u8 *const texptr[], const int texbufw[], int texlevel, int frac_texlevel, bool bilinear, const RasterizerState &state) { const u8 **tptr0 = const_cast(&texptr[texlevel]); const int *bufw0 = &texbufw[texlevel]; @@ -488,7 +509,7 @@ static inline Vec4IntResult SOFTRAST_CALL ApplyTexturing(float s, float t, int x return state.linear(s, t, x, y, prim_color, tptr0, bufw0, texlevel, frac_texlevel); } -static inline Vec4IntResult SOFTRAST_CALL ApplyTexturingSingle(float s, float t, int x, int y, Vec4IntArg prim_color, u8 *texptr[], int texbufw[], int texlevel, int frac_texlevel, bool bilinear, const RasterizerState &state) { +static inline Vec4IntResult SOFTRAST_CALL ApplyTexturingSingle(float s, float t, int x, int y, Vec4IntArg prim_color, u8 *const texptr[], const int texbufw[], int texlevel, int frac_texlevel, bool bilinear, const RasterizerState &state) { return ApplyTexturing(s, t, ((x & 15) + 1) / 2, ((y & 15) + 1) / 2, prim_color, texptr, texbufw, texlevel, frac_texlevel, bilinear, state); } @@ -555,7 +576,7 @@ static inline void CalculateSamplingParams(const float ds, const float dt, const } } -static inline void ApplyTexturing(const RasterizerState &state, Vec4 *prim_color, const Vec4 &mask, const Vec4 &s, const Vec4 &t, int maxTexLevel, u8 *texptr[], int texbufw[], int x, int y) { +static inline void ApplyTexturing(const RasterizerState &state, Vec4 *prim_color, const Vec4 &mask, const Vec4 &s, const Vec4 &t, int maxTexLevel, u8 *const texptr[], const int texbufw[], int x, int y) { float ds = s[1] - s[0]; float dt = t[2] - t[0]; @@ -750,23 +771,7 @@ void DrawTriangleSlice( Vec4 bias2 = Vec4::AssignToAll(IsRightSideOrFlatBottomLine(v2.screenpos.xy(), v0.screenpos.xy(), v1.screenpos.xy()) ? -1 : 0); const PixelFuncID &pixelID = state.pixelID; - - int texbufw[8]{}; - int maxTexLevel = state.samplerID.hasAnyMips ? gstate.getTextureMaxLevel() : 0; - u8 *texptr[8]{}; - - if (gstate.isTextureMapEnabled() && !clearMode) { - GETextureFormat texfmt = state.samplerID.TexFmt(); - for (int i = 0; i <= maxTexLevel; i++) { - u32 texaddr = gstate.getTextureAddress(i); - texbufw[i] = GetTextureBufw(i, texaddr, texfmt); - if (Memory::IsValidAddress(texaddr)) - texptr[i] = Memory::GetPointerUnchecked(texaddr); - else - texptr[i] = 0; - } - } TriangleEdge e0; TriangleEdge e1; @@ -872,7 +877,7 @@ void DrawTriangleSlice( GetTextureCoordinates(v0, v1, v2, w0, w1, w2, wsum_recip, s, t); } - ApplyTexturing(state, prim_color, mask, s, t, maxTexLevel, texptr, texbufw, curX, curY); + ApplyTexturing(state, prim_color, mask, s, t, maxTexLevel, state.texptr, state.texbufw, curX, curY); } if (!clearMode) { @@ -1029,20 +1034,7 @@ void DrawPoint(const VertexData &v0, const RasterizerState &state) { auto &samplerID = state.samplerID; if (gstate.isTextureMapEnabled() && !pixelID.clearMode) { - int texbufw[8] = {0}; - int maxTexLevel = samplerID.hasAnyMips ? gstate.getTextureMaxLevel() : 0; - u8 *texptr[8] = {NULL}; - - GETextureFormat texfmt = samplerID.TexFmt(); - for (int i = 0; i <= maxTexLevel; i++) { - u32 texaddr = gstate.getTextureAddress(i); - texbufw[i] = GetTextureBufw(i, texaddr, texfmt); - if (Memory::IsValidAddress(texaddr)) - texptr[i] = Memory::GetPointerUnchecked(texaddr); - else - texptr[i] = 0; - } float s = v0.texturecoords.s(); float t = v0.texturecoords.t(); @@ -1059,7 +1051,7 @@ void DrawPoint(const VertexData &v0, const RasterizerState &state) { bool bilinear; CalculateSamplingParams(0.0f, 0.0f, maxTexLevel, texLevel, texLevelFrac, bilinear); PROFILE_THIS_SCOPE("sampler"); - prim_color = ApplyTexturingSingle(s, t, pos.x, pos.y, ToVec4IntArg(prim_color), texptr, texbufw, texLevel, texLevelFrac, bilinear, state); + prim_color = ApplyTexturingSingle(s, t, pos.x, pos.y, ToVec4IntArg(prim_color), state.texptr, state.texbufw, texLevel, texLevelFrac, bilinear, state); } if (!pixelID.clearMode) @@ -1312,19 +1304,7 @@ void DrawLine(const VertexData &v0, const VertexData &v1, const RasterizerState scissorBR.x += 15; scissorBR.y += 15; - int texbufw[8] = {0}; - int maxTexLevel = state.samplerID.hasAnyMips ? gstate.getTextureMaxLevel() : 0; - u8 *texptr[8] = {NULL}; - - if (gstate.isTextureMapEnabled() && !state.pixelID.clearMode) { - GETextureFormat texfmt = state.samplerID.TexFmt(); - for (int i = 0; i <= maxTexLevel; i++) { - u32 texaddr = gstate.getTextureAddress(i); - texbufw[i] = GetTextureBufw(i, texaddr, texfmt); - texptr[i] = Memory::GetPointer(texaddr); - } - } auto &pixelID = state.pixelID; auto &samplerID = state.samplerID; @@ -1401,7 +1381,7 @@ void DrawLine(const VertexData &v0, const VertexData &v1, const RasterizerState } PROFILE_THIS_SCOPE("sampler"); - prim_color = ApplyTexturingSingle(s, t, x, y, ToVec4IntArg(prim_color), texptr, texbufw, texLevel, texLevelFrac, texBilinear, state); + prim_color = ApplyTexturingSingle(s, t, x, y, ToVec4IntArg(prim_color), state.texptr, state.texbufw, texLevel, texLevelFrac, texBilinear, state); } if (!pixelID.clearMode) diff --git a/GPU/Software/Rasterizer.h b/GPU/Software/Rasterizer.h index 696d619daa29..59e2d390c9e2 100644 --- a/GPU/Software/Rasterizer.h +++ b/GPU/Software/Rasterizer.h @@ -38,8 +38,12 @@ struct RasterizerState { SingleFunc drawPixel; Sampler::LinearFunc linear; Sampler::NearestFunc nearest; + int texbufw[8]{}; + u8 *texptr[8]{}; }; +void ComputeRasterizerState(RasterizerState *state); + // Draws a triangle if its vertices are specified in counter-clockwise order void DrawTriangle(const VertexData &v0, const VertexData &v1, const VertexData &v2, const RasterizerState &state); void DrawPoint(const VertexData &v0, const RasterizerState &state); diff --git a/GPU/Software/RasterizerRectangle.cpp b/GPU/Software/RasterizerRectangle.cpp index 7b140463c38d..795674c5e189 100644 --- a/GPU/Software/RasterizerRectangle.cpp +++ b/GPU/Software/RasterizerRectangle.cpp @@ -78,13 +78,10 @@ static inline Vec4IntResult SOFTRAST_CALL ModulateRGBA(Vec4IntArg prim_in, Vec4I } void DrawSprite(const VertexData &v0, const VertexData &v1, const RasterizerState &state) { - const u8 *texptr = nullptr; + const u8 *texptr = state.texptr[0]; GETextureFormat texfmt = state.samplerID.TexFmt(); - u32 texaddr = gstate.getTextureAddress(0); - int texbufw = GetTextureBufw(0, texaddr, texfmt); - if (Memory::IsValidAddress(texaddr)) - texptr = Memory::GetPointerUnchecked(texaddr); + int texbufw = state.texbufw[0]; ScreenCoords pprime(v0.screenpos.x, v0.screenpos.y, 0); Sampler::FetchFunc fetchFunc = Sampler::GetFetchFunc(state.samplerID); diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index ef711785a777..0c490c205704 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -27,6 +27,7 @@ #include "GPU/Common/DrawEngineCommon.h" #include "GPU/Common/VertexDecoderCommon.h" #include "GPU/Common/SplineCommon.h" +#include "GPU/Common/TextureDecoder.h" #include "GPU/Debugger/Debugger.h" #include "GPU/Software/Clipper.h" #include "GPU/Software/FuncId.h" @@ -342,11 +343,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy // then resolve the indices. This lets us avoid transforming shared vertices twice. Rasterizer::RasterizerState state; - ComputePixelFuncID(&state.pixelID); - ComputeSamplerID(&state.samplerID); - state.drawPixel = Rasterizer::GetSingleFunc(state.pixelID); - state.linear = Sampler::GetLinearFunc(state.samplerID); - state.nearest = Sampler::GetNearestFunc(state.samplerID); + ComputeRasterizerState(&state); bool outside_range_flag = false; switch (prim_type) {