diff --git a/src/polyrenderer/drawers/poly_triangle.cpp b/src/polyrenderer/drawers/poly_triangle.cpp
index f75b5e43d3..0e834dee5f 100644
--- a/src/polyrenderer/drawers/poly_triangle.cpp
+++ b/src/polyrenderer/drawers/poly_triangle.cpp
@@ -169,16 +169,7 @@ void PolyTriangleThreadData::DrawElements(const PolyDrawArgs &drawargs, const vo
 		return;
 
 	TriDrawTriangleArgs args;
-	args.dest = dest;
-	args.pitch = dest_pitch;
-	args.clipright = dest_width;
-	args.clipbottom = dest_height;
 	args.uniforms = &drawargs;
-	args.destBgra = dest_bgra;
-	args.stencilbuffer = PolyStencilBuffer::Instance()->Values();
-	args.stencilpitch = PolyStencilBuffer::Instance()->Width();
-	args.zbuffer = PolyZBuffer::Instance()->Values();
-	args.depthOffset = weaponScene ? 1.0f : 0.0f;
 
 	ShadedTriVertex vert[3];
 	if (drawmode == PolyDrawMode::Triangles)
@@ -223,16 +214,7 @@ void PolyTriangleThreadData::DrawArray(const PolyDrawArgs &drawargs, const void
 		return;
 
 	TriDrawTriangleArgs args;
-	args.dest = dest;
-	args.pitch = dest_pitch;
-	args.clipright = dest_width;
-	args.clipbottom = dest_height;
 	args.uniforms = &drawargs;
-	args.destBgra = dest_bgra;
-	args.stencilbuffer = PolyStencilBuffer::Instance()->Values();
-	args.stencilpitch = PolyStencilBuffer::Instance()->Width();
-	args.zbuffer = PolyZBuffer::Instance()->Values();
-	args.depthOffset = weaponScene ? 1.0f : 0.0f;
 
 	int vinput = 0;
 
diff --git a/src/polyrenderer/drawers/poly_triangle.h b/src/polyrenderer/drawers/poly_triangle.h
index 132823af4e..fadc799d60 100644
--- a/src/polyrenderer/drawers/poly_triangle.h
+++ b/src/polyrenderer/drawers/poly_triangle.h
@@ -29,6 +29,8 @@
 #include "polyrenderer/drawers/poly_buffer.h"
 #include "polyrenderer/drawers/poly_draw_args.h"
 
+class PolyDrawerCommand;
+
 class PolyTriangleDrawer
 {
 public:
@@ -88,6 +90,13 @@ public:
 
 	static PolyTriangleThreadData *Get(DrawerThread *thread);
 
+	int dest_pitch = 0;
+	int dest_width = 0;
+	int dest_height = 0;
+	bool dest_bgra = false;
+	uint8_t *dest = nullptr;
+	bool weaponScene = false;
+
 private:
 	ShadedTriVertex ShadeVertex(const PolyDrawArgs &drawargs, const void *vertices, int index);
 	void DrawShadedTriangle(const ShadedTriVertex *vertices, bool ccw, TriDrawTriangleArgs *args);
@@ -99,14 +108,8 @@ private:
 	int viewport_y = 0;
 	int viewport_width = 0;
 	int viewport_height = 0;
-	int dest_pitch = 0;
-	int dest_width = 0;
-	int dest_height = 0;
-	bool dest_bgra = false;
-	uint8_t *dest = nullptr;
 	bool ccw = true;
 	bool twosided = false;
-	bool weaponScene = false;
 	const Mat4f *objectToClip = nullptr;
 	const Mat4f *objectToWorld = nullptr;
 	int modelFrame1 = -1;
@@ -116,7 +119,12 @@ private:
 	enum { max_additional_vertices = 16 };
 };
 
-class PolySetTransformCommand : public DrawerCommand
+class PolyDrawerCommand : public DrawerCommand
+{
+public:
+};
+
+class PolySetTransformCommand : public PolyDrawerCommand
 {
 public:
 	PolySetTransformCommand(const Mat4f *objectToClip, const Mat4f *objectToWorld);
@@ -128,7 +136,7 @@ private:
 	const Mat4f *objectToWorld;
 };
 
-class PolySetCullCCWCommand : public DrawerCommand
+class PolySetCullCCWCommand : public PolyDrawerCommand
 {
 public:
 	PolySetCullCCWCommand(bool ccw);
@@ -139,7 +147,7 @@ private:
 	bool ccw;
 };
 
-class PolySetTwoSidedCommand : public DrawerCommand
+class PolySetTwoSidedCommand : public PolyDrawerCommand
 {
 public:
 	PolySetTwoSidedCommand(bool twosided);
@@ -150,7 +158,7 @@ private:
 	bool twosided;
 };
 
-class PolySetWeaponSceneCommand : public DrawerCommand
+class PolySetWeaponSceneCommand : public PolyDrawerCommand
 {
 public:
 	PolySetWeaponSceneCommand(bool value);
@@ -161,7 +169,7 @@ private:
 	bool value;
 };
 
-class PolySetModelVertexShaderCommand : public DrawerCommand
+class PolySetModelVertexShaderCommand : public PolyDrawerCommand
 {
 public:
 	PolySetModelVertexShaderCommand(int frame1, int frame2, float interpolationFactor);
@@ -174,7 +182,7 @@ private:
 	float interpolationFactor;
 };
 
-class PolyClearStencilCommand : public DrawerCommand
+class PolyClearStencilCommand : public PolyDrawerCommand
 {
 public:
 	PolyClearStencilCommand(uint8_t value);
@@ -185,7 +193,7 @@ private:
 	uint8_t value;
 };
 
-class PolySetViewportCommand : public DrawerCommand
+class PolySetViewportCommand : public PolyDrawerCommand
 {
 public:
 	PolySetViewportCommand(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra);
@@ -204,7 +212,7 @@ private:
 	bool dest_bgra;
 };
 
-class DrawPolyTrianglesCommand : public DrawerCommand
+class DrawPolyTrianglesCommand : public PolyDrawerCommand
 {
 public:
 	DrawPolyTrianglesCommand(const PolyDrawArgs &args, const void *vertices, const unsigned int *elements, int count, PolyDrawMode mode);
@@ -219,7 +227,7 @@ private:
 	PolyDrawMode mode;
 };
 
-class DrawRectCommand : public DrawerCommand
+class DrawRectCommand : public PolyDrawerCommand
 {
 public:
 	DrawRectCommand(const RectDrawArgs &args) : args(args) { }
diff --git a/src/polyrenderer/drawers/screen_triangle.cpp b/src/polyrenderer/drawers/screen_triangle.cpp
index 5619756260..551753c207 100644
--- a/src/polyrenderer/drawers/screen_triangle.cpp
+++ b/src/polyrenderer/drawers/screen_triangle.cpp
@@ -60,9 +60,9 @@ void ScreenTriangle::Draw(const TriDrawTriangleArgs *args, PolyTriangleThreadDat
 	ShadedTriVertex *sortedVertices[3];
 	SortVertices(args, sortedVertices);
 
-	int clipright = args->clipright;
+	int clipright = thread->dest_width;
 	int cliptop = thread->numa_start_y;
-	int clipbottom = MIN(args->clipbottom, thread->numa_end_y);
+	int clipbottom = MIN(thread->dest_height, thread->numa_end_y);
 
 	int topY = (int)(sortedVertices[0]->y + 0.5f);
 	int midY = (int)(sortedVertices[1]->y + 0.5f);
@@ -148,13 +148,16 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa
 	void(*drawfunc)(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread);
 	float stepXW, v1X, v1Y, v1W, posXW;
 	uint8_t stencilTestValue, stencilWriteValue;
+	float *zbuffer;
 	float *zbufferLine;
+	uint8_t *stencilbuffer;
 	uint8_t *stencilLine;
+	int pitch;
 
 	if (OptT::Flags & SWTRI_WriteColor)
 	{
 		int bmode = (int)args->uniforms->BlendMode();
-		drawfunc = args->destBgra ? ScreenTriangle::SpanDrawers32[bmode] : ScreenTriangle::SpanDrawers8[bmode];
+		drawfunc = thread->dest_bgra ? ScreenTriangle::SpanDrawers32[bmode] : ScreenTriangle::SpanDrawers8[bmode];
 	}
 
 	if ((OptT::Flags & SWTRI_DepthTest) || (OptT::Flags & SWTRI_WriteDepth))
@@ -163,8 +166,17 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa
 		v1X = args->v1->x;
 		v1Y = args->v1->y;
 		v1W = args->v1->w;
+		zbuffer = PolyZBuffer::Instance()->Values();
 	}
 
+	if ((OptT::Flags & SWTRI_StencilTest) || (OptT::Flags & SWTRI_WriteStencil))
+	{
+		stencilbuffer = PolyStencilBuffer::Instance()->Values();
+	}
+
+	if ((OptT::Flags & SWTRI_StencilTest) || (OptT::Flags & SWTRI_WriteStencil) || (OptT::Flags & SWTRI_DepthTest) || (OptT::Flags & SWTRI_WriteDepth))
+		pitch = PolyStencilBuffer::Instance()->Width();
+
 	if (OptT::Flags & SWTRI_StencilTest)
 		stencilTestValue = args->uniforms->StencilTestValue();
 
@@ -178,15 +190,15 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa
 		int xend = edges[(y << 1) + 1];
 
 		if ((OptT::Flags & SWTRI_StencilTest) || (OptT::Flags & SWTRI_WriteStencil))
-			stencilLine = args->stencilbuffer + args->stencilpitch * y;
+			stencilLine = stencilbuffer + pitch * y;
 
 		if ((OptT::Flags & SWTRI_DepthTest) || (OptT::Flags & SWTRI_WriteDepth))
 		{
-			zbufferLine = args->zbuffer + args->stencilpitch * y;
+			zbufferLine = zbuffer + pitch * y;
 
 			float startX = x + (0.5f - v1X);
 			float startY = y + (0.5f - v1Y);
-			posXW = v1W + stepXW * startX + args->gradientY.W * startY + args->depthOffset;
+			posXW = v1W + stepXW * startX + args->gradientY.W * startY + (thread->weaponScene ? 1.0f : 0.0f);
 		}
 
 #ifndef NO_SSE
@@ -859,8 +871,8 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyT
 		_fuzzpos = swrenderer::fuzzpos;
 	}
 
-	uint32_t *dest = (uint32_t*)args->dest;
-	uint32_t *destLine = dest + args->pitch * y;
+	uint32_t *dest = (uint32_t*)thread->dest;
+	uint32_t *destLine = dest + thread->dest_pitch * y;
 
 	int sseend = x0;
 #ifndef NO_SSE
@@ -1286,8 +1298,8 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTr
 		_fuzzpos = swrenderer::fuzzpos;
 	}
 
-	uint8_t *dest = (uint8_t*)args->dest;
-	uint8_t *destLine = dest + args->pitch * y;
+	uint8_t *dest = (uint8_t*)thread->dest;
+	uint8_t *destLine = dest + thread->dest_pitch * y;
 
 	for (int x = x0; x < x1; x++)
 	{
diff --git a/src/polyrenderer/drawers/screen_triangle.h b/src/polyrenderer/drawers/screen_triangle.h
index 80fd24ce71..e99260a3f1 100644
--- a/src/polyrenderer/drawers/screen_triangle.h
+++ b/src/polyrenderer/drawers/screen_triangle.h
@@ -45,21 +45,12 @@ struct ScreenTriangleStepVariables
 
 struct TriDrawTriangleArgs
 {
-	uint8_t *dest;
-	int32_t pitch;
 	ShadedTriVertex *v1;
 	ShadedTriVertex *v2;
 	ShadedTriVertex *v3;
-	int32_t clipright;
-	int32_t clipbottom;
-	uint8_t *stencilbuffer;
-	int stencilpitch;
-	float *zbuffer;
 	const PolyDrawArgs *uniforms;
-	bool destBgra;
 	ScreenTriangleStepVariables gradientX;
 	ScreenTriangleStepVariables gradientY;
-	float depthOffset;
 
 	bool CalculateGradients()
 	{