From bf38fd57b055c999d707cd0abb546443baa5dfd8 Mon Sep 17 00:00:00 2001
From: Magnus Norddahl <dpjudas@users.noreply.github.com>
Date: Sat, 12 Aug 2017 15:16:31 +0200
Subject: [PATCH] - Replace subsector gbuffer in softpoly with a zbuffer

---
 src/polyrenderer/drawers/poly_buffer.cpp     |   6 +-
 src/polyrenderer/drawers/poly_buffer.h       |   8 +-
 src/polyrenderer/drawers/poly_draw_args.h    |  15 +-
 src/polyrenderer/drawers/poly_triangle.cpp   |   2 +-
 src/polyrenderer/drawers/screen_triangle.cpp | 252 ++++++++++++-------
 src/polyrenderer/drawers/screen_triangle.h   |   2 +-
 src/polyrenderer/poly_renderer.cpp           |   2 +-
 src/polyrenderer/scene/poly_decal.cpp        |  15 +-
 src/polyrenderer/scene/poly_decal.h          |   4 +-
 src/polyrenderer/scene/poly_particle.cpp     |   7 +-
 src/polyrenderer/scene/poly_particle.h       |   2 +-
 src/polyrenderer/scene/poly_plane.cpp        |  23 +-
 src/polyrenderer/scene/poly_plane.h          |   6 +-
 src/polyrenderer/scene/poly_portal.h         |   3 +-
 src/polyrenderer/scene/poly_scene.cpp        |  12 +-
 src/polyrenderer/scene/poly_sky.cpp          |   1 -
 src/polyrenderer/scene/poly_sprite.cpp       |   7 +-
 src/polyrenderer/scene/poly_sprite.h         |   2 +-
 src/polyrenderer/scene/poly_wall.cpp         |  11 +-
 src/polyrenderer/scene/poly_wallsprite.cpp   |   6 +-
 src/polyrenderer/scene/poly_wallsprite.h     |   2 +-
 21 files changed, 222 insertions(+), 166 deletions(-)

diff --git a/src/polyrenderer/drawers/poly_buffer.cpp b/src/polyrenderer/drawers/poly_buffer.cpp
index 143d16bbdc..43e8731450 100644
--- a/src/polyrenderer/drawers/poly_buffer.cpp
+++ b/src/polyrenderer/drawers/poly_buffer.cpp
@@ -38,13 +38,13 @@
 
 /////////////////////////////////////////////////////////////////////////////
 
-PolySubsectorGBuffer *PolySubsectorGBuffer::Instance()
+PolyZBuffer *PolyZBuffer::Instance()
 {
-	static PolySubsectorGBuffer buffer;
+	static PolyZBuffer buffer;
 	return &buffer;
 }
 
-void PolySubsectorGBuffer::Resize(int newwidth, int newheight)
+void PolyZBuffer::Resize(int newwidth, int newheight)
 {
 	width = newwidth;
 	height = newheight;
diff --git a/src/polyrenderer/drawers/poly_buffer.h b/src/polyrenderer/drawers/poly_buffer.h
index a376cec464..a7c44c9c05 100644
--- a/src/polyrenderer/drawers/poly_buffer.h
+++ b/src/polyrenderer/drawers/poly_buffer.h
@@ -26,21 +26,21 @@
 
 struct TriVertex;
 
-class PolySubsectorGBuffer
+class PolyZBuffer
 {
 public:
-	static PolySubsectorGBuffer *Instance();
+	static PolyZBuffer *Instance();
 	void Resize(int newwidth, int newheight);
 	int Width() const { return width; }
 	int Height() const { return height; }
 	int BlockWidth() const { return (width + 7) / 8; }
 	int BlockHeight() const { return (height + 7) / 8; }
-	uint32_t *Values() { return values.data(); }
+	float *Values() { return values.data(); }
 
 private:
 	int width;
 	int height;
-	std::vector<uint32_t> values;
+	std::vector<float> values;
 };
 
 class PolyStencilBuffer
diff --git a/src/polyrenderer/drawers/poly_draw_args.h b/src/polyrenderer/drawers/poly_draw_args.h
index c90aaadd06..0d84d24dfb 100644
--- a/src/polyrenderer/drawers/poly_draw_args.h
+++ b/src/polyrenderer/drawers/poly_draw_args.h
@@ -53,12 +53,11 @@ public:
 	void SetTexture(FTexture *texture);
 	void SetTexture(FTexture *texture, uint32_t translationID, bool forcePal = false);
 	void SetLight(FSWColormap *basecolormap, uint32_t lightlevel, double globVis, bool fixed);
-	void SetSubsectorDepth(uint32_t subsectorDepth) { mSubsectorDepth = subsectorDepth; }
-	void SetSubsectorDepthTest(bool enable) { mSubsectorTest = enable; }
+	void SetDepthTest(bool enable) { mDepthTest = enable; }
 	void SetStencilTestValue(uint8_t stencilTestValue) { mStencilTestValue = stencilTestValue; }
 	void SetWriteColor(bool enable) { mWriteColor = enable; }
 	void SetWriteStencil(bool enable, uint8_t stencilWriteValue = 0) { mWriteStencil = enable; mStencilWriteValue = stencilWriteValue; }
-	void SetWriteSubsectorDepth(bool enable) { mWriteSubsector = enable; }
+	void SetWriteDepth(bool enable) { mWriteDepth = enable; }
 	void SetFaceCullCCW(bool counterclockwise) { mFaceCullCCW = counterclockwise; }
 	void SetStyle(TriBlendMode blendmode, double srcalpha = 1.0, double destalpha = 1.0) { mBlendMode = blendmode; mSrcAlpha = (uint32_t)(srcalpha * 256.0 + 0.5); mDestAlpha = (uint32_t)(destalpha * 256.0 + 0.5); }
 	void SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *texture, bool fullbright);
@@ -85,9 +84,8 @@ public:
 	uint8_t StencilTestValue() const { return mStencilTestValue; }
 	uint8_t StencilWriteValue() const { return mStencilWriteValue; }
 
-	bool SubsectorTest() const { return mSubsectorTest; }
-	bool WriteSubsector() const { return mWriteSubsector; }
-	uint32_t SubsectorDepth() const { return mSubsectorDepth; }
+	bool DepthTest() const { return mDepthTest; }
+	bool WriteDepth() const { return mWriteDepth; }
 
 	TriBlendMode BlendMode() const { return mBlendMode; }
 	uint32_t Color() const { return mColor; }
@@ -117,10 +115,10 @@ private:
 	int mVertexCount = 0;
 	PolyDrawMode mDrawMode = PolyDrawMode::Triangles;
 	bool mFaceCullCCW = false;
-	bool mSubsectorTest = false;
+	bool mDepthTest = false;
 	bool mWriteStencil = true;
 	bool mWriteColor = true;
-	bool mWriteSubsector = true;
+	bool mWriteDepth = true;
 	const uint8_t *mTexturePixels = nullptr;
 	int mTextureWidth = 0;
 	int mTextureHeight = 0;
@@ -131,7 +129,6 @@ private:
 	float mClipPlane[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
 	TriBlendMode mBlendMode = TriBlendMode::FillOpaque;
 	uint32_t mLight = 0;
-	uint32_t mSubsectorDepth = 0;
 	uint32_t mColor = 0;
 	uint32_t mSrcAlpha = 0;
 	uint32_t mDestAlpha = 0;
diff --git a/src/polyrenderer/drawers/poly_triangle.cpp b/src/polyrenderer/drawers/poly_triangle.cpp
index 1cf9609ccd..c411dff275 100644
--- a/src/polyrenderer/drawers/poly_triangle.cpp
+++ b/src/polyrenderer/drawers/poly_triangle.cpp
@@ -99,7 +99,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadD
 	args.stencilPitch = PolyStencilBuffer::Instance()->BlockWidth();
 	args.stencilValues = PolyStencilBuffer::Instance()->Values();
 	args.stencilMasks = PolyStencilBuffer::Instance()->Masks();
-	args.subsectorGBuffer = PolySubsectorGBuffer::Instance()->Values();
+	args.zbuffer = PolyZBuffer::Instance()->Values();
 
 	bool ccw = drawargs.FaceCullCCW();
 	const TriVertex *vinput = drawargs.Vertices();
diff --git a/src/polyrenderer/drawers/screen_triangle.cpp b/src/polyrenderer/drawers/screen_triangle.cpp
index 01dd16766b..f44c983e71 100644
--- a/src/polyrenderer/drawers/screen_triangle.cpp
+++ b/src/polyrenderer/drawers/screen_triangle.cpp
@@ -76,10 +76,9 @@ private:
 	int clipright;
 	int clipbottom;
 
-	// Subsector buffer
-	uint32_t * RESTRICT subsectorGBuffer;
-	uint32_t subsectorDepth;
-	int32_t subsectorPitch;
+	// Depth buffer
+	float * RESTRICT zbuffer;
+	int32_t zbufferPitch;
 
 	// Triangle bounding block
 	int minx, miny;
@@ -113,10 +112,10 @@ private:
 	void CoverageTest();
 	void StencilEqualTest();
 	void StencilGreaterEqualTest();
-	void SubsectorTest();
+	void DepthTest(const TriDrawTriangleArgs *args);
 	void ClipTest();
 	void StencilWrite();
-	void SubsectorWrite();
+	void DepthWrite(const TriDrawTriangleArgs *args);
 };
 
 TriangleBlock::TriangleBlock(const TriDrawTriangleArgs *args)
@@ -134,9 +133,8 @@ TriangleBlock::TriangleBlock(const TriDrawTriangleArgs *args)
 	stencilTestValue = args->uniforms->StencilTestValue();
 	stencilWriteValue = args->uniforms->StencilWriteValue();
 
-	subsectorGBuffer = args->subsectorGBuffer;
-	subsectorDepth = args->uniforms->SubsectorDepth();
-	subsectorPitch = args->stencilPitch;
+	zbuffer = args->zbuffer;
+	zbufferPitch = args->stencilPitch;
 
 	// 28.4 fixed-point coordinates
 #ifdef NO_SSE
@@ -235,10 +233,10 @@ void TriangleBlock::Loop(const TriDrawTriangleArgs *args, WorkerThreadData *thre
 	int core_skip = (num_cores - ((miny / q) - core) % num_cores) % num_cores;
 	int start_miny = miny + core_skip * q;
 
-	bool subsectorTest = args->uniforms->SubsectorTest();
+	bool depthTest = args->uniforms->DepthTest();
 	bool writeColor = args->uniforms->WriteColor();
 	bool writeStencil = args->uniforms->WriteStencil();
-	bool writeSubsector = args->uniforms->WriteSubsector();
+	bool writeDepth = args->uniforms->WriteDepth();
 
 	int bmode = (int)args->uniforms->BlendMode();
 	auto drawFunc = args->destBgra ? ScreenTriangle::TriDrawers32[bmode] : ScreenTriangle::TriDrawers8[bmode];
@@ -259,8 +257,8 @@ void TriangleBlock::Loop(const TriDrawTriangleArgs *args, WorkerThreadData *thre
 			if (Mask0 == 0 && Mask1 == 0)
 				continue;
 
-			// To do: make the stencil test use its own flag for comparison mode instead of abusing the subsector test..
-			if (!subsectorTest)
+			// To do: make the stencil test use its own flag for comparison mode instead of abusing the depth test..
+			if (!depthTest)
 			{
 				StencilEqualTest();
 				if (Mask0 == 0 && Mask1 == 0)
@@ -272,7 +270,7 @@ void TriangleBlock::Loop(const TriDrawTriangleArgs *args, WorkerThreadData *thre
 				if (Mask0 == 0 && Mask1 == 0)
 					continue;
 
-				SubsectorTest();
+				DepthTest(args);
 				if (Mask0 == 0 && Mask1 == 0)
 					continue;
 			}
@@ -281,34 +279,54 @@ void TriangleBlock::Loop(const TriDrawTriangleArgs *args, WorkerThreadData *thre
 				drawFunc(X, Y, Mask0, Mask1, args);
 			if (writeStencil)
 				StencilWrite();
-			if (writeSubsector)
-				SubsectorWrite();
+			if (writeDepth)
+				DepthWrite(args);
 		}
 	}
 }
 
 #ifdef NO_SSE
 
-void TriangleBlock::SubsectorTest()
+void TriangleBlock::DepthTest(const TriDrawTriangleArgs *args)
 {
-	int block = (X >> 3) + (Y >> 3) * subsectorPitch;
-	uint32_t *subsector = subsectorGBuffer + block * 64;
+	int block = (X >> 3) + (Y >> 3) * zbufferPitch;
+	float *depth = zbuffer + block * 64;
+
+	const TriVertex &v1 = *args->v1;
+
+	float stepXW = args->gradientX.W;
+	float stepYW = args->gradientY.W;
+	float posYW = v1.w + stepXW * (X - v1.x) + stepYW * (Y - v1.y);
+
 	uint32_t mask0 = 0;
 	uint32_t mask1 = 0;
 
-	for (int i = 0; i < 32; i++)
+	for (int iy = 0; iy < 4; iy++)
 	{
-		bool covered = *subsector >= subsectorDepth;
-		mask0 <<= 1;
-		mask0 |= (uint32_t)covered;
-		subsector++;
+		float posXW = posYW;
+		for (int ix = 0; ix < 8; ix++)
+		{
+			bool covered = *depth <= posXW;
+			mask0 <<= 1;
+			mask0 |= (uint32_t)covered;
+			depth++;
+			posXW += stepXW;
+		}
+		posYW += stepYW;
 	}
-	for (int i = 0; i < 32; i++)
+
+	for (int iy = 0; iy < 4; iy++)
 	{
-		bool covered = *subsector >= subsectorDepth;
-		mask1 <<= 1;
-		mask1 |= (uint32_t)covered;
-		subsector++;
+		float posXW = posYW;
+		for (int ix = 0; ix < 8; ix++)
+		{
+			bool covered = *depth <= posXW;
+			mask1 <<= 1;
+			mask1 |= (uint32_t)covered;
+			depth++;
+			posXW += stepXW;
+		}
+		posYW += stepYW;
 	}
 
 	Mask0 = Mask0 & mask0;
@@ -317,26 +335,50 @@ void TriangleBlock::SubsectorTest()
 
 #else
 
-void TriangleBlock::SubsectorTest()
+void TriangleBlock::DepthTest(const TriDrawTriangleArgs *args)
 {
-	int block = (X >> 3) + (Y >> 3) * subsectorPitch;
-	uint32_t *subsector = subsectorGBuffer + block * 64;
+	int block = (X >> 3) + (Y >> 3) * zbufferPitch;
+	float *depth = zbuffer + block * 64;
+
+	const TriVertex &v1 = *args->v1;
+
+	float stepXW = args->gradientX.W;
+	float stepYW = args->gradientY.W;
+	float posYW = v1.w + stepXW * (X - v1.x) + stepYW * (Y - v1.y);
+
+	__m128 mposYW = _mm_setr_ps(posYW, posYW + stepXW, posYW + stepXW + stepXW, posYW + stepXW + stepXW + stepXW);
+	__m128 mstepXW = _mm_set1_ps(stepXW * 4.0f);
+	__m128 mstepYW = _mm_set1_ps(stepYW);
+
 	uint32_t mask0 = 0;
 	uint32_t mask1 = 0;
-	__m128i msubsectorDepth = _mm_set1_epi32(subsectorDepth);
-	__m128i mnotxor = _mm_set1_epi32(0xffffffff);
 
-	for (int iy = 0; iy < 8; iy++)
+	for (int iy = 0; iy < 4; iy++)
 	{
-		mask0 <<= 4;
-		mask0 |= _mm_movemask_ps(_mm_castsi128_ps(_mm_shuffle_epi32(_mm_xor_si128(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)subsector), msubsectorDepth), mnotxor), _MM_SHUFFLE(0, 1, 2, 3))));
-		subsector += 4;
+		__m128 mposXW = mposYW;
+		for (int ix = 0; ix < 2; ix++)
+		{
+			__m128 covered = _mm_cmplt_ps(_mm_loadu_ps(depth), mposXW);
+			mask0 <<= 4;
+			mask0 |= _mm_movemask_ps(_mm_shuffle_ps(covered, covered, _MM_SHUFFLE(0, 1, 2, 3)));
+			depth += 4;
+			mposXW = _mm_add_ps(mposXW, mstepXW);
+		}
+		mposYW = _mm_add_ps(mposYW, mstepYW);
 	}
-	for (int iy = 0; iy < 8; iy++)
+
+	for (int iy = 0; iy < 4; iy++)
 	{
-		mask1 <<= 4;
-		mask1 |= _mm_movemask_ps(_mm_castsi128_ps(_mm_shuffle_epi32(_mm_xor_si128(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)subsector), msubsectorDepth), mnotxor), _MM_SHUFFLE(0, 1, 2, 3))));
-		subsector += 4;
+		__m128 mposXW = mposYW;
+		for (int ix = 0; ix < 2; ix++)
+		{
+			__m128 covered = _mm_cmplt_ps(_mm_loadu_ps(depth), mposXW);
+			mask1 <<= 4;
+			mask1 |= _mm_movemask_ps(_mm_shuffle_ps(covered, covered, _MM_SHUFFLE(0, 1, 2, 3)));
+			depth += 4;
+			mposXW = _mm_add_ps(mposXW, mstepXW);
+		}
+		mposYW = _mm_add_ps(mposYW, mstepYW);
 	}
 
 	Mask0 = Mask0 & mask0;
@@ -798,65 +840,91 @@ void TriangleBlock::StencilWrite()
 
 #ifdef NO_SSE
 
-void TriangleBlock::SubsectorWrite()
+void TriangleBlock::DepthWrite(const TriDrawTriangleArgs *args)
 {
-	int block = (X >> 3) + (Y >> 3) * subsectorPitch;
-	uint32_t *subsector = subsectorGBuffer + block * 64;
+	int block = (X >> 3) + (Y >> 3) * zbufferPitch;
+	float *depth = zbuffer + block * 64;
+
+	const TriVertex &v1 = *args->v1;
+
+	float stepXW = args->gradientX.W;
+	float stepYW = args->gradientY.W;
+	float posYW = v1.w + stepXW * (X - v1.x) + stepYW * (Y - v1.y);
 
 	if (Mask0 == 0xffffffff && Mask1 == 0xffffffff)
 	{
-		for (int i = 0; i < 64; i++)
+		for (int iy = 0; iy < 8; iy++)
 		{
-			*(subsector++) = subsectorDepth;
+			float posXW = posYW;
+			for (int ix = 0; ix < 8; ix++)
+			{
+				*(depth++) = posXW;
+				posXW += stepXW;
+			}
+			posYW += stepYW;
 		}
 	}
 	else
 	{
 		uint32_t mask0 = Mask0;
 		uint32_t mask1 = Mask1;
-		for (int i = 0; i < 32; i++)
+
+		for (int iy = 0; iy < 4; iy++)
 		{
-			if (mask0 & (1 << 31))
-				*subsector = subsectorDepth;
-			mask0 <<= 1;
-			subsector++;
+			float posXW = posYW;
+			for (int ix = 0; ix < 8; ix++)
+			{
+				if (mask0 & (1 << 31))
+					*depth = posXW;
+				posXW += stepXW;
+				mask0 <<= 1;
+				depth++;
+			}
+			posYW += stepYW;
 		}
-		for (int i = 0; i < 32; i++)
+
+		for (int iy = 0; iy < 4; iy++)
 		{
-			if (mask1 & (1 << 31))
-				*subsector = subsectorDepth;
-			mask1 <<= 1;
-			subsector++;
+			float posXW = posYW;
+			for (int ix = 0; ix < 8; ix++)
+			{
+				if (mask1 & (1 << 31))
+					*depth = posXW;
+				posXW += stepXW;
+				mask1 <<= 1;
+				depth++;
+			}
+			posYW += stepYW;
 		}
 	}
 }
 
 #else
 
-void TriangleBlock::SubsectorWrite()
+void TriangleBlock::DepthWrite(const TriDrawTriangleArgs *args)
 {
-	int block = (X >> 3) + (Y >> 3) * subsectorPitch;
-	uint32_t *subsector = subsectorGBuffer + block * 64;
-	__m128i msubsectorDepth = _mm_set1_epi32(subsectorDepth);
+	int block = (X >> 3) + (Y >> 3) * zbufferPitch;
+	float *depth = zbuffer + block * 64;
+
+	const TriVertex &v1 = *args->v1;
+
+	float stepXW = args->gradientX.W;
+	float stepYW = args->gradientY.W;
+	float posYW = v1.w + stepXW * (X - v1.x) + stepYW * (Y - v1.y);
+
+	__m128 mposYW = _mm_setr_ps(posYW, posYW + stepXW, posYW + stepXW + stepXW, posYW + stepXW + stepXW + stepXW);
+	__m128 mstepXW = _mm_set1_ps(stepXW * 4.0f);
+	__m128 mstepYW = _mm_set1_ps(stepYW);
 
 	if (Mask0 == 0xffffffff && Mask1 == 0xffffffff)
 	{
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth); subsector += 4;
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth); subsector += 4;
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth); subsector += 4;
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth); subsector += 4;
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth); subsector += 4;
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth); subsector += 4;
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth); subsector += 4;
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth); subsector += 4;
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth); subsector += 4;
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth); subsector += 4;
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth); subsector += 4;
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth); subsector += 4;
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth); subsector += 4;
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth); subsector += 4;
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth); subsector += 4;
-		_mm_storeu_si128((__m128i*)subsector, msubsectorDepth);
+		for (int iy = 0; iy < 8; iy++)
+		{
+			__m128 mposXW = mposYW;
+			_mm_storeu_ps(depth, mposXW); depth += 4; mposXW = _mm_add_ps(mposXW, mstepXW);
+			_mm_storeu_ps(depth, mposXW); depth += 4;
+			mposYW = _mm_add_ps(mposYW, mstepYW);
+		}
 	}
 	else
 	{
@@ -866,23 +934,21 @@ void TriangleBlock::SubsectorWrite()
 		__m128i mmask0 = _mm_set1_epi32(Mask0);
 		__m128i mmask1 = _mm_set1_epi32(Mask1);
 
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask0, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); mmask0 = _mm_slli_epi32(mmask0, 4); subsector += 4;
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask0, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); mmask0 = _mm_slli_epi32(mmask0, 4); subsector += 4;
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask0, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); mmask0 = _mm_slli_epi32(mmask0, 4); subsector += 4;
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask0, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); mmask0 = _mm_slli_epi32(mmask0, 4); subsector += 4;
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask0, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); mmask0 = _mm_slli_epi32(mmask0, 4); subsector += 4;
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask0, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); mmask0 = _mm_slli_epi32(mmask0, 4); subsector += 4;
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask0, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); mmask0 = _mm_slli_epi32(mmask0, 4); subsector += 4;
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask0, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); subsector += 4;
+		for (int iy = 0; iy < 4; iy++)
+		{
+			__m128 mposXW = mposYW;
+			_mm_maskmoveu_si128(_mm_castps_si128(mposXW), _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask0, topfour), _mm_setzero_si128()), mxormask), (char*)depth); mmask0 = _mm_slli_epi32(mmask0, 4); depth += 4; mposXW = _mm_add_ps(mposXW, mstepXW);
+			_mm_maskmoveu_si128(_mm_castps_si128(mposXW), _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask0, topfour), _mm_setzero_si128()), mxormask), (char*)depth); mmask0 = _mm_slli_epi32(mmask0, 4); depth += 4;
+			mposYW = _mm_add_ps(mposYW, mstepYW);
+		}
 
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask1, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); mmask1 = _mm_slli_epi32(mmask1, 4); subsector += 4;
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask1, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); mmask1 = _mm_slli_epi32(mmask1, 4); subsector += 4;
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask1, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); mmask1 = _mm_slli_epi32(mmask1, 4); subsector += 4;
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask1, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); mmask1 = _mm_slli_epi32(mmask1, 4); subsector += 4;
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask1, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); mmask1 = _mm_slli_epi32(mmask1, 4); subsector += 4;
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask1, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); mmask1 = _mm_slli_epi32(mmask1, 4); subsector += 4;
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask1, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); mmask1 = _mm_slli_epi32(mmask1, 4); subsector += 4;
-		_mm_maskmoveu_si128(msubsectorDepth, _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask1, topfour), _mm_setzero_si128()), mxormask), (char*)subsector); subsector += 4;
+		for (int iy = 0; iy < 4; iy++)
+		{
+			__m128 mposXW = mposYW;
+			_mm_maskmoveu_si128(_mm_castps_si128(mposXW), _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask1, topfour), _mm_setzero_si128()), mxormask), (char*)depth); mmask1 = _mm_slli_epi32(mmask1, 4); depth += 4; mposXW = _mm_add_ps(mposXW, mstepXW);
+			_mm_maskmoveu_si128(_mm_castps_si128(mposXW), _mm_xor_si128(_mm_cmpeq_epi32(_mm_and_si128(mmask1, topfour), _mm_setzero_si128()), mxormask), (char*)depth); mmask1 = _mm_slli_epi32(mmask1, 4); depth += 4;
+			mposYW = _mm_add_ps(mposYW, mstepYW);
+		}
 	}
 }
 
diff --git a/src/polyrenderer/drawers/screen_triangle.h b/src/polyrenderer/drawers/screen_triangle.h
index 4339edaf4b..98ea1146c5 100644
--- a/src/polyrenderer/drawers/screen_triangle.h
+++ b/src/polyrenderer/drawers/screen_triangle.h
@@ -60,7 +60,7 @@ struct TriDrawTriangleArgs
 	uint8_t *stencilValues;
 	uint32_t *stencilMasks;
 	int32_t stencilPitch;
-	uint32_t *subsectorGBuffer;
+	float *zbuffer;
 	const PolyDrawArgs *uniforms;
 	bool destBgra;
 	ScreenTriangleStepVariables gradientX;
diff --git a/src/polyrenderer/poly_renderer.cpp b/src/polyrenderer/poly_renderer.cpp
index fc119e65e2..53f051b1f9 100644
--- a/src/polyrenderer/poly_renderer.cpp
+++ b/src/polyrenderer/poly_renderer.cpp
@@ -159,7 +159,7 @@ void PolyRenderer::ClearBuffers()
 {
 	FrameMemory.Clear();
 	PolyStencilBuffer::Instance()->Clear(RenderTarget->GetWidth(), RenderTarget->GetHeight(), 0);
-	PolySubsectorGBuffer::Instance()->Resize(RenderTarget->GetPitch(), RenderTarget->GetHeight());
+	PolyZBuffer::Instance()->Resize(RenderTarget->GetPitch(), RenderTarget->GetHeight());
 	NextStencilValue = 0;
 }
 
diff --git a/src/polyrenderer/scene/poly_decal.cpp b/src/polyrenderer/scene/poly_decal.cpp
index 1c75384159..d619c13f57 100644
--- a/src/polyrenderer/scene/poly_decal.cpp
+++ b/src/polyrenderer/scene/poly_decal.cpp
@@ -31,7 +31,7 @@
 #include "a_sharedglobal.h"
 #include "swrenderer/scene/r_scene.h"
 
-void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue)
+void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, const seg_t *line, uint32_t stencilValue)
 {
 	if (line->linedef == nullptr && line->sidedef == nullptr)
 		return;
@@ -39,11 +39,11 @@ void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const PolyC
 	for (DBaseDecal *decal = line->sidedef->AttachedDecals; decal != nullptr; decal = decal->WallNext)
 	{
 		RenderPolyDecal render;
-		render.Render(worldToClip, clipPlane, decal, line, subsectorDepth, stencilValue);
+		render.Render(worldToClip, clipPlane, decal, line, stencilValue);
 	}
 }
 
-void RenderPolyDecal::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue)
+void RenderPolyDecal::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t stencilValue)
 {
 	if (decal->RenderFlags & RF_INVISIBLE || !viewactive || !decal->PicNum.isValid())
 		return;
@@ -62,6 +62,10 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, const PolyClipPlane &
 	DVector2 decal_pos = { dcx, dcy };
 
 	DVector2 angvec = (line->v2->fPos() - line->v1->fPos()).Unit();
+	DVector2 normal = { angvec.Y, -angvec.X };
+
+	decal_pos += normal;
+
 	DVector2 decal_left = decal_pos - edge_left * angvec;
 	DVector2 decal_right = decal_pos + edge_right * angvec;
 
@@ -139,7 +143,6 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, const PolyClipPlane &
 
 	PolyDrawArgs args;
 	args.SetLight(GetColorTable(front->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), fullbrightSprite);
-	args.SetSubsectorDepth(subsectorDepth);
 	args.SetColor(0xff000000 | decal->AlphaColor, decal->AlphaColor >> 24);
 	args.SetStyle(decal->RenderStyle, decal->Alpha, decal->AlphaColor, decal->Translation, tex, false);
 	args.SetTransform(&worldToClip);
@@ -147,8 +150,8 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, const PolyClipPlane &
 	args.SetStencilTestValue(stencilValue);
 	args.SetWriteStencil(true, stencilValue);
 	args.SetClipPlane(clipPlane);
-	args.SetSubsectorDepthTest(true);
+	args.SetDepthTest(true);
 	args.SetWriteStencil(false);
-	args.SetWriteSubsectorDepth(false);
+	args.SetWriteDepth(false);
 	args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
 }
diff --git a/src/polyrenderer/scene/poly_decal.h b/src/polyrenderer/scene/poly_decal.h
index a0d676951c..0cab330ca1 100644
--- a/src/polyrenderer/scene/poly_decal.h
+++ b/src/polyrenderer/scene/poly_decal.h
@@ -27,8 +27,8 @@
 class RenderPolyDecal
 {
 public:
-	static void RenderWallDecals(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue);
+	static void RenderWallDecals(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, const seg_t *line, uint32_t stencilValue);
 
 private:
-	void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue);
+	void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t stencilValue);
 };
diff --git a/src/polyrenderer/scene/poly_particle.cpp b/src/polyrenderer/scene/poly_particle.cpp
index ab80400dd7..1a67de786f 100644
--- a/src/polyrenderer/scene/poly_particle.cpp
+++ b/src/polyrenderer/scene/poly_particle.cpp
@@ -31,7 +31,7 @@
 
 EXTERN_CVAR(Int, gl_particles_style)
 
-void RenderPolyParticle::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue)
+void RenderPolyParticle::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t stencilValue)
 {
 	DVector3 pos = particle->Pos;
 	double psize = particle->size / 8.0;
@@ -75,15 +75,14 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, const PolyClipPlan
 
 	PolyDrawArgs args;
 	args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.ParticleGlobVis(foggy), fullbrightSprite);
-	args.SetSubsectorDepth(subsectorDepth);
-	args.SetSubsectorDepthTest(true);
+	args.SetDepthTest(true);
 	args.SetColor(particle->color | 0xff000000, particle->color >> 24);
 	args.SetStyle(TriBlendMode::Shaded, particle->alpha, 1.0 - particle->alpha);
 	args.SetTransform(&worldToClip);
 	args.SetFaceCullCCW(true);
 	args.SetStencilTestValue(stencilValue);
 	args.SetWriteStencil(false);
-	args.SetWriteSubsectorDepth(false);
+	args.SetWriteDepth(false);
 	args.SetClipPlane(clipPlane);
 	args.SetTexture(GetParticleTexture(), ParticleTextureSize, ParticleTextureSize);
 	args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
diff --git a/src/polyrenderer/scene/poly_particle.h b/src/polyrenderer/scene/poly_particle.h
index a5cc3d0d04..af4b4ebfc3 100644
--- a/src/polyrenderer/scene/poly_particle.h
+++ b/src/polyrenderer/scene/poly_particle.h
@@ -28,7 +28,7 @@
 class RenderPolyParticle
 {
 public:
-	void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue);
+	void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t stencilValue);
 
 private:
 	static uint8_t *GetParticleTexture();
diff --git a/src/polyrenderer/scene/poly_plane.cpp b/src/polyrenderer/scene/poly_plane.cpp
index ad471b4f06..d76a1756f8 100644
--- a/src/polyrenderer/scene/poly_plane.cpp
+++ b/src/polyrenderer/scene/poly_plane.cpp
@@ -33,7 +33,7 @@
 
 EXTERN_CVAR(Int, r_3dfloors)
 
-void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t ceilingSubsectorDepth, uint32_t floorSubsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals)
+void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals)
 {
 	RenderPolyPlane plane;
 
@@ -61,7 +61,7 @@ void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipP
 			double fakeHeight = fakeFloor->top.plane->ZatPoint(frontsector->centerspot);
 			if (fakeHeight < viewpoint.Pos.Z && fakeHeight > frontsector->floorplane.ZatPoint(frontsector->centerspot))
 			{
-				plane.Render3DFloor(worldToClip, clipPlane, sub, floorSubsectorDepth, stencilValue, false, fakeFloor);
+				plane.Render3DFloor(worldToClip, clipPlane, sub, stencilValue, false, fakeFloor);
 			}
 		}
 
@@ -82,16 +82,16 @@ void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipP
 			double fakeHeight = fakeFloor->bottom.plane->ZatPoint(frontsector->centerspot);
 			if (fakeHeight > viewpoint.Pos.Z && fakeHeight < frontsector->ceilingplane.ZatPoint(frontsector->centerspot))
 			{
-				plane.Render3DFloor(worldToClip, clipPlane, sub, ceilingSubsectorDepth, stencilValue, true, fakeFloor);
+				plane.Render3DFloor(worldToClip, clipPlane, sub, stencilValue, true, fakeFloor);
 			}
 		}
 	}
 
-	plane.Render(worldToClip, clipPlane, cull, sub, ceilingSubsectorDepth, stencilValue, true, skyCeilingHeight, sectorPortals);
-	plane.Render(worldToClip, clipPlane, cull, sub, floorSubsectorDepth, stencilValue, false, skyFloorHeight, sectorPortals);
+	plane.Render(worldToClip, clipPlane, cull, sub, stencilValue, true, skyCeilingHeight, sectorPortals);
+	plane.Render(worldToClip, clipPlane, cull, sub, stencilValue, false, skyFloorHeight, sectorPortals);
 }
 
-void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakeFloor)
+void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, bool ceiling, F3DFloor *fakeFloor)
 {
 	FTextureID picnum = ceiling ? *fakeFloor->bottom.texture : *fakeFloor->top.texture;
 	FTexture *tex = TexMan(picnum);
@@ -131,7 +131,6 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const PolyClip
 
 	PolyDrawArgs args;
 	args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false);
-	args.SetSubsectorDepth(subsectorDepth);
 	args.SetTransform(&worldToClip);
 	args.SetStyle(TriBlendMode::TextureOpaque);
 	args.SetFaceCullCCW(true);
@@ -142,7 +141,7 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const PolyClip
 	args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan);
 }
 
-void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals)
+void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals)
 {
 	const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
 	bool foggy = false;
@@ -302,7 +301,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &
 
 	PolyDrawArgs args;
 	args.SetLight(GetColorTable(frontsector->Colormap, frontsector->SpecialColors[ceiling]), frontsector->lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false);
-	args.SetSubsectorDepth(isSky ? RenderPolyScene::SkySubsectorDepth : subsectorDepth);
+	//args.SetSubsectorDepth(isSky ? RenderPolyScene::SkySubsectorDepth : subsectorDepth);
 	args.SetTransform(&worldToClip);
 	args.SetFaceCullCCW(ccw);
 	args.SetStencilTestValue(stencilValue);
@@ -320,7 +319,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &
 		if (portal)
 		{
 			args.SetWriteStencil(true, polyportal->StencilValue);
-			polyportal->Shape.push_back({ vertices, (int)sub->numlines, ccw, subsectorDepth });
+			polyportal->Shape.push_back({ vertices, (int)sub->numlines, ccw });
 		}
 		else
 		{
@@ -328,7 +327,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &
 		}
 
 		args.SetWriteColor(false);
-		args.SetWriteSubsectorDepth(false);
+		args.SetWriteDepth(false);
 		args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan);
 
 		for (uint32_t i = 0; i < sub->numlines; i++)
@@ -397,7 +396,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &
 			
 			if (portal)
 			{
-				polyportal->Shape.push_back({ wallvert, 4, ccw, subsectorDepth });
+				polyportal->Shape.push_back({ wallvert, 4, ccw });
 			}
 		}
 	}
diff --git a/src/polyrenderer/scene/poly_plane.h b/src/polyrenderer/scene/poly_plane.h
index bb022aea91..3da2e4709f 100644
--- a/src/polyrenderer/scene/poly_plane.h
+++ b/src/polyrenderer/scene/poly_plane.h
@@ -30,7 +30,7 @@ class PolyCull;
 class RenderPolyPlane
 {
 public:
-	static void RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t ceilingSubsectorDepth, uint32_t floorSubsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals);
+	static void RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals);
 
 private:
 	struct UVTransform
@@ -47,7 +47,7 @@ private:
 		float xOffs, yOffs;
 	};
 
-	void Render3DFloor(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakefloor);
-	void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals);
+	void Render3DFloor(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, bool ceiling, F3DFloor *fakefloor);
+	void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals);
 	TriVertex PlaneVertex(vertex_t *v1, double height, const UVTransform &transform);
 };
diff --git a/src/polyrenderer/scene/poly_portal.h b/src/polyrenderer/scene/poly_portal.h
index 266313e408..b62922f56e 100644
--- a/src/polyrenderer/scene/poly_portal.h
+++ b/src/polyrenderer/scene/poly_portal.h
@@ -26,11 +26,10 @@
 
 struct PolyPortalVertexRange
 {
-	PolyPortalVertexRange(const TriVertex *vertices, int count, bool ccw, uint32_t subsectorDepth) : Vertices(vertices), Count(count), Ccw(ccw), SubsectorDepth(subsectorDepth) { }
+	PolyPortalVertexRange(const TriVertex *vertices, int count, bool ccw) : Vertices(vertices), Count(count), Ccw(ccw) { }
 	const TriVertex *Vertices;
 	int Count;
 	bool Ccw;
-	uint32_t SubsectorDepth;
 };
 
 class PolyPortalSegment
diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp
index 2e5b048401..036d30ffe0 100644
--- a/src/polyrenderer/scene/poly_scene.cpp
+++ b/src/polyrenderer/scene/poly_scene.cpp
@@ -179,7 +179,7 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub, uint32_t ceilingSubsecto
 
 	if (sub->sector->CenterFloor() != sub->sector->CenterCeiling())
 	{
-		RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, Cull, sub, ceilingSubsectorDepth, floorSubsectorDepth, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals);
+		RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, Cull, sub, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals);
 	}
 
 	if (mainBSP)
@@ -384,7 +384,6 @@ void RenderPolyScene::RenderPortals(int portalDepth)
 			for (const auto &verts : portal->Shape)
 			{
 				args.SetFaceCullCCW(verts.Ccw);
-				args.SetSubsectorDepth(verts.SubsectorDepth);
 				args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
 			}
 		}
@@ -396,7 +395,6 @@ void RenderPolyScene::RenderPortals(int portalDepth)
 			for (const auto &verts : portal->Shape)
 			{
 				args.SetFaceCullCCW(verts.Ccw);
-				args.SetSubsectorDepth(verts.SubsectorDepth);
 				args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
 			}
 		}
@@ -420,7 +418,6 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
 			for (const auto &verts : portal->Shape)
 			{
 				args.SetFaceCullCCW(verts.Ccw);
-				args.SetSubsectorDepth(verts.SubsectorDepth);
 				args.SetWriteColor(false);
 				args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
 			}
@@ -439,7 +436,6 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
 			for (const auto &verts : portal->Shape)
 			{
 				args.SetFaceCullCCW(verts.Ccw);
-				args.SetSubsectorDepth(verts.SubsectorDepth);
 				args.SetWriteColor(false);
 				args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
 			}
@@ -467,7 +463,7 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
 		if (obj->particle)
 		{
 			RenderPolyParticle spr;
-			spr.Render(WorldToClip, PortalPlane, obj->particle, obj->sub, obj->subsectorDepth, StencilValue + 1);
+			spr.Render(WorldToClip, PortalPlane, obj->particle, obj->sub, StencilValue + 1);
 		}
 		else if (!obj->thing)
 		{
@@ -476,12 +472,12 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
 		else if ((obj->thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
 		{
 			RenderPolyWallSprite wallspr;
-			wallspr.Render(WorldToClip, PortalPlane, obj->thing, obj->sub, obj->subsectorDepth, StencilValue + 1);
+			wallspr.Render(WorldToClip, PortalPlane, obj->thing, obj->sub, StencilValue + 1);
 		}
 		else
 		{
 			RenderPolySprite spr;
-			spr.Render(WorldToClip, PortalPlane, obj->thing, obj->sub, obj->subsectorDepth, StencilValue + 1, obj->SpriteLeft, obj->SpriteRight);
+			spr.Render(WorldToClip, PortalPlane, obj->thing, obj->sub, StencilValue + 1, obj->SpriteLeft, obj->SpriteRight);
 		}
 	}
 }
diff --git a/src/polyrenderer/scene/poly_sky.cpp b/src/polyrenderer/scene/poly_sky.cpp
index 4fa4e7889c..531fb6be5c 100644
--- a/src/polyrenderer/scene/poly_sky.cpp
+++ b/src/polyrenderer/scene/poly_sky.cpp
@@ -83,7 +83,6 @@ void PolySkyDome::Render(const TriMatrix &worldToClip)
 
 	PolyDrawArgs args;
 	args.SetLight(&NormalLight, 255, PolyRenderer::Instance()->Light.WallGlobVis(false), true);
-	args.SetSubsectorDepth(RenderPolyScene::SkySubsectorDepth);
 	args.SetTransform(&objectToClip);
 	args.SetStencilTestValue(255);
 	args.SetWriteStencil(true, 1);
diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp
index 3ff88514db..e0782ebd50 100644
--- a/src/polyrenderer/scene/poly_sprite.cpp
+++ b/src/polyrenderer/scene/poly_sprite.cpp
@@ -67,7 +67,7 @@ bool RenderPolySprite::GetLine(AActor *thing, DVector2 &left, DVector2 &right)
 	return true;
 }
 
-void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, float t1, float t2)
+void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t stencilValue, float t1, float t2)
 {
 	DVector2 line[2];
 	if (!GetLine(thing, line[0], line[1]))
@@ -142,7 +142,6 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane
 
 	PolyDrawArgs args;
 	args.SetLight(GetColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites], true), lightlevel, PolyRenderer::Instance()->Light.SpriteGlobVis(foggy), fullbrightSprite);
-	args.SetSubsectorDepth(subsectorDepth);
 	args.SetTransform(&worldToClip);
 	args.SetFaceCullCCW(true);
 	args.SetStencilTestValue(stencilValue);
@@ -152,8 +151,8 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane
 		args.SetStyle(LegacyRenderStyles[STYLE_Normal], 1.0f, thing->fillcolor, thing->Translation, tex, fullbrightSprite);
 	else
 		args.SetStyle(thing->RenderStyle, thing->Alpha, thing->fillcolor, thing->Translation, tex, fullbrightSprite);
-	args.SetSubsectorDepthTest(true);
-	args.SetWriteSubsectorDepth(false);
+	args.SetDepthTest(true);
+	args.SetWriteDepth(false);
 	args.SetWriteStencil(false);
 	args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
 }
diff --git a/src/polyrenderer/scene/poly_sprite.h b/src/polyrenderer/scene/poly_sprite.h
index e190d9ee6c..bb31fab0a0 100644
--- a/src/polyrenderer/scene/poly_sprite.h
+++ b/src/polyrenderer/scene/poly_sprite.h
@@ -27,7 +27,7 @@
 class RenderPolySprite
 {
 public:
-	void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, float t1, float t2);
+	void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t stencilValue, float t1, float t2);
 
 	static bool GetLine(AActor *thing, DVector2 &left, DVector2 &right);
 	static bool IsThingCulled(AActor *thing);
diff --git a/src/polyrenderer/scene/poly_wall.cpp b/src/polyrenderer/scene/poly_wall.cpp
index db95ec94a3..4a44947814 100644
--- a/src/polyrenderer/scene/poly_wall.cpp
+++ b/src/polyrenderer/scene/poly_wall.cpp
@@ -270,7 +270,6 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &c
 
 	PolyDrawArgs args;
 	args.SetLight(GetColorTable(Line->frontsector->Colormap, Line->frontsector->SpecialColors[sector_t::walltop]), GetLightLevel(), PolyRenderer::Instance()->Light.WallGlobVis(foggy), false);
-	args.SetSubsectorDepth(SubsectorDepth);
 	args.SetTransform(&worldToClip);
 	args.SetFaceCullCCW(true);
 	args.SetStencilTestValue(StencilValue);
@@ -283,9 +282,9 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &c
 	{
 		args.SetWriteStencil(true, Polyportal->StencilValue);
 		args.SetWriteColor(false);
-		args.SetWriteSubsectorDepth(false);
+		args.SetWriteDepth(false);
 		args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
-		Polyportal->Shape.push_back({ vertices, 4, true, SubsectorDepth });
+		Polyportal->Shape.push_back({ vertices, 4, true });
 	}
 	else if (!Masked)
 	{
@@ -298,13 +297,13 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &c
 		double srcalpha = MIN(Line->alpha, 1.0);
 		double destalpha = addtrans ? 1.0 : 1.0 - srcalpha;
 		args.SetStyle(TriBlendMode::TextureAdd, srcalpha, destalpha);
-		args.SetSubsectorDepthTest(true);
-		args.SetWriteSubsectorDepth(true);
+		args.SetDepthTest(true);
+		args.SetWriteDepth(true);
 		args.SetWriteStencil(false);
 		args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
 	}
 
-	RenderPolyDecal::RenderWallDecals(worldToClip, clipPlane, LineSeg, SubsectorDepth, StencilValue);
+	RenderPolyDecal::RenderWallDecals(worldToClip, clipPlane, LineSeg, StencilValue);
 }
 
 void RenderPolyWall::ClampHeight(TriVertex &v1, TriVertex &v2)
diff --git a/src/polyrenderer/scene/poly_wallsprite.cpp b/src/polyrenderer/scene/poly_wallsprite.cpp
index d00e6d2bdd..36e02fbb47 100644
--- a/src/polyrenderer/scene/poly_wallsprite.cpp
+++ b/src/polyrenderer/scene/poly_wallsprite.cpp
@@ -29,7 +29,7 @@
 #include "polyrenderer/poly_renderer.h"
 #include "polyrenderer/scene/poly_light.h"
 
-void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue)
+void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t stencilValue)
 {
 	if (RenderPolySprite::IsThingCulled(thing))
 		return;
@@ -106,8 +106,8 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const PolyClipPl
 	args.SetStencilTestValue(stencilValue);
 	args.SetTexture(tex);
 	args.SetClipPlane(clipPlane);
-	args.SetSubsectorDepthTest(true);
-	args.SetWriteSubsectorDepth(false);
+	args.SetDepthTest(true);
+	args.SetWriteDepth(false);
 	args.SetWriteStencil(false);
 	args.SetStyle(TriBlendMode::TextureMasked);
 	args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
diff --git a/src/polyrenderer/scene/poly_wallsprite.h b/src/polyrenderer/scene/poly_wallsprite.h
index c0c0005b86..5e1a992b1e 100644
--- a/src/polyrenderer/scene/poly_wallsprite.h
+++ b/src/polyrenderer/scene/poly_wallsprite.h
@@ -27,5 +27,5 @@
 class RenderPolyWallSprite
 {
 public:
-	void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue);
+	void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t stencilValue);
 };