diff --git a/GPU/Software/Clipper.cpp b/GPU/Software/Clipper.cpp index 70fa09066f..0a9c4da0e9 100644 --- a/GPU/Software/Clipper.cpp +++ b/GPU/Software/Clipper.cpp @@ -127,7 +127,7 @@ static void RotateUVThrough(const VertexData &tl, const VertexData &br, VertexDa } } -void ProcessTriangleInternal(VertexData &v0, VertexData &v1, VertexData &v2, const VertexData &provoking, bool fromRectangle); +void ProcessTriangleInternal(VertexData &v0, VertexData &v1, VertexData &v2, const VertexData &provoking, const PixelFuncID &pixelID, const SamplerID &samplerID, bool fromRectangle); static inline bool CheckOutsideZ(ClipCoords p, int &pos, int &neg) { constexpr float outsideValue = 1.000030517578125f; @@ -143,8 +143,7 @@ static inline bool CheckOutsideZ(ClipCoords p, int &pos, int &neg) { return false; } -void ProcessRect(const VertexData& v0, const VertexData& v1) -{ +void ProcessRect(const VertexData &v0, const VertexData &v1, const PixelFuncID &pixelID, const SamplerID &samplerID) { if (!gstate.isModeThrough()) { // We may discard the entire rect based on depth values. int outsidePos = 0, outsideNeg = 0; @@ -192,14 +191,14 @@ void ProcessRect(const VertexData& v0, const VertexData& v1) } // Four triangles to do backfaces as well. Two of them will get backface culled. - ProcessTriangleInternal(*topleft, *topright, *bottomright, buf[3], true); - ProcessTriangleInternal(*bottomright, *topright, *topleft, buf[3], true); - ProcessTriangleInternal(*bottomright, *bottomleft, *topleft, buf[3], true); - ProcessTriangleInternal(*topleft, *bottomleft, *bottomright, buf[3], true); + ProcessTriangleInternal(*topleft, *topright, *bottomright, buf[3], pixelID, samplerID, true); + ProcessTriangleInternal(*bottomright, *topright, *topleft, buf[3], pixelID, samplerID, true); + ProcessTriangleInternal(*bottomright, *bottomleft, *topleft, buf[3], pixelID, samplerID, true); + ProcessTriangleInternal(*topleft, *bottomleft, *bottomright, buf[3], pixelID, samplerID, true); } else { // through mode handling - if (Rasterizer::RectangleFastPath(v0, v1)) { + if (Rasterizer::RectangleFastPath(v0, v1, pixelID, samplerID)) { return; } @@ -241,28 +240,26 @@ void ProcessRect(const VertexData& v0, const VertexData& v1) RotateUVThrough(v0, v1, *topright, *bottomleft); if (gstate.isModeClear()) { - Rasterizer::ClearRectangle(v0, v1); + Rasterizer::ClearRectangle(v0, v1, pixelID, samplerID); } else { // Four triangles to do backfaces as well. Two of them will get backface culled. - Rasterizer::DrawTriangle(*topleft, *topright, *bottomleft); - Rasterizer::DrawTriangle(*bottomleft, *topright, *topleft); - Rasterizer::DrawTriangle(*topright, *bottomright, *bottomleft); - Rasterizer::DrawTriangle(*bottomleft, *bottomright, *topright); + Rasterizer::DrawTriangle(*topleft, *topright, *bottomleft, pixelID, samplerID); + Rasterizer::DrawTriangle(*bottomleft, *topright, *topleft, pixelID, samplerID); + Rasterizer::DrawTriangle(*topright, *bottomright, *bottomleft, pixelID, samplerID); + Rasterizer::DrawTriangle(*bottomleft, *bottomright, *topright, pixelID, samplerID); } } } -void ProcessPoint(VertexData& v0) -{ +void ProcessPoint(VertexData &v0, const PixelFuncID &pixelID, const SamplerID &samplerID) { // Points need no clipping. Will be bounds checked in the rasterizer (which seems backwards?) - Rasterizer::DrawPoint(v0); + Rasterizer::DrawPoint(v0, pixelID, samplerID); } -void ProcessLine(VertexData& v0, VertexData& v1) -{ +void ProcessLine(VertexData &v0, VertexData &v1, const PixelFuncID &pixelID, const SamplerID &samplerID) { if (gstate.isModeThrough()) { // Actually, should clip this one too so we don't need to do bounds checks in the rasterizer. - Rasterizer::DrawLine(v0, v1); + Rasterizer::DrawLine(v0, v1, pixelID, samplerID); return; } @@ -289,19 +286,19 @@ void ProcessLine(VertexData& v0, VertexData& v1) VertexData data[2] = { *Vertices[0], *Vertices[1] }; data[0].screenpos = TransformUnit::ClipToScreen(data[0].clippos); data[1].screenpos = TransformUnit::ClipToScreen(data[1].clippos); - Rasterizer::DrawLine(data[0], data[1]); + Rasterizer::DrawLine(data[0], data[1], pixelID, samplerID); } -void ProcessTriangleInternal(VertexData &v0, VertexData &v1, VertexData &v2, const VertexData &provoking, bool fromRectangle) { +void ProcessTriangleInternal(VertexData &v0, VertexData &v1, VertexData &v2, const VertexData &provoking, const PixelFuncID &pixelID, const SamplerID &samplerID, bool fromRectangle) { if (gstate.isModeThrough()) { // In case of cull reordering, make sure the right color is on the final vertex. if (gstate.getShadeMode() == GE_SHADE_FLAT) { VertexData corrected2 = v2; corrected2.color0 = provoking.color0; corrected2.color1 = provoking.color1; - Rasterizer::DrawTriangle(v0, v1, corrected2); + Rasterizer::DrawTriangle(v0, v1, corrected2, pixelID, samplerID); } else { - Rasterizer::DrawTriangle(v0, v1, v2); + Rasterizer::DrawTriangle(v0, v1, v2, pixelID, samplerID); } return; } @@ -385,13 +382,13 @@ void ProcessTriangleInternal(VertexData &v0, VertexData &v1, VertexData &v2, con data[2].color1 = provoking.color1; } - Rasterizer::DrawTriangle(data[0], data[1], data[2]); + Rasterizer::DrawTriangle(data[0], data[1], data[2], pixelID, samplerID); } } } -void ProcessTriangle(VertexData &v0, VertexData &v1, VertexData &v2, const VertexData &provoking) { - ProcessTriangleInternal(v0, v1, v2, provoking, false); +void ProcessTriangle(VertexData &v0, VertexData &v1, VertexData &v2, const VertexData &provoking, const PixelFuncID &pixelID, const SamplerID &samplerID) { + ProcessTriangleInternal(v0, v1, v2, provoking, pixelID, samplerID, false); } } // namespace diff --git a/GPU/Software/Clipper.h b/GPU/Software/Clipper.h index d00262001a..101d040e24 100644 --- a/GPU/Software/Clipper.h +++ b/GPU/Software/Clipper.h @@ -19,11 +19,14 @@ #include "TransformUnit.h" +struct PixelFuncID; +struct SamplerID; + namespace Clipper { -void ProcessPoint(VertexData& v0); -void ProcessLine(VertexData& v0, VertexData& v1); -void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2, const VertexData &provoking); -void ProcessRect(const VertexData& v0, const VertexData& v1); +void ProcessPoint(VertexData &v0, const PixelFuncID &pixelID, const SamplerID &samplerID); +void ProcessLine(VertexData &v0, VertexData &v1, const PixelFuncID &pixelID, const SamplerID &samplerID); +void ProcessTriangle(VertexData &v0, VertexData &v1, VertexData &v2, const VertexData &provoking, const PixelFuncID &pixelID, const SamplerID &samplerID); +void ProcessRect(const VertexData &v0, const VertexData &v1, const PixelFuncID &pixelID, const SamplerID &samplerID); } diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index ead96ef1fe..769eddc508 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -948,8 +948,7 @@ void DrawTriangleSlice( } // Draws triangle, vertices specified in counter-clockwise direction -void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData& v2) -{ +void DrawTriangle(const VertexData &v0, const VertexData &v1, const VertexData &v2, const PixelFuncID &pixelID, const SamplerID &samplerID) { PROFILE_THIS_SCOPE("draw_tri"); Vec2 d01((int)v0.screenpos.x - (int)v1.screenpos.x, (int)v0.screenpos.y - (int)v1.screenpos.y); @@ -983,10 +982,10 @@ void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData& int rangeY = (maxY - minY + 31) / 32; int rangeX = (maxX - minX + 31) / 32; - PixelFuncID pixelID; - ComputePixelFuncID(&pixelID); Rasterizer::SingleFunc drawPixel = Rasterizer::GetSingleFunc(pixelID); - Sampler::Funcs sampler = Sampler::GetFuncs(); + Sampler::Funcs sampler; + sampler.nearest = Sampler::GetNearestFunc(samplerID); + sampler.linear = Sampler::GetLinearFunc(samplerID); auto drawSlice = cpu_info.bSSE4_1 ? (gstate.isModeClear() ? &DrawTriangleSlice : &DrawTriangleSlice) : @@ -1020,8 +1019,7 @@ void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData& } } -void DrawPoint(const VertexData &v0) -{ +void DrawPoint(const VertexData &v0, const PixelFuncID &pixelID, const SamplerID &samplerID) { ScreenCoords pos = v0.screenpos; Vec4 prim_color = v0.color0; Vec3 sec_color = v0.color1; @@ -1036,8 +1034,6 @@ void DrawPoint(const VertexData &v0) return; Sampler::Funcs sampler = Sampler::GetFuncs(); - PixelFuncID pixelID; - ComputePixelFuncID(&pixelID); Rasterizer::SingleFunc drawPixel = Rasterizer::GetSingleFunc(pixelID); if (gstate.isTextureMapEnabled() && !pixelID.clearMode) { @@ -1115,8 +1111,7 @@ void DrawPoint(const VertexData &v0) #endif } -void ClearRectangle(const VertexData &v0, const VertexData &v1) -{ +void ClearRectangle(const VertexData &v0, const VertexData &v1, const PixelFuncID &pixelID, const SamplerID &samplerID) { int minX = std::min(v0.screenpos.x, v1.screenpos.x) & ~0xF; int minY = std::min(v0.screenpos.y, v1.screenpos.y) & ~0xF; int maxX = (std::max(v0.screenpos.x, v1.screenpos.x) + 0xF) & ~0xF; @@ -1144,7 +1139,7 @@ void ClearRectangle(const VertexData &v0, const VertexData &v1) gpuDebug->GetCurrentDisplayList(currentList); #endif - if (gstate.isClearModeDepthMask()) { + if (pixelID.DepthClear()) { const u16 z = v1.screenpos.z; const int stride = gstate.DepthBufStride(); @@ -1179,17 +1174,18 @@ void ClearRectangle(const VertexData &v0, const VertexData &v1) // Note: this stays 0xFFFFFFFF if keeping color and alpha, even for 16-bit. u32 keepOldMask = 0xFFFFFFFF; - if (gstate.isClearModeColorMask()) + if (pixelID.ColorClear()) keepOldMask &= 0xFF000000; - if (gstate.isClearModeAlphaMask()) + if (pixelID.StencilClear()) keepOldMask &= 0x00FFFFFF; // The pixel write masks are respected in clear mode. - keepOldMask |= gstate.getColorMask(); + if (pixelID.applyColorWriteMask) + keepOldMask |= gstate.getColorMask(); const u32 new_color = v1.color0.ToRGBA(); u16 new_color16; - switch (gstate.FrameBufFormat()) { + switch (pixelID.FBFormat()) { case GE_FORMAT_565: new_color16 = RGBA8888ToRGB565(new_color); keepOldMask = keepOldMask == 0 ? 0 : (0xFFFF0000 | RGBA8888ToRGB565(keepOldMask)); @@ -1217,7 +1213,7 @@ void ClearRectangle(const VertexData &v0, const VertexData &v1) if (keepOldMask == 0) { const int stride = gstate.FrameBufStride(); - if (gstate.FrameBufFormat() == GE_FORMAT_8888) { + if (pixelID.FBFormat() == GE_FORMAT_8888) { const bool canMemsetColor = (new_color & 0xFF) == (new_color >> 8) && (new_color & 0xFFFF) == (new_color >> 16); if (canMemsetColor) { ParallelRangeLoop(&g_threadManager, [=](int y1, int y2) { @@ -1261,7 +1257,7 @@ void ClearRectangle(const VertexData &v0, const VertexData &v1) } else if (keepOldMask != 0xFFFFFFFF) { const int stride = gstate.FrameBufStride(); - if (gstate.FrameBufFormat() == GE_FORMAT_8888) { + if (pixelID.FBFormat() == GE_FORMAT_8888) { ParallelRangeLoop(&g_threadManager, [=](int y1, int y2) { DrawingCoords p = pprime; for (p.y = y1; p.y < y2; ++p.y) { @@ -1288,7 +1284,7 @@ void ClearRectangle(const VertexData &v0, const VertexData &v1) #if defined(SOFTGPU_MEMORY_TAGGING_DETAILED) || defined(SOFTGPU_MEMORY_TAGGING_BASIC) if (keepOldMask != 0xFFFFFFFF) { - uint32_t bpp = gstate.FrameBufFormat() == GE_FORMAT_8888 ? 4 : 2; + uint32_t bpp = pixelID.FBFormat() == GE_FORMAT_8888 ? 4 : 2; std::string tag = StringFromFormat("DisplayListX_%08x", currentList.pc); for (int y = pprime.y; y < pend.y; ++y) { uint32_t row = gstate.getFrameBufAddress() + y * gstate.FrameBufStride() * bpp; @@ -1298,8 +1294,7 @@ void ClearRectangle(const VertexData &v0, const VertexData &v1) #endif } -void DrawLine(const VertexData &v0, const VertexData &v1) -{ +void DrawLine(const VertexData &v0, const VertexData &v1, const PixelFuncID &pixelID, const SamplerID &samplerID) { // TODO: Use a proper line drawing algorithm that handles fractional endpoints correctly. Vec3 a(v0.screenpos.x, v0.screenpos.y, v0.screenpos.z); Vec3 b(v1.screenpos.x, v1.screenpos.y, v0.screenpos.z); @@ -1330,9 +1325,6 @@ void DrawLine(const VertexData &v0, const VertexData &v1) scissorBR.x += 15; scissorBR.y += 15; - PixelFuncID pixelID; - ComputePixelFuncID(&pixelID); - int texbufw[8] = {0}; int maxTexLevel = gstate.getTextureMaxLevel(); diff --git a/GPU/Software/Rasterizer.h b/GPU/Software/Rasterizer.h index 2bdc212702..8754df14c1 100644 --- a/GPU/Software/Rasterizer.h +++ b/GPU/Software/Rasterizer.h @@ -31,10 +31,10 @@ struct GPUDebugBuffer; namespace Rasterizer { // Draws a triangle if its vertices are specified in counter-clockwise order -void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData& v2); -void DrawPoint(const VertexData &v0); -void DrawLine(const VertexData &v0, const VertexData &v1); -void ClearRectangle(const VertexData &v0, const VertexData &v1); +void DrawTriangle(const VertexData &v0, const VertexData &v1, const VertexData &v2, const PixelFuncID &pixelID, const SamplerID &samplerID); +void DrawPoint(const VertexData &v0, const PixelFuncID &pixelID, const SamplerID &samplerID); +void DrawLine(const VertexData &v0, const VertexData &v1, const PixelFuncID &pixelID, const SamplerID &samplerID); +void ClearRectangle(const VertexData &v0, const VertexData &v1, const PixelFuncID &pixelID, const SamplerID &samplerID); bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer); bool GetCurrentTexture(GPUDebugBuffer &buffer, int level); diff --git a/GPU/Software/RasterizerRectangle.cpp b/GPU/Software/RasterizerRectangle.cpp index 4e35ed6b97..cf8775e6ed 100644 --- a/GPU/Software/RasterizerRectangle.cpp +++ b/GPU/Software/RasterizerRectangle.cpp @@ -77,7 +77,7 @@ static inline Vec4IntResult SOFTRAST_CALL ModulateRGBA(Vec4IntArg prim_in, Vec4I return ToVec4IntResult(out); } -void DrawSprite(const VertexData& v0, const VertexData& v1) { +void DrawSprite(const VertexData &v0, const VertexData &v1, const PixelFuncID &pixelID, const SamplerID &samplerID) { const u8 *texptr = nullptr; GETextureFormat texfmt = gstate.getTextureFormat(); @@ -86,12 +86,6 @@ void DrawSprite(const VertexData& v0, const VertexData& v1) { if (Memory::IsValidAddress(texaddr)) texptr = Memory::GetPointerUnchecked(texaddr); - // These look at gstate. - SamplerID samplerID; - ComputeSamplerID(&samplerID); - PixelFuncID pixelID; - ComputePixelFuncID(&pixelID); - ScreenCoords pprime(v0.screenpos.x, v0.screenpos.y, 0); Sampler::FetchFunc fetchFunc = Sampler::GetFetchFunc(samplerID); Sampler::NearestFunc nearestFunc = Sampler::GetNearestFunc(samplerID); @@ -285,7 +279,7 @@ static inline bool NoClampOrWrap(const Vec2f &tc) { } // Returns true if the normal path should be skipped. -bool RectangleFastPath(const VertexData &v0, const VertexData &v1) { +bool RectangleFastPath(const VertexData &v0, const VertexData &v1, const PixelFuncID &pixelID, const SamplerID &samplerID) { g_DarkStalkerStretch = DSStretch::Off; // Check for 1:1 texture mapping. In that case we can call DrawSprite. int xdiff = v1.screenpos.x - v0.screenpos.x; @@ -301,7 +295,7 @@ bool RectangleFastPath(const VertexData &v0, const VertexData &v1) { bool state_check = !gstate.isModeClear() && NoClampOrWrap(v0.texturecoords) && NoClampOrWrap(v1.texturecoords); // TODO: No mipmap levels? Might be a font at level 1... if ((coord_check || !gstate.isTextureMapEnabled()) && orient_check && state_check) { - Rasterizer::DrawSprite(v0, v1); + Rasterizer::DrawSprite(v0, v1, pixelID, samplerID); return true; } @@ -323,7 +317,7 @@ bool RectangleFastPath(const VertexData &v0, const VertexData &v1) { gstate.textureMapEnable &= ~1; VertexData newV1 = v1; newV1.color0 = Vec4(0, 0, 0, 255); - Rasterizer::DrawSprite(v0, newV1); + Rasterizer::DrawSprite(v0, newV1, pixelID, samplerID); gstate.textureMapEnable |= 1; } return true; diff --git a/GPU/Software/RasterizerRectangle.h b/GPU/Software/RasterizerRectangle.h index d6d08b597c..f6bc5f2988 100644 --- a/GPU/Software/RasterizerRectangle.h +++ b/GPU/Software/RasterizerRectangle.h @@ -14,7 +14,7 @@ namespace Rasterizer { // Returns true if the normal path should be skipped. - bool RectangleFastPath(const VertexData &v0, const VertexData &v1); + bool RectangleFastPath(const VertexData &v0, const VertexData &v1, const PixelFuncID &pixelID, const SamplerID &samplerID); bool DetectRectangleFromThroughModeStrip(const VertexData data[4]); bool DetectRectangleFromThroughModeFan(const VertexData *data, int c, int *tlIndex, int *brIndex); diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index 3e8a6a9ab0..72b0496b78 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -30,6 +30,7 @@ #include "GPU/Debugger/Debugger.h" #include "GPU/Software/TransformUnit.h" #include "GPU/Software/Clipper.h" +#include "GPU/Software/FuncId.h" #include "GPU/Software/Lighting.h" #include "GPU/Software/RasterizerRectangle.h" @@ -339,6 +340,11 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy // TODO: Do this in two passes - first process the vertices (before indexing/stripping), // then resolve the indices. This lets us avoid transforming shared vertices twice. + PixelFuncID pixelID; + ComputePixelFuncID(&pixelID); + SamplerID samplerID; + ComputeSamplerID(&samplerID); + bool outside_range_flag = false; switch (prim_type) { case GE_PRIM_POINTS: @@ -370,22 +376,22 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy case GE_PRIM_TRIANGLES: { if (!gstate.isCullEnabled() || gstate.isModeClear()) { - Clipper::ProcessTriangle(data[0], data[1], data[2], data[2]); - Clipper::ProcessTriangle(data[2], data[1], data[0], data[2]); + Clipper::ProcessTriangle(data[0], data[1], data[2], data[2], pixelID, samplerID); + Clipper::ProcessTriangle(data[2], data[1], data[0], data[2], pixelID, samplerID); } else if (!gstate.getCullMode()) { - Clipper::ProcessTriangle(data[2], data[1], data[0], data[2]); + Clipper::ProcessTriangle(data[2], data[1], data[0], data[2], pixelID, samplerID); } else { - Clipper::ProcessTriangle(data[0], data[1], data[2], data[2]); + Clipper::ProcessTriangle(data[0], data[1], data[2], data[2], pixelID, samplerID); } break; } case GE_PRIM_LINES: - Clipper::ProcessLine(data[0], data[1]); + Clipper::ProcessLine(data[0], data[1], pixelID, samplerID); break; case GE_PRIM_POINTS: - Clipper::ProcessPoint(data[0]); + Clipper::ProcessPoint(data[0], pixelID, samplerID); break; default: @@ -425,14 +431,14 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy } if (data_index == 4) { - Clipper::ProcessRect(data[0], data[1]); - Clipper::ProcessRect(data[2], data[3]); + Clipper::ProcessRect(data[0], data[1], pixelID, samplerID); + Clipper::ProcessRect(data[2], data[3], pixelID, samplerID); data_index = 0; } } if (data_index >= 2) { - Clipper::ProcessRect(data[0], data[1]); + Clipper::ProcessRect(data[0], data[1], pixelID, samplerID); data_index -= 2; } break; @@ -461,7 +467,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy --skip_count; } else { // We already incremented data_index, so data_index & 1 is previous one. - Clipper::ProcessLine(data[data_index & 1], data[(data_index & 1) ^ 1]); + Clipper::ProcessLine(data[data_index & 1], data[(data_index & 1) ^ 1], pixelID, samplerID); } } break; @@ -487,7 +493,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy // If a strip is effectively a rectangle, draw it as such! if (!outside_range_flag && Rasterizer::DetectRectangleFromThroughModeStrip(data)) { - Clipper::ProcessRect(data[0], data[3]); + Clipper::ProcessRect(data[0], data[3], pixelID, samplerID); break; } } @@ -515,14 +521,14 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy } if (!gstate.isCullEnabled() || gstate.isModeClear()) { - Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index]); - Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index]); + Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index], pixelID, samplerID); + Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index], pixelID, samplerID); } else if ((!gstate.getCullMode()) ^ ((data_index - 1) % 2)) { // We need to reverse the vertex order for each second primitive, // but we additionally need to do that for every primitive if CCW cullmode is used. - Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index]); + Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index], pixelID, samplerID); } else { - Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index]); + Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index], pixelID, samplerID); } } break; @@ -563,7 +569,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy int tl = -1, br = -1; if (!outside_range_flag && Rasterizer::DetectRectangleFromThroughModeFan(data, vertex_count, &tl, &br)) { - Clipper::ProcessRect(data[tl], data[br]); + Clipper::ProcessRect(data[tl], data[br], pixelID, samplerID); break; } } @@ -591,14 +597,14 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy } if (!gstate.isCullEnabled() || gstate.isModeClear()) { - Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index]); - Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index]); + Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index], pixelID, samplerID); + Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index], pixelID, samplerID); } else if ((!gstate.getCullMode()) ^ ((data_index - 1) % 2)) { // We need to reverse the vertex order for each second primitive, // but we additionally need to do that for every primitive if CCW cullmode is used. - Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index]); + Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index], pixelID, samplerID); } else { - Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index]); + Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index], pixelID, samplerID); } } break;