From 7c7d6e99e9101a8153b2f845448fe2b3ff3e70e7 Mon Sep 17 00:00:00 2001
From: Magnus Norddahl <dpjudas@users.noreply.github.com>
Date: Sun, 29 Jan 2017 10:05:37 +0100
Subject: [PATCH] Split DrawerArgs into WallDrawerArgs, ColumnDrawerArgs,
 SpanDrawerArgs and SkyDrawerArgs

---
 src/swrenderer/drawers/r_draw.cpp           |   2 +-
 src/swrenderer/drawers/r_draw.h             |  76 +-
 src/swrenderer/drawers/r_draw_pal.cpp       |  16 +-
 src/swrenderer/drawers/r_draw_pal.h         |  86 +--
 src/swrenderer/drawers/r_draw_rgba.cpp      |  18 +-
 src/swrenderer/drawers/r_draw_rgba.h        |  88 +--
 src/swrenderer/drawers/r_drawerargs.cpp     | 733 ++++++++++++++++++++
 src/swrenderer/drawers/r_drawerargs.h       | 215 ++++++
 src/swrenderer/line/r_fogboundary.h         |   2 +-
 src/swrenderer/line/r_line.cpp              |   2 +-
 src/swrenderer/line/r_renderdrawsegment.cpp |  27 +-
 src/swrenderer/line/r_walldraw.cpp          |   8 +-
 src/swrenderer/line/r_walldraw.h            |   8 +-
 src/swrenderer/plane/r_flatplane.h          |   4 +-
 src/swrenderer/plane/r_skyplane.h           |   2 +-
 src/swrenderer/plane/r_slopeplane.h         |   2 +-
 src/swrenderer/things/r_decal.cpp           |   4 +-
 src/swrenderer/things/r_decal.h             |   4 +-
 src/swrenderer/things/r_playersprite.cpp    |   2 +-
 src/swrenderer/things/r_sprite.cpp          |   2 +-
 src/swrenderer/things/r_voxel.cpp           |   4 +-
 src/swrenderer/things/r_voxel.h             |   4 +-
 src/swrenderer/things/r_wallsprite.cpp      |   4 +-
 src/swrenderer/things/r_wallsprite.h        |   4 +-
 src/v_draw.cpp                              |   4 +-
 25 files changed, 1142 insertions(+), 179 deletions(-)
 create mode 100644 src/swrenderer/drawers/r_drawerargs.cpp
 create mode 100644 src/swrenderer/drawers/r_drawerargs.h

diff --git a/src/swrenderer/drawers/r_draw.cpp b/src/swrenderer/drawers/r_draw.cpp
index b569aac0d..db7cb8a6b 100644
--- a/src/swrenderer/drawers/r_draw.cpp
+++ b/src/swrenderer/drawers/r_draw.cpp
@@ -156,7 +156,7 @@ namespace swrenderer
 		}
 	}
 
-	void R_UpdateFuzzPos(const DrawerArgs &args)
+	void R_UpdateFuzzPos(const ColumnDrawerArgs &args)
 	{
 		int yl = MAX(args.dc_yl, 1);
 		int yh = MIN(args.dc_yh, fuzzviewheight);
diff --git a/src/swrenderer/drawers/r_draw.h b/src/swrenderer/drawers/r_draw.h
index efedc277b..f34601b57 100644
--- a/src/swrenderer/drawers/r_draw.h
+++ b/src/swrenderer/drawers/r_draw.h
@@ -20,6 +20,10 @@ EXTERN_CVAR(Bool, r_dynlights);
 namespace swrenderer
 {
 	class DrawerArgs;
+	class SkyDrawerArgs;
+	class WallDrawerArgs;
+	class SpanDrawerArgs;
+	class ColumnDrawerArgs;
 
 	extern int ylookup[MAXHEIGHT];
 	extern uint8_t shadetables[/*NUMCOLORMAPS*16*256*/];
@@ -46,46 +50,46 @@ namespace swrenderer
 	{
 	public:
 		virtual ~SWPixelFormatDrawers() { }
-		virtual void DrawWallColumn(const DrawerArgs &args) = 0;
-		virtual void DrawWallMaskedColumn(const DrawerArgs &args) = 0;
-		virtual void DrawWallAddColumn(const DrawerArgs &args) = 0;
-		virtual void DrawWallAddClampColumn(const DrawerArgs &args) = 0;
-		virtual void DrawWallSubClampColumn(const DrawerArgs &args) = 0;
-		virtual void DrawWallRevSubClampColumn(const DrawerArgs &args) = 0;
-		virtual void DrawSingleSkyColumn(const DrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky) = 0;
-		virtual void DrawDoubleSkyColumn(const DrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky) = 0;
-		virtual void DrawColumn(const DrawerArgs &args) = 0;
-		virtual void FillColumn(const DrawerArgs &args) = 0;
-		virtual void FillAddColumn(const DrawerArgs &args) = 0;
-		virtual void FillAddClampColumn(const DrawerArgs &args) = 0;
-		virtual void FillSubClampColumn(const DrawerArgs &args) = 0;
-		virtual void FillRevSubClampColumn(const DrawerArgs &args) = 0;
-		virtual void DrawFuzzColumn(const DrawerArgs &args) = 0;
-		virtual void DrawAddColumn(const DrawerArgs &args) = 0;
-		virtual void DrawTranslatedColumn(const DrawerArgs &args) = 0;
-		virtual void DrawTranslatedAddColumn(const DrawerArgs &args) = 0;
-		virtual void DrawShadedColumn(const DrawerArgs &args) = 0;
-		virtual void DrawAddClampColumn(const DrawerArgs &args) = 0;
-		virtual void DrawAddClampTranslatedColumn(const DrawerArgs &args) = 0;
-		virtual void DrawSubClampColumn(const DrawerArgs &args) = 0;
-		virtual void DrawSubClampTranslatedColumn(const DrawerArgs &args) = 0;
-		virtual void DrawRevSubClampColumn(const DrawerArgs &args) = 0;
-		virtual void DrawRevSubClampTranslatedColumn(const DrawerArgs &args) = 0;
-		virtual void DrawSpan(const DrawerArgs &args) = 0;
-		virtual void DrawSpanMasked(const DrawerArgs &args) = 0;
-		virtual void DrawSpanTranslucent(const DrawerArgs &args) = 0;
-		virtual void DrawSpanMaskedTranslucent(const DrawerArgs &args) = 0;
-		virtual void DrawSpanAddClamp(const DrawerArgs &args) = 0;
-		virtual void DrawSpanMaskedAddClamp(const DrawerArgs &args) = 0;
-		virtual void FillSpan(const DrawerArgs &args) = 0;
-		virtual void DrawTiltedSpan(const DrawerArgs &args, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap) = 0;
-		virtual void DrawColoredSpan(const DrawerArgs &args, int y, int x1, int x2) = 0;
-		virtual void DrawFogBoundaryLine(const DrawerArgs &args, int y, int x1, int x2) = 0;
+		virtual void DrawWallColumn(const WallDrawerArgs &args) = 0;
+		virtual void DrawWallMaskedColumn(const WallDrawerArgs &args) = 0;
+		virtual void DrawWallAddColumn(const WallDrawerArgs &args) = 0;
+		virtual void DrawWallAddClampColumn(const WallDrawerArgs &args) = 0;
+		virtual void DrawWallSubClampColumn(const WallDrawerArgs &args) = 0;
+		virtual void DrawWallRevSubClampColumn(const WallDrawerArgs &args) = 0;
+		virtual void DrawSingleSkyColumn(const SkyDrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky) = 0;
+		virtual void DrawDoubleSkyColumn(const SkyDrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky) = 0;
+		virtual void DrawColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void FillColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void FillAddColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void FillAddClampColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void FillSubClampColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void FillRevSubClampColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void DrawFuzzColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void DrawAddColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void DrawTranslatedColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void DrawTranslatedAddColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void DrawShadedColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void DrawAddClampColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void DrawAddClampTranslatedColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void DrawSubClampColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void DrawSubClampTranslatedColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void DrawRevSubClampColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void DrawRevSubClampTranslatedColumn(const ColumnDrawerArgs &args) = 0;
+		virtual void DrawSpan(const SpanDrawerArgs &args) = 0;
+		virtual void DrawSpanMasked(const SpanDrawerArgs &args) = 0;
+		virtual void DrawSpanTranslucent(const SpanDrawerArgs &args) = 0;
+		virtual void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) = 0;
+		virtual void DrawSpanAddClamp(const SpanDrawerArgs &args) = 0;
+		virtual void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) = 0;
+		virtual void FillSpan(const SpanDrawerArgs &args) = 0;
+		virtual void DrawTiltedSpan(const SpanDrawerArgs &args, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap) = 0;
+		virtual void DrawColoredSpan(const SpanDrawerArgs &args, int y, int x1, int x2) = 0;
+		virtual void DrawFogBoundaryLine(const SpanDrawerArgs &args, int y, int x1, int x2) = 0;
 	};
 
 	void R_InitShadeMaps();
 	void R_InitFuzzTable(int fuzzoff);
 	void R_InitParticleTexture();
 
-	void R_UpdateFuzzPos(const DrawerArgs &args);
+	void R_UpdateFuzzPos(const ColumnDrawerArgs &args);
 }
diff --git a/src/swrenderer/drawers/r_draw_pal.cpp b/src/swrenderer/drawers/r_draw_pal.cpp
index 18abbb195..0ae0e294d 100644
--- a/src/swrenderer/drawers/r_draw_pal.cpp
+++ b/src/swrenderer/drawers/r_draw_pal.cpp
@@ -96,7 +96,7 @@ CVAR(Bool, r_blendmethod, false, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
 
 namespace swrenderer
 {
-	PalWall1Command::PalWall1Command(const DrawerArgs &args)
+	PalWall1Command::PalWall1Command(const WallDrawerArgs &args)
 	{
 		_iscale = args.dc_iscale;
 		_texturefrac = args.dc_texturefrac;
@@ -559,7 +559,7 @@ namespace swrenderer
 
 	/////////////////////////////////////////////////////////////////////////
 
-	PalSkyCommand::PalSkyCommand(const DrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky) : solid_top(solid_top), solid_bottom(solid_bottom), fadeSky(fadeSky)
+	PalSkyCommand::PalSkyCommand(const SkyDrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky) : solid_top(solid_top), solid_bottom(solid_bottom), fadeSky(fadeSky)
 	{
 		_dest = args.Dest();
 		_dest_y = args.DestY();
@@ -864,7 +864,7 @@ namespace swrenderer
 
 	/////////////////////////////////////////////////////////////////////////
 
-	PalColumnCommand::PalColumnCommand(const DrawerArgs &args)
+	PalColumnCommand::PalColumnCommand(const ColumnDrawerArgs &args)
 	{
 		_count = args.dc_count;
 		_dest = args.Dest();
@@ -1761,7 +1761,7 @@ namespace swrenderer
 
 	/////////////////////////////////////////////////////////////////////////
 
-	DrawFuzzColumnPalCommand::DrawFuzzColumnPalCommand(const DrawerArgs &args)
+	DrawFuzzColumnPalCommand::DrawFuzzColumnPalCommand(const ColumnDrawerArgs &args)
 	{
 		_yl = args.dc_yl;
 		_yh = args.dc_yh;
@@ -1848,7 +1848,7 @@ namespace swrenderer
 
 	/////////////////////////////////////////////////////////////////////////
 
-	PalSpanCommand::PalSpanCommand(const DrawerArgs &args)
+	PalSpanCommand::PalSpanCommand(const SpanDrawerArgs &args)
 	{
 		_source = args.ds_source;
 		_colormap = args.ds_colormap;
@@ -2623,7 +2623,7 @@ namespace swrenderer
 
 	/////////////////////////////////////////////////////////////////////////
 
-	DrawTiltedSpanPalCommand::DrawTiltedSpanPalCommand(const DrawerArgs &args, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap)
+	DrawTiltedSpanPalCommand::DrawTiltedSpanPalCommand(const SpanDrawerArgs &args, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap)
 		: y(y), x1(x1), x2(x2), plane_sz(plane_sz), plane_su(plane_su), plane_sv(plane_sv), plane_shade(plane_shade), planeshade(planeshade), planelightfloat(planelightfloat), pviewx(pviewx), pviewy(pviewy)
 	{
 		_colormap = args.ds_colormap;
@@ -2869,7 +2869,7 @@ namespace swrenderer
 
 	/////////////////////////////////////////////////////////////////////////
 
-	DrawColoredSpanPalCommand::DrawColoredSpanPalCommand(const DrawerArgs &args, int y, int x1, int x2) : PalSpanCommand(args), y(y), x1(x1), x2(x2)
+	DrawColoredSpanPalCommand::DrawColoredSpanPalCommand(const SpanDrawerArgs &args, int y, int x1, int x2) : PalSpanCommand(args), y(y), x1(x1), x2(x2)
 	{
 		color = args.ds_color;
 		destorg = dc_destorg;
@@ -2885,7 +2885,7 @@ namespace swrenderer
 
 	/////////////////////////////////////////////////////////////////////////
 
-	DrawFogBoundaryLinePalCommand::DrawFogBoundaryLinePalCommand(const DrawerArgs &args, int y, int x1, int x2) : PalSpanCommand(args), y(y), x1(x1), x2(x2)
+	DrawFogBoundaryLinePalCommand::DrawFogBoundaryLinePalCommand(const SpanDrawerArgs &args, int y, int x1, int x2) : PalSpanCommand(args), y(y), x1(x1), x2(x2)
 	{
 		_colormap = args.dc_colormap;
 		_destorg = dc_destorg;
diff --git a/src/swrenderer/drawers/r_draw_pal.h b/src/swrenderer/drawers/r_draw_pal.h
index ea798ef3c..c8c3dacb6 100644
--- a/src/swrenderer/drawers/r_draw_pal.h
+++ b/src/swrenderer/drawers/r_draw_pal.h
@@ -11,7 +11,7 @@ namespace swrenderer
 	class PalWall1Command : public DrawerCommand
 	{
 	public:
-		PalWall1Command(const DrawerArgs &args);
+		PalWall1Command(const WallDrawerArgs &args);
 		FString DebugInfo() override { return "PalWallCommand"; }
 
 	protected:
@@ -44,7 +44,7 @@ namespace swrenderer
 	class PalSkyCommand : public DrawerCommand
 	{
 	public:
-		PalSkyCommand(const DrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky);
+		PalSkyCommand(const SkyDrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky);
 		FString DebugInfo() override { return "PalSkyCommand"; }
 
 	protected:
@@ -69,7 +69,7 @@ namespace swrenderer
 	class PalColumnCommand : public DrawerCommand
 	{
 	public:
-		PalColumnCommand(const DrawerArgs &args);
+		PalColumnCommand(const ColumnDrawerArgs &args);
 		FString DebugInfo() override { return "PalColumnCommand"; }
 
 	protected:
@@ -110,7 +110,7 @@ namespace swrenderer
 	class DrawFuzzColumnPalCommand : public DrawerCommand
 	{
 	public:
-		DrawFuzzColumnPalCommand(const DrawerArgs &args);
+		DrawFuzzColumnPalCommand(const ColumnDrawerArgs &args);
 		void Execute(DrawerThread *thread) override;
 		FString DebugInfo() override { return "DrawFuzzColumnPalCommand"; }
 
@@ -127,7 +127,7 @@ namespace swrenderer
 	class PalSpanCommand : public DrawerCommand
 	{
 	public:
-		PalSpanCommand(const DrawerArgs &args);
+		PalSpanCommand(const SpanDrawerArgs &args);
 		FString DebugInfo() override { return "PalSpanCommand"; }
 
 	protected:
@@ -167,7 +167,7 @@ namespace swrenderer
 	class DrawTiltedSpanPalCommand : public DrawerCommand
 	{
 	public:
-		DrawTiltedSpanPalCommand(const DrawerArgs &args, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap);
+		DrawTiltedSpanPalCommand(const SpanDrawerArgs &args, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap);
 		void Execute(DrawerThread *thread) override;
 		FString DebugInfo() override { return "DrawTiltedSpanPalCommand"; }
 
@@ -197,7 +197,7 @@ namespace swrenderer
 	class DrawColoredSpanPalCommand : public PalSpanCommand
 	{
 	public:
-		DrawColoredSpanPalCommand(const DrawerArgs &args, int y, int x1, int x2);
+		DrawColoredSpanPalCommand(const SpanDrawerArgs &args, int y, int x1, int x2);
 		void Execute(DrawerThread *thread) override;
 		FString DebugInfo() override { return "DrawColoredSpanPalCommand"; }
 
@@ -212,7 +212,7 @@ namespace swrenderer
 	class DrawFogBoundaryLinePalCommand : public PalSpanCommand
 	{
 	public:
-		DrawFogBoundaryLinePalCommand(const DrawerArgs &args, int y, int x1, int x2);
+		DrawFogBoundaryLinePalCommand(const SpanDrawerArgs &args, int y, int x1, int x2);
 		void Execute(DrawerThread *thread) override;
 
 	private:
@@ -241,10 +241,10 @@ namespace swrenderer
 	class SWPalDrawers : public SWPixelFormatDrawers
 	{
 	public:
-		void DrawWallColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWall1PalCommand>(args); }
-		void DrawWallMaskedColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallMasked1PalCommand>(args); }
+		void DrawWallColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWall1PalCommand>(args); }
+		void DrawWallMaskedColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallMasked1PalCommand>(args); }
 
-		void DrawWallAddColumn(const DrawerArgs &args) override
+		void DrawWallAddColumn(const WallDrawerArgs &args) override
 		{
 			if (args.dc_num_lights == 0)
 				DrawerCommandQueue::QueueCommand<DrawWallAdd1PalCommand>(args);
@@ -252,42 +252,42 @@ namespace swrenderer
 				DrawerCommandQueue::QueueCommand<DrawWallAddClamp1PalCommand>(args);
 		}
 
-		void DrawWallAddClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallAddClamp1PalCommand>(args); }
-		void DrawWallSubClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallSubClamp1PalCommand>(args); }
-		void DrawWallRevSubClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallRevSubClamp1PalCommand>(args); }
-		void DrawSingleSkyColumn(const DrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky) override { DrawerCommandQueue::QueueCommand<DrawSingleSky1PalCommand>(args, solid_top, solid_bottom, fadeSky); }
-		void DrawDoubleSkyColumn(const DrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky) override { DrawerCommandQueue::QueueCommand<DrawDoubleSky1PalCommand>(args, solid_top, solid_bottom, fadeSky); }
-		void DrawColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnPalCommand>(args); }
-		void FillColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnPalCommand>(args); }
-		void FillAddColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddPalCommand>(args); }
-		void FillAddClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddClampPalCommand>(args); }
-		void FillSubClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnSubClampPalCommand>(args); }
-		void FillRevSubClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnRevSubClampPalCommand>(args); }
-		void DrawFuzzColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawFuzzColumnPalCommand>(args); R_UpdateFuzzPos(args); }
-		void DrawAddColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddPalCommand>(args); }
-		void DrawTranslatedColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTranslatedPalCommand>(args); }
-		void DrawTranslatedAddColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTlatedAddPalCommand>(args); }
-		void DrawShadedColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnShadedPalCommand>(args); }
-		void DrawAddClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampPalCommand>(args); }
-		void DrawAddClampTranslatedColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampTranslatedPalCommand>(args); }
-		void DrawSubClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampPalCommand>(args); }
-		void DrawSubClampTranslatedColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampTranslatedPalCommand>(args); }
-		void DrawRevSubClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnRevSubClampPalCommand>(args); }
-		void DrawRevSubClampTranslatedColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnRevSubClampTranslatedPalCommand>(args); }
-		void DrawSpan(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanPalCommand>(args); }
-		void DrawSpanMasked(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedPalCommand>(args); }
-		void DrawSpanTranslucent(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanTranslucentPalCommand>(args); }
-		void DrawSpanMaskedTranslucent(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedTranslucentPalCommand>(args); }
-		void DrawSpanAddClamp(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanAddClampPalCommand>(args); }
-		void DrawSpanMaskedAddClamp(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedAddClampPalCommand>(args); }
-		void FillSpan(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillSpanPalCommand>(args); }
+		void DrawWallAddClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallAddClamp1PalCommand>(args); }
+		void DrawWallSubClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallSubClamp1PalCommand>(args); }
+		void DrawWallRevSubClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallRevSubClamp1PalCommand>(args); }
+		void DrawSingleSkyColumn(const SkyDrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky) override { DrawerCommandQueue::QueueCommand<DrawSingleSky1PalCommand>(args, solid_top, solid_bottom, fadeSky); }
+		void DrawDoubleSkyColumn(const SkyDrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky) override { DrawerCommandQueue::QueueCommand<DrawDoubleSky1PalCommand>(args, solid_top, solid_bottom, fadeSky); }
+		void DrawColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnPalCommand>(args); }
+		void FillColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnPalCommand>(args); }
+		void FillAddColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddPalCommand>(args); }
+		void FillAddClampColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddClampPalCommand>(args); }
+		void FillSubClampColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnSubClampPalCommand>(args); }
+		void FillRevSubClampColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnRevSubClampPalCommand>(args); }
+		void DrawFuzzColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawFuzzColumnPalCommand>(args); R_UpdateFuzzPos(args); }
+		void DrawAddColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddPalCommand>(args); }
+		void DrawTranslatedColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTranslatedPalCommand>(args); }
+		void DrawTranslatedAddColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTlatedAddPalCommand>(args); }
+		void DrawShadedColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnShadedPalCommand>(args); }
+		void DrawAddClampColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampPalCommand>(args); }
+		void DrawAddClampTranslatedColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampTranslatedPalCommand>(args); }
+		void DrawSubClampColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampPalCommand>(args); }
+		void DrawSubClampTranslatedColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampTranslatedPalCommand>(args); }
+		void DrawRevSubClampColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnRevSubClampPalCommand>(args); }
+		void DrawRevSubClampTranslatedColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnRevSubClampTranslatedPalCommand>(args); }
+		void DrawSpan(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanPalCommand>(args); }
+		void DrawSpanMasked(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedPalCommand>(args); }
+		void DrawSpanTranslucent(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanTranslucentPalCommand>(args); }
+		void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedTranslucentPalCommand>(args); }
+		void DrawSpanAddClamp(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanAddClampPalCommand>(args); }
+		void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedAddClampPalCommand>(args); }
+		void FillSpan(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillSpanPalCommand>(args); }
 
-		void DrawTiltedSpan(const DrawerArgs &args, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap) override
+		void DrawTiltedSpan(const SpanDrawerArgs &args, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap) override
 		{
 			DrawerCommandQueue::QueueCommand<DrawTiltedSpanPalCommand>(args, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy, basecolormap);
 		}
 
-		void DrawColoredSpan(const DrawerArgs &args, int y, int x1, int x2) override { DrawerCommandQueue::QueueCommand<DrawColoredSpanPalCommand>(args, y, x1, x2); }
-		void DrawFogBoundaryLine(const DrawerArgs &args, int y, int x1, int x2) override { DrawerCommandQueue::QueueCommand<DrawFogBoundaryLinePalCommand>(args, y, x1, x2); }
+		void DrawColoredSpan(const SpanDrawerArgs &args, int y, int x1, int x2) override { DrawerCommandQueue::QueueCommand<DrawColoredSpanPalCommand>(args, y, x1, x2); }
+		void DrawFogBoundaryLine(const SpanDrawerArgs &args, int y, int x1, int x2) override { DrawerCommandQueue::QueueCommand<DrawFogBoundaryLinePalCommand>(args, y, x1, x2); }
 	};
 }
diff --git a/src/swrenderer/drawers/r_draw_rgba.cpp b/src/swrenderer/drawers/r_draw_rgba.cpp
index e096c97c8..77e74eebd 100644
--- a/src/swrenderer/drawers/r_draw_rgba.cpp
+++ b/src/swrenderer/drawers/r_draw_rgba.cpp
@@ -60,7 +60,7 @@ CVAR(Float, r_lod_bias, -1.5, 0); // To do: add CVAR_ARCHIVE | CVAR_GLOBALCONFIG
 
 namespace swrenderer
 {
-	DrawSpanLLVMCommand::DrawSpanLLVMCommand(const DrawerArgs &drawerargs)
+	DrawSpanLLVMCommand::DrawSpanLLVMCommand(const SpanDrawerArgs &drawerargs)
 	{
 		args.xfrac = drawerargs.ds_xfrac;
 		args.yfrac = drawerargs.ds_yfrac;
@@ -180,7 +180,7 @@ namespace swrenderer
 		return d;
 	}
 
-	DrawWall1LLVMCommand::DrawWall1LLVMCommand(const DrawerArgs &drawerargs)
+	DrawWall1LLVMCommand::DrawWall1LLVMCommand(const WallDrawerArgs &drawerargs)
 	{
 		args.dest = (uint32_t*)drawerargs.Dest();
 		args.dest_y = drawerargs.DestY();
@@ -244,7 +244,7 @@ namespace swrenderer
 		return "DrawColumn\n" + args.ToString();
 	}
 
-	DrawColumnLLVMCommand::DrawColumnLLVMCommand(const DrawerArgs &drawerargs)
+	DrawColumnLLVMCommand::DrawColumnLLVMCommand(const ColumnDrawerArgs &drawerargs)
 	{
 		args.dest = (uint32_t*)drawerargs.Dest();
 		args.source = drawerargs.dc_source;
@@ -298,7 +298,7 @@ namespace swrenderer
 		return d;
 	}
 
-	DrawSkyLLVMCommand::DrawSkyLLVMCommand(const DrawerArgs &drawerargs, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky)
+	DrawSkyLLVMCommand::DrawSkyLLVMCommand(const SkyDrawerArgs &drawerargs, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky)
 	{
 		args.dest = (uint32_t*)drawerargs.Dest();
 		args.dest_y = drawerargs.DestY();
@@ -325,7 +325,7 @@ namespace swrenderer
 
 	/////////////////////////////////////////////////////////////////////////////
 
-	DrawFuzzColumnRGBACommand::DrawFuzzColumnRGBACommand(const DrawerArgs &drawerargs)
+	DrawFuzzColumnRGBACommand::DrawFuzzColumnRGBACommand(const ColumnDrawerArgs &drawerargs)
 	{
 		_x = drawerargs.dc_x;
 		_yl = drawerargs.dc_yl;
@@ -433,7 +433,7 @@ namespace swrenderer
 
 	/////////////////////////////////////////////////////////////////////////////
 
-	FillSpanRGBACommand::FillSpanRGBACommand(const DrawerArgs &drawerargs)
+	FillSpanRGBACommand::FillSpanRGBACommand(const SpanDrawerArgs &drawerargs)
 	{
 		_x1 = drawerargs.ds_x1;
 		_x2 = drawerargs.ds_x2;
@@ -463,7 +463,7 @@ namespace swrenderer
 
 	/////////////////////////////////////////////////////////////////////////////
 
-	DrawFogBoundaryLineRGBACommand::DrawFogBoundaryLineRGBACommand(const DrawerArgs &drawerargs, int y, int x, int x2)
+	DrawFogBoundaryLineRGBACommand::DrawFogBoundaryLineRGBACommand(const SpanDrawerArgs &drawerargs, int y, int x, int x2)
 	{
 		_y = y;
 		_x = x;
@@ -531,7 +531,7 @@ namespace swrenderer
 
 	/////////////////////////////////////////////////////////////////////////////
 
-	DrawTiltedSpanRGBACommand::DrawTiltedSpanRGBACommand(const DrawerArgs &drawerargs, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy)
+	DrawTiltedSpanRGBACommand::DrawTiltedSpanRGBACommand(const SpanDrawerArgs &drawerargs, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy)
 	{
 		_x1 = x1;
 		_x2 = x2;
@@ -665,7 +665,7 @@ namespace swrenderer
 
 	/////////////////////////////////////////////////////////////////////////////
 
-	DrawColoredSpanRGBACommand::DrawColoredSpanRGBACommand(const DrawerArgs &drawerargs, int y, int x1, int x2)
+	DrawColoredSpanRGBACommand::DrawColoredSpanRGBACommand(const SpanDrawerArgs &drawerargs, int y, int x1, int x2)
 	{
 		_y = y;
 		_x1 = x1;
diff --git a/src/swrenderer/drawers/r_draw_rgba.h b/src/swrenderer/drawers/r_draw_rgba.h
index 1d3717a1c..ae0b259db 100644
--- a/src/swrenderer/drawers/r_draw_rgba.h
+++ b/src/swrenderer/drawers/r_draw_rgba.h
@@ -80,7 +80,7 @@ namespace swrenderer
 	class DrawSpanLLVMCommand : public DrawerCommand
 	{
 	public:
-		DrawSpanLLVMCommand(const DrawerArgs &drawerargs);
+		DrawSpanLLVMCommand(const SpanDrawerArgs &drawerargs);
 
 		void Execute(DrawerThread *thread) override;
 		FString DebugInfo() override;
@@ -135,7 +135,7 @@ namespace swrenderer
 		WorkerThreadData ThreadData(DrawerThread *thread);
 
 	public:
-		DrawWall1LLVMCommand(const DrawerArgs &drawerargs);
+		DrawWall1LLVMCommand(const WallDrawerArgs &drawerargs);
 
 		void Execute(DrawerThread *thread) override;
 		FString DebugInfo() override;
@@ -150,7 +150,7 @@ namespace swrenderer
 		FString DebugInfo() override;
 
 	public:
-		DrawColumnLLVMCommand(const DrawerArgs &drawerargs);
+		DrawColumnLLVMCommand(const ColumnDrawerArgs &drawerargs);
 
 		void Execute(DrawerThread *thread) override;
 	};
@@ -163,7 +163,7 @@ namespace swrenderer
 		WorkerThreadData ThreadData(DrawerThread *thread);
 
 	public:
-		DrawSkyLLVMCommand(const DrawerArgs &drawerargs, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky);
+		DrawSkyLLVMCommand(const SkyDrawerArgs &drawerargs, uint32_t solid_top, uint32_t solid_bottom, bool fadeSky);
 		FString DebugInfo() override;
 	};
 
@@ -201,7 +201,7 @@ namespace swrenderer
 		int _fuzzviewheight;
 
 	public:
-		DrawFuzzColumnRGBACommand(const DrawerArgs &drawerargs);
+		DrawFuzzColumnRGBACommand(const ColumnDrawerArgs &drawerargs);
 		void Execute(DrawerThread *thread) override;
 		FString DebugInfo() override;
 	};
@@ -216,7 +216,7 @@ namespace swrenderer
 		int _color;
 
 	public:
-		FillSpanRGBACommand(const DrawerArgs &drawerargs);
+		FillSpanRGBACommand(const SpanDrawerArgs &drawerargs);
 		void Execute(DrawerThread *thread) override;
 		FString DebugInfo() override;
 	};
@@ -231,7 +231,7 @@ namespace swrenderer
 		ShadeConstants _shade_constants;
 
 	public:
-		DrawFogBoundaryLineRGBACommand(const DrawerArgs &drawerargs, int y, int x, int x2);
+		DrawFogBoundaryLineRGBACommand(const SpanDrawerArgs &drawerargs, int y, int x, int x2);
 		void Execute(DrawerThread *thread) override;
 		FString DebugInfo() override;
 	};
@@ -257,7 +257,7 @@ namespace swrenderer
 		const uint32_t * RESTRICT _source;
 
 	public:
-		DrawTiltedSpanRGBACommand(const DrawerArgs &drawerargs, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy);
+		DrawTiltedSpanRGBACommand(const SpanDrawerArgs &drawerargs, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy);
 		void Execute(DrawerThread *thread) override;
 		FString DebugInfo() override;
 	};
@@ -272,7 +272,7 @@ namespace swrenderer
 		int _color;
 
 	public:
-		DrawColoredSpanRGBACommand(const DrawerArgs &drawerargs, int y, int x1, int x2);
+		DrawColoredSpanRGBACommand(const SpanDrawerArgs &drawerargs, int y, int x1, int x2);
 
 		void Execute(DrawerThread *thread) override;
 		FString DebugInfo() override;
@@ -354,46 +354,46 @@ namespace swrenderer
 	class SWTruecolorDrawers : public SWPixelFormatDrawers
 	{
 	public:
-		void DrawWallColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWall1LLVMCommand>(args); }
-		void DrawWallMaskedColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallMasked1LLVMCommand>(args); }
-		void DrawWallAddColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallAdd1LLVMCommand>(args); }
-		void DrawWallAddClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallAddClamp1LLVMCommand>(args); }
-		void DrawWallSubClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallSubClamp1LLVMCommand>(args); }
-		void DrawWallRevSubClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallRevSubClamp1LLVMCommand>(args); }
-		void DrawSingleSkyColumn(const DrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool skyFade) override { DrawerCommandQueue::QueueCommand<DrawSingleSky1LLVMCommand>(args, solid_top, solid_bottom, skyFade); }
-		void DrawDoubleSkyColumn(const DrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool skyFade) override { DrawerCommandQueue::QueueCommand<DrawDoubleSky1LLVMCommand>(args, solid_top, solid_bottom, skyFade); }
-		void DrawColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnLLVMCommand>(args); }
-		void FillColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnLLVMCommand>(args); }
-		void FillAddColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddLLVMCommand>(args); }
-		void FillAddClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddClampLLVMCommand>(args); }
-		void FillSubClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnSubClampLLVMCommand>(args); }
-		void FillRevSubClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnRevSubClampLLVMCommand>(args); }
-		void DrawFuzzColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawFuzzColumnRGBACommand>(args); R_UpdateFuzzPos(args); }
-		void DrawAddColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddLLVMCommand>(args); }
-		void DrawTranslatedColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTranslatedLLVMCommand>(args); }
-		void DrawTranslatedAddColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTlatedAddLLVMCommand>(args); }
-		void DrawShadedColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnShadedLLVMCommand>(args); }
-		void DrawAddClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampLLVMCommand>(args); }
-		void DrawAddClampTranslatedColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampTranslatedLLVMCommand>(args); }
-		void DrawSubClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampLLVMCommand>(args); }
-		void DrawSubClampTranslatedColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampTranslatedLLVMCommand>(args); }
-		void DrawRevSubClampColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnRevSubClampLLVMCommand>(args); }
-		void DrawRevSubClampTranslatedColumn(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnRevSubClampTranslatedLLVMCommand>(args); }
-		void DrawSpan(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanLLVMCommand>(args); }
-		void DrawSpanMasked(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedLLVMCommand>(args); }
-		void DrawSpanTranslucent(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanTranslucentLLVMCommand>(args); }
-		void DrawSpanMaskedTranslucent(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedTranslucentLLVMCommand>(args); }
-		void DrawSpanAddClamp(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanAddClampLLVMCommand>(args); }
-		void DrawSpanMaskedAddClamp(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedAddClampLLVMCommand>(args); }
-		void FillSpan(const DrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillSpanRGBACommand>(args); }
+		void DrawWallColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWall1LLVMCommand>(args); }
+		void DrawWallMaskedColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallMasked1LLVMCommand>(args); }
+		void DrawWallAddColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallAdd1LLVMCommand>(args); }
+		void DrawWallAddClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallAddClamp1LLVMCommand>(args); }
+		void DrawWallSubClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallSubClamp1LLVMCommand>(args); }
+		void DrawWallRevSubClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallRevSubClamp1LLVMCommand>(args); }
+		void DrawSingleSkyColumn(const SkyDrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool skyFade) override { DrawerCommandQueue::QueueCommand<DrawSingleSky1LLVMCommand>(args, solid_top, solid_bottom, skyFade); }
+		void DrawDoubleSkyColumn(const SkyDrawerArgs &args, uint32_t solid_top, uint32_t solid_bottom, bool skyFade) override { DrawerCommandQueue::QueueCommand<DrawDoubleSky1LLVMCommand>(args, solid_top, solid_bottom, skyFade); }
+		void DrawColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnLLVMCommand>(args); }
+		void FillColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnLLVMCommand>(args); }
+		void FillAddColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddLLVMCommand>(args); }
+		void FillAddClampColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddClampLLVMCommand>(args); }
+		void FillSubClampColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnSubClampLLVMCommand>(args); }
+		void FillRevSubClampColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnRevSubClampLLVMCommand>(args); }
+		void DrawFuzzColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawFuzzColumnRGBACommand>(args); R_UpdateFuzzPos(args); }
+		void DrawAddColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddLLVMCommand>(args); }
+		void DrawTranslatedColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTranslatedLLVMCommand>(args); }
+		void DrawTranslatedAddColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTlatedAddLLVMCommand>(args); }
+		void DrawShadedColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnShadedLLVMCommand>(args); }
+		void DrawAddClampColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampLLVMCommand>(args); }
+		void DrawAddClampTranslatedColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampTranslatedLLVMCommand>(args); }
+		void DrawSubClampColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampLLVMCommand>(args); }
+		void DrawSubClampTranslatedColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampTranslatedLLVMCommand>(args); }
+		void DrawRevSubClampColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnRevSubClampLLVMCommand>(args); }
+		void DrawRevSubClampTranslatedColumn(const ColumnDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnRevSubClampTranslatedLLVMCommand>(args); }
+		void DrawSpan(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanLLVMCommand>(args); }
+		void DrawSpanMasked(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedLLVMCommand>(args); }
+		void DrawSpanTranslucent(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanTranslucentLLVMCommand>(args); }
+		void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedTranslucentLLVMCommand>(args); }
+		void DrawSpanAddClamp(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanAddClampLLVMCommand>(args); }
+		void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedAddClampLLVMCommand>(args); }
+		void FillSpan(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillSpanRGBACommand>(args); }
 
-		void DrawTiltedSpan(const DrawerArgs &args, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap) override
+		void DrawTiltedSpan(const SpanDrawerArgs &args, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap) override
 		{
 			DrawerCommandQueue::QueueCommand<DrawTiltedSpanRGBACommand>(args, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy);
 		}
 
-		void DrawColoredSpan(const DrawerArgs &args, int y, int x1, int x2) override { DrawerCommandQueue::QueueCommand<DrawColoredSpanRGBACommand>(args, y, x1, x2); }
-		void DrawFogBoundaryLine(const DrawerArgs &args, int y, int x1, int x2) override { DrawerCommandQueue::QueueCommand<DrawFogBoundaryLineRGBACommand>(args, y, x1, x2); }
+		void DrawColoredSpan(const SpanDrawerArgs &args, int y, int x1, int x2) override { DrawerCommandQueue::QueueCommand<DrawColoredSpanRGBACommand>(args, y, x1, x2); }
+		void DrawFogBoundaryLine(const SpanDrawerArgs &args, int y, int x1, int x2) override { DrawerCommandQueue::QueueCommand<DrawFogBoundaryLineRGBACommand>(args, y, x1, x2); }
 	};
 
 	/////////////////////////////////////////////////////////////////////////////
diff --git a/src/swrenderer/drawers/r_drawerargs.cpp b/src/swrenderer/drawers/r_drawerargs.cpp
new file mode 100644
index 000000000..af08e8d56
--- /dev/null
+++ b/src/swrenderer/drawers/r_drawerargs.cpp
@@ -0,0 +1,733 @@
+/*
+** r_drawerargs.cpp
+**
+**---------------------------------------------------------------------------
+** Copyright 1998-2016 Randy Heit
+** Copyright 2016 Magnus Norddahl
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions
+** are met:
+**
+** 1. Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+** 2. Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in the
+**    documentation and/or other materials provided with the distribution.
+** 3. The name of the author may not be used to endorse or promote products
+**    derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**---------------------------------------------------------------------------
+**
+*/
+
+#include <stddef.h>
+#include "r_drawerargs.h"
+#include "r_draw_pal.h"
+#include "r_draw_rgba.h"
+
+namespace swrenderer
+{
+	namespace
+	{
+		SWPixelFormatDrawers *active_drawers;
+		SWPalDrawers pal_drawers;
+		SWTruecolorDrawers tc_drawers;
+	}
+
+	void R_InitColumnDrawers()
+	{
+		if (r_swtruecolor)
+			active_drawers = &tc_drawers;
+		else
+			active_drawers = &pal_drawers;
+	}
+
+	SWPixelFormatDrawers *DrawerArgs::Drawers() const
+	{
+		return active_drawers;
+	}
+
+	DrawerArgs::DrawerArgs()
+	{
+		colfunc = &SWPixelFormatDrawers::DrawColumn;
+		basecolfunc = &SWPixelFormatDrawers::DrawColumn;
+		fuzzcolfunc = &SWPixelFormatDrawers::DrawFuzzColumn;
+		transcolfunc = &SWPixelFormatDrawers::DrawTranslatedColumn;
+		spanfunc = &SWPixelFormatDrawers::DrawSpan;
+	}
+
+	void DrawerArgs::SetColorMapLight(FSWColormap *base_colormap, float light, int shade)
+	{
+		if (r_swtruecolor)
+		{
+			dc_shade_constants.light_red = base_colormap->Color.r * 256 / 255;
+			dc_shade_constants.light_green = base_colormap->Color.g * 256 / 255;
+			dc_shade_constants.light_blue = base_colormap->Color.b * 256 / 255;
+			dc_shade_constants.light_alpha = base_colormap->Color.a * 256 / 255;
+			dc_shade_constants.fade_red = base_colormap->Fade.r;
+			dc_shade_constants.fade_green = base_colormap->Fade.g;
+			dc_shade_constants.fade_blue = base_colormap->Fade.b;
+			dc_shade_constants.fade_alpha = base_colormap->Fade.a;
+			dc_shade_constants.desaturate = MIN(abs(base_colormap->Desaturate), 255) * 255 / 256;
+			dc_shade_constants.simple_shade = (base_colormap->Color.d == 0x00ffffff && base_colormap->Fade.d == 0x00000000 && base_colormap->Desaturate == 0);
+			dc_colormap = base_colormap->Maps;
+			dc_light = LIGHTSCALE(light, shade);
+		}
+		else
+		{
+			dc_colormap = base_colormap->Maps + (GETPALOOKUP(light, shade) << COLORMAPSHIFT);
+		}
+	}
+
+	void SpanDrawerArgs::SetDSColorMapLight(FSWColormap *base_colormap, float light, int shade)
+	{
+		if (r_swtruecolor)
+		{
+			ds_shade_constants.light_red = base_colormap->Color.r * 256 / 255;
+			ds_shade_constants.light_green = base_colormap->Color.g * 256 / 255;
+			ds_shade_constants.light_blue = base_colormap->Color.b * 256 / 255;
+			ds_shade_constants.light_alpha = base_colormap->Color.a * 256 / 255;
+			ds_shade_constants.fade_red = base_colormap->Fade.r;
+			ds_shade_constants.fade_green = base_colormap->Fade.g;
+			ds_shade_constants.fade_blue = base_colormap->Fade.b;
+			ds_shade_constants.fade_alpha = base_colormap->Fade.a;
+			ds_shade_constants.desaturate = MIN(abs(base_colormap->Desaturate), 255) * 255 / 256;
+			ds_shade_constants.simple_shade = (base_colormap->Color.d == 0x00ffffff && base_colormap->Fade.d == 0x00000000 && base_colormap->Desaturate == 0);
+			ds_colormap = base_colormap->Maps;
+			ds_light = LIGHTSCALE(light, shade);
+		}
+		else
+		{
+			ds_colormap = base_colormap->Maps + (GETPALOOKUP(light, shade) << COLORMAPSHIFT);
+		}
+	}
+
+	void DrawerArgs::SetTranslationMap(lighttable_t *translation)
+	{
+		if (r_swtruecolor)
+		{
+			dc_colormap = nullptr;
+			dc_translation = translation;
+			dc_shade_constants.light_red = 256;
+			dc_shade_constants.light_green = 256;
+			dc_shade_constants.light_blue = 256;
+			dc_shade_constants.light_alpha = 256;
+			dc_shade_constants.fade_red = 0;
+			dc_shade_constants.fade_green = 0;
+			dc_shade_constants.fade_blue = 0;
+			dc_shade_constants.fade_alpha = 256;
+			dc_shade_constants.desaturate = 0;
+			dc_shade_constants.simple_shade = true;
+			dc_light = 0;
+		}
+		else
+		{
+			dc_colormap = translation;
+		}
+	}
+
+	void SpanDrawerArgs::SetSpanTexture(FTexture *tex)
+	{
+		tex->GetWidth();
+		ds_xbits = tex->WidthBits;
+		ds_ybits = tex->HeightBits;
+		if ((1 << ds_xbits) > tex->GetWidth())
+		{
+			ds_xbits--;
+		}
+		if ((1 << ds_ybits) > tex->GetHeight())
+		{
+			ds_ybits--;
+		}
+
+		ds_source = r_swtruecolor ? (const uint8_t*)tex->GetPixelsBgra() : tex->GetPixels();
+		ds_source_mipmapped = tex->Mipmapped() && tex->GetWidth() > 1 && tex->GetHeight() > 1;
+	}
+
+	void SpanDrawerArgs::SetSpanColormap(FDynamicColormap *colormap, int shade)
+	{
+		SetDSColorMapLight(colormap, 0, shade);
+	}
+
+	void ColumnDrawerArgs::DrawMaskedColumn(int x, fixed_t iscale, FTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked)
+	{
+		// Handle the linear filtered version in a different function to reduce chances of merge conflicts from zdoom.
+		if (r_swtruecolor && !drawer_needs_pal_input) // To do: add support to R_DrawColumnHoriz_rgba
+		{
+			DrawMaskedColumnBgra(x, iscale, tex, col, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, unmasked);
+			return;
+		}
+
+		dc_x = x;
+		dc_iscale = iscale;
+		dc_textureheight = tex->GetHeight();
+
+		const FTexture::Span *span;
+		const BYTE *column;
+		if (r_swtruecolor && !drawer_needs_pal_input)
+			column = (const BYTE *)tex->GetColumnBgra(col >> FRACBITS, &span);
+		else
+			column = tex->GetColumn(col >> FRACBITS, &span);
+
+		FTexture::Span unmaskedSpan[2];
+		if (unmasked)
+		{
+			span = unmaskedSpan;
+			unmaskedSpan[0].TopOffset = 0;
+			unmaskedSpan[0].Length = tex->GetHeight();
+			unmaskedSpan[1].TopOffset = 0;
+			unmaskedSpan[1].Length = 0;
+		}
+
+		int pixelsize = r_swtruecolor ? 4 : 1;
+
+		while (span->Length != 0)
+		{
+			const int length = span->Length;
+			const int top = span->TopOffset;
+
+			// calculate unclipped screen coordinates for post
+			dc_yl = (int)(sprtopscreen + spryscale * top + 0.5);
+			dc_yh = (int)(sprtopscreen + spryscale * (top + length) + 0.5) - 1;
+
+			if (sprflipvert)
+			{
+				swapvalues(dc_yl, dc_yh);
+			}
+
+			if (dc_yh >= mfloorclip[dc_x])
+			{
+				dc_yh = mfloorclip[dc_x] - 1;
+			}
+			if (dc_yl < mceilingclip[dc_x])
+			{
+				dc_yl = mceilingclip[dc_x];
+			}
+
+			if (dc_yl <= dc_yh)
+			{
+				dc_texturefrac = FLOAT2FIXED((dc_yl + 0.5 - sprtopscreen) / spryscale);
+				dc_source = column;
+				dc_source2 = nullptr;
+				SetDest(dc_x, dc_yl);
+				dc_count = dc_yh - dc_yl + 1;
+
+				fixed_t maxfrac = ((top + length) << FRACBITS) - 1;
+				dc_texturefrac = MAX(dc_texturefrac, 0);
+				dc_texturefrac = MIN(dc_texturefrac, maxfrac);
+				if (dc_iscale > 0)
+					dc_count = MIN(dc_count, (maxfrac - dc_texturefrac + dc_iscale - 1) / dc_iscale);
+				else if (dc_iscale < 0)
+					dc_count = MIN(dc_count, (dc_texturefrac - dc_iscale) / (-dc_iscale));
+
+				(Drawers()->*colfunc)(*this);
+			}
+			span++;
+		}
+	}
+
+	void ColumnDrawerArgs::DrawMaskedColumnBgra(int x, fixed_t iscale, FTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked)
+	{
+		dc_x = x;
+		dc_iscale = iscale;
+
+		// Normalize to 0-1 range:
+		double uv_stepd = FIXED2DBL(dc_iscale);
+		double v_step = uv_stepd / tex->GetHeight();
+
+		// Convert to uint32:
+		dc_iscale = (uint32_t)(v_step * (1 << 30));
+
+		// Texture mipmap and filter selection:
+		fixed_t xoffset = col;
+
+		double xmagnitude = 1.0; // To do: pass this into R_DrawMaskedColumn
+		double ymagnitude = fabs(uv_stepd);
+		double magnitude = MAX(ymagnitude, xmagnitude);
+		double min_lod = -1000.0;
+		double lod = MAX(log2(magnitude) + r_lod_bias, min_lod);
+		bool magnifying = lod < 0.0f;
+
+		int mipmap_offset = 0;
+		int mip_width = tex->GetWidth();
+		int mip_height = tex->GetHeight();
+		uint32_t xpos = (uint32_t)((((uint64_t)xoffset) << FRACBITS) / mip_width);
+		if (r_mipmap && tex->Mipmapped() && mip_width > 1 && mip_height > 1)
+		{
+			int level = (int)lod;
+			while (level > 0 && mip_width > 1 && mip_height > 1)
+			{
+				mipmap_offset += mip_width * mip_height;
+				level--;
+				mip_width = MAX(mip_width >> 1, 1);
+				mip_height = MAX(mip_height >> 1, 1);
+			}
+		}
+		xoffset = (xpos >> FRACBITS) * mip_width;
+
+		const uint32_t *pixels = tex->GetPixelsBgra() + mipmap_offset;
+
+		bool filter_nearest = (magnifying && !r_magfilter) || (!magnifying && !r_minfilter);
+		if (filter_nearest)
+		{
+			xoffset = MAX(MIN(xoffset, (mip_width << FRACBITS) - 1), 0);
+
+			int tx = xoffset >> FRACBITS;
+			dc_source = (BYTE*)(pixels + tx * mip_height);
+			dc_source2 = nullptr;
+			dc_textureheight = mip_height;
+			dc_texturefracx = 0;
+		}
+		else
+		{
+			xoffset = MAX(MIN(xoffset - (FRACUNIT / 2), (mip_width << FRACBITS) - 1), 0);
+
+			int tx0 = xoffset >> FRACBITS;
+			int tx1 = MIN(tx0 + 1, mip_width - 1);
+			dc_source = (BYTE*)(pixels + tx0 * mip_height);
+			dc_source2 = (BYTE*)(pixels + tx1 * mip_height);
+			dc_textureheight = mip_height;
+			dc_texturefracx = (xoffset >> (FRACBITS - 4)) & 15;
+		}
+
+		// Grab the posts we need to draw
+		const FTexture::Span *span;
+		tex->GetColumnBgra(col >> FRACBITS, &span);
+		FTexture::Span unmaskedSpan[2];
+		if (unmasked)
+		{
+			span = unmaskedSpan;
+			unmaskedSpan[0].TopOffset = 0;
+			unmaskedSpan[0].Length = tex->GetHeight();
+			unmaskedSpan[1].TopOffset = 0;
+			unmaskedSpan[1].Length = 0;
+		}
+
+		// Draw each span post
+		while (span->Length != 0)
+		{
+			const int length = span->Length;
+			const int top = span->TopOffset;
+
+			// calculate unclipped screen coordinates for post
+			dc_yl = (int)(sprtopscreen + spryscale * top + 0.5);
+			dc_yh = (int)(sprtopscreen + spryscale * (top + length) + 0.5) - 1;
+
+			if (sprflipvert)
+			{
+				swapvalues(dc_yl, dc_yh);
+			}
+
+			if (dc_yh >= mfloorclip[dc_x])
+			{
+				dc_yh = mfloorclip[dc_x] - 1;
+			}
+			if (dc_yl < mceilingclip[dc_x])
+			{
+				dc_yl = mceilingclip[dc_x];
+			}
+
+			if (dc_yl <= dc_yh)
+			{
+				SetDest(dc_x, dc_yl);
+				dc_count = dc_yh - dc_yl + 1;
+
+				double v = ((dc_yl + 0.5 - sprtopscreen) / spryscale) / tex->GetHeight();
+				dc_texturefrac = (uint32_t)(v * (1 << 30));
+
+				(Drawers()->*colfunc)(*this);
+			}
+			span++;
+		}
+	}
+
+	bool DrawerArgs::SetBlendFunc(int op, fixed_t fglevel, fixed_t bglevel, int flags)
+	{
+		// r_drawtrans is a seriously bad thing to turn off. I wonder if I should
+		// just remove it completely.
+		if (!r_drawtrans || (op == STYLEOP_Add && fglevel == FRACUNIT && bglevel == 0 && !(flags & STYLEF_InvertSource)))
+		{
+			if (flags & STYLEF_ColorIsFixed)
+			{
+				colfunc = &SWPixelFormatDrawers::FillColumn;
+			}
+			else if (dc_translation == NULL)
+			{
+				colfunc = basecolfunc;
+			}
+			else
+			{
+				colfunc = transcolfunc;
+				drawer_needs_pal_input = true;
+			}
+			return true;
+		}
+		if (flags & STYLEF_InvertSource)
+		{
+			dc_srcblend = Col2RGB8_Inverse[fglevel >> 10];
+			dc_destblend = Col2RGB8_LessPrecision[bglevel >> 10];
+			dc_srcalpha = fglevel;
+			dc_destalpha = bglevel;
+		}
+		else if (op == STYLEOP_Add && fglevel + bglevel <= FRACUNIT)
+		{
+			dc_srcblend = Col2RGB8[fglevel >> 10];
+			dc_destblend = Col2RGB8[bglevel >> 10];
+			dc_srcalpha = fglevel;
+			dc_destalpha = bglevel;
+		}
+		else
+		{
+			dc_srcblend = Col2RGB8_LessPrecision[fglevel >> 10];
+			dc_destblend = Col2RGB8_LessPrecision[bglevel >> 10];
+			dc_srcalpha = fglevel;
+			dc_destalpha = bglevel;
+		}
+		switch (op)
+		{
+		case STYLEOP_Add:
+			if (fglevel == 0 && bglevel == FRACUNIT)
+			{
+				return false;
+			}
+			if (fglevel + bglevel <= FRACUNIT)
+			{ // Colors won't overflow when added
+				if (flags & STYLEF_ColorIsFixed)
+				{
+					colfunc = &SWPixelFormatDrawers::FillAddColumn;
+				}
+				else if (dc_translation == NULL)
+				{
+					colfunc = &SWPixelFormatDrawers::DrawAddColumn;
+				}
+				else
+				{
+					colfunc = &SWPixelFormatDrawers::DrawTranslatedAddColumn;
+					drawer_needs_pal_input = true;
+				}
+			}
+			else
+			{ // Colors might overflow when added
+				if (flags & STYLEF_ColorIsFixed)
+				{
+					colfunc = &SWPixelFormatDrawers::FillAddClampColumn;
+				}
+				else if (dc_translation == NULL)
+				{
+					colfunc = &SWPixelFormatDrawers::DrawAddClampColumn;
+				}
+				else
+				{
+					colfunc = &SWPixelFormatDrawers::DrawAddClampTranslatedColumn;
+					drawer_needs_pal_input = true;
+				}
+			}
+			return true;
+
+		case STYLEOP_Sub:
+			if (flags & STYLEF_ColorIsFixed)
+			{
+				colfunc = &SWPixelFormatDrawers::FillSubClampColumn;
+			}
+			else if (dc_translation == NULL)
+			{
+				colfunc = &SWPixelFormatDrawers::DrawSubClampColumn;
+			}
+			else
+			{
+				colfunc = &SWPixelFormatDrawers::DrawSubClampTranslatedColumn;
+				drawer_needs_pal_input = true;
+			}
+			return true;
+
+		case STYLEOP_RevSub:
+			if (fglevel == 0 && bglevel == FRACUNIT)
+			{
+				return false;
+			}
+			if (flags & STYLEF_ColorIsFixed)
+			{
+				colfunc = &SWPixelFormatDrawers::FillRevSubClampColumn;
+			}
+			else if (dc_translation == NULL)
+			{
+				colfunc = &SWPixelFormatDrawers::DrawRevSubClampColumn;
+			}
+			else
+			{
+				colfunc = &SWPixelFormatDrawers::DrawRevSubClampTranslatedColumn;
+				drawer_needs_pal_input = true;
+			}
+			return true;
+
+		default:
+			return false;
+		}
+	}
+
+	fixed_t DrawerArgs::GetAlpha(int type, fixed_t alpha)
+	{
+		switch (type)
+		{
+		case STYLEALPHA_Zero:		return 0;
+		case STYLEALPHA_One:		return OPAQUE;
+		case STYLEALPHA_Src:		return alpha;
+		case STYLEALPHA_InvSrc:		return OPAQUE - alpha;
+		default:					return 0;
+		}
+	}
+
+	bool DrawerArgs::SetPatchStyle(FRenderStyle style, fixed_t alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap, fixed_t shadedlightshade)
+	{
+		fixed_t fglevel, bglevel;
+
+		drawer_needs_pal_input = false;
+
+		style.CheckFuzz();
+
+		if (style.BlendOp == STYLEOP_Shadow)
+		{
+			style = LegacyRenderStyles[STYLE_TranslucentStencil];
+			alpha = TRANSLUC33;
+			color = 0;
+		}
+
+		if (style.Flags & STYLEF_ForceAlpha)
+		{
+			alpha = clamp<fixed_t>(alpha, 0, OPAQUE);
+		}
+		else if (style.Flags & STYLEF_TransSoulsAlpha)
+		{
+			alpha = fixed_t(transsouls * OPAQUE);
+		}
+		else if (style.Flags & STYLEF_Alpha1)
+		{
+			alpha = FRACUNIT;
+		}
+		else
+		{
+			alpha = clamp<fixed_t>(alpha, 0, OPAQUE);
+		}
+
+		if (translation != -1)
+		{
+			dc_translation = NULL;
+			if (translation != 0)
+			{
+				FRemapTable *table = TranslationToTable(translation);
+				if (table != NULL && !table->Inactive)
+				{
+					if (r_swtruecolor)
+						dc_translation = (uint8_t*)table->Palette;
+					else
+						dc_translation = table->Remap;
+				}
+			}
+		}
+
+		// Check for special modes
+		if (style.BlendOp == STYLEOP_Fuzz)
+		{
+			colfunc = fuzzcolfunc;
+			return true;
+		}
+		else if (style == LegacyRenderStyles[STYLE_Shaded])
+		{
+			// Shaded drawer only gets 16 levels of alpha because it saves memory.
+			if ((alpha >>= 12) == 0 || basecolormap == nullptr)
+				return false;
+			colfunc = &SWPixelFormatDrawers::DrawShadedColumn;
+			drawer_needs_pal_input = true;
+			CameraLight *cameraLight = CameraLight::Instance();
+			dc_color = cameraLight->fixedcolormap ? cameraLight->fixedcolormap->Maps[APART(color)] : basecolormap->Maps[APART(color)];
+			basecolormap = &ShadeFakeColormap[16 - alpha];
+			if (cameraLight->fixedlightlev >= 0 && cameraLight->fixedcolormap == NULL)
+			{
+				fixed_t shade = shadedlightshade;
+				if (shade == 0) FIXEDLIGHT2SHADE(cameraLight->fixedlightlev);
+				SetColorMapLight(basecolormap, 0, shade);
+			}
+			else
+			{
+				SetColorMapLight(basecolormap, 0, shadedlightshade);
+			}
+			return true;
+		}
+
+		fglevel = GetAlpha(style.SrcAlpha, alpha);
+		bglevel = GetAlpha(style.DestAlpha, alpha);
+
+		if (style.Flags & STYLEF_ColorIsFixed)
+		{
+			uint32_t x = fglevel >> 10;
+			uint32_t r = RPART(color);
+			uint32_t g = GPART(color);
+			uint32_t b = BPART(color);
+			// dc_color is used by the rt_* routines. It is indexed into dc_srcblend.
+			dc_color = RGB256k.RGB[r >> 2][g >> 2][b >> 2];
+			if (style.Flags & STYLEF_InvertSource)
+			{
+				r = 255 - r;
+				g = 255 - g;
+				b = 255 - b;
+			}
+			uint32_t alpha = clamp(fglevel >> (FRACBITS - 8), 0, 255);
+			dc_srccolor_bgra = (alpha << 24) | (r << 16) | (g << 8) | b;
+			// dc_srccolor is used by the R_Fill* routines. It is premultiplied
+			// with the alpha.
+			dc_srccolor = ((((r*x) >> 4) << 20) | ((g*x) >> 4) | ((((b)*x) >> 4) << 10)) & 0x3feffbff;
+			SetColorMapLight(&identitycolormap, 0, 0);
+		}
+
+		if (!DrawerArgs::SetBlendFunc(style.BlendOp, fglevel, bglevel, style.Flags))
+		{
+			return false;
+		}
+		return true;
+	}
+
+	bool DrawerArgs::SetPatchStyle(FRenderStyle style, float alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap, fixed_t shadedlightshade)
+	{
+		return SetPatchStyle(style, FLOAT2FIXED(alpha), translation, color, basecolormap, shadedlightshade);
+	}
+
+	void WallDrawerArgs::SetDest(int x, int y)
+	{
+		int pixelsize = r_swtruecolor ? 4 : 1;
+		dc_dest = dc_destorg + (ylookup[y] + x) * pixelsize;
+		dc_dest_y = y;
+	}
+
+	WallDrawerFunc WallDrawerArgs::GetTransMaskDrawer()
+	{
+		if (colfunc == &SWPixelFormatDrawers::DrawAddColumn)
+		{
+			return &SWPixelFormatDrawers::DrawWallAddColumn;
+		}
+		if (colfunc == &SWPixelFormatDrawers::DrawAddClampColumn)
+		{
+			return &SWPixelFormatDrawers::DrawWallAddClampColumn;
+		}
+		if (colfunc == &SWPixelFormatDrawers::DrawSubClampColumn)
+		{
+			return &SWPixelFormatDrawers::DrawWallSubClampColumn;
+		}
+		if (colfunc == &SWPixelFormatDrawers::DrawRevSubClampColumn)
+		{
+			return &SWPixelFormatDrawers::DrawWallRevSubClampColumn;
+		}
+		return nullptr;
+	}
+
+	void DrawerArgs::SetSpanStyle(bool masked, bool additive, fixed_t alpha)
+	{
+		if (masked)
+		{
+			if (alpha < OPAQUE || additive)
+			{
+				if (!additive)
+				{
+					spanfunc = &SWPixelFormatDrawers::DrawSpanMaskedTranslucent;
+					dc_srcblend = Col2RGB8[alpha >> 10];
+					dc_destblend = Col2RGB8[(OPAQUE - alpha) >> 10];
+					dc_srcalpha = alpha;
+					dc_destalpha = OPAQUE - alpha;
+				}
+				else
+				{
+					spanfunc = &SWPixelFormatDrawers::DrawSpanMaskedAddClamp;
+					dc_srcblend = Col2RGB8_LessPrecision[alpha >> 10];
+					dc_destblend = Col2RGB8_LessPrecision[FRACUNIT >> 10];
+					dc_srcalpha = alpha;
+					dc_destalpha = FRACUNIT;
+				}
+			}
+			else
+			{
+				spanfunc = &SWPixelFormatDrawers::DrawSpanMasked;
+			}
+		}
+		else
+		{
+			if (alpha < OPAQUE || additive)
+			{
+				if (!additive)
+				{
+					spanfunc = &SWPixelFormatDrawers::DrawSpanTranslucent;
+					dc_srcblend = Col2RGB8[alpha >> 10];
+					dc_destblend = Col2RGB8[(OPAQUE - alpha) >> 10];
+					dc_srcalpha = alpha;
+					dc_destalpha = OPAQUE - alpha;
+				}
+				else
+				{
+					spanfunc = &SWPixelFormatDrawers::DrawSpanAddClamp;
+					dc_srcblend = Col2RGB8_LessPrecision[alpha >> 10];
+					dc_destblend = Col2RGB8_LessPrecision[FRACUNIT >> 10];
+					dc_srcalpha = alpha;
+					dc_destalpha = FRACUNIT;
+				}
+			}
+			else
+			{
+				spanfunc = &SWPixelFormatDrawers::DrawSpan;
+			}
+		}
+	}
+
+	void SpanDrawerArgs::DrawTiltedSpan(int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap)
+	{
+		Drawers()->DrawTiltedSpan(*this, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy, basecolormap);
+	}
+
+	void SpanDrawerArgs::DrawFogBoundaryLine(int y, int x1, int x2)
+	{
+		Drawers()->DrawFogBoundaryLine(*this, y, x1, x2);
+	}
+
+	void SpanDrawerArgs::DrawColoredSpan(int y, int x1, int x2)
+	{
+		Drawers()->DrawColoredSpan(*this, y, x1, x2);
+	}
+
+	void SkyDrawerArgs::DrawSingleSkyColumn(uint32_t solid_top, uint32_t solid_bottom, bool fadeSky)
+	{
+		Drawers()->DrawSingleSkyColumn(*this, solid_top, solid_bottom, fadeSky);
+	}
+
+	void SkyDrawerArgs::DrawDoubleSkyColumn(uint32_t solid_top, uint32_t solid_bottom, bool fadeSky)
+	{
+		Drawers()->DrawDoubleSkyColumn(*this, solid_top, solid_bottom, fadeSky);
+	}
+
+	void SkyDrawerArgs::SetDest(int x, int y)
+	{
+		int pixelsize = r_swtruecolor ? 4 : 1;
+		dc_dest = dc_destorg + (ylookup[y] + x) * pixelsize;
+		dc_dest_y = y;
+	}
+
+	void ColumnDrawerArgs::FillColumn()
+	{
+		Drawers()->FillColumn(*this);
+	}
+
+	void ColumnDrawerArgs::SetDest(int x, int y)
+	{
+		int pixelsize = r_swtruecolor ? 4 : 1;
+		dc_dest = dc_destorg + (ylookup[y] + x) * pixelsize;
+		dc_dest_y = y;
+	}
+}
diff --git a/src/swrenderer/drawers/r_drawerargs.h b/src/swrenderer/drawers/r_drawerargs.h
new file mode 100644
index 000000000..053051c8c
--- /dev/null
+++ b/src/swrenderer/drawers/r_drawerargs.h
@@ -0,0 +1,215 @@
+
+#pragma once
+
+#include "templates.h"
+#include "doomtype.h"
+#include "doomdef.h"
+#include "r_defs.h"
+#include "r_draw.h"
+#include "v_video.h"
+#include "r_data/colormaps.h"
+#include "r_data/r_translate.h"
+#include "swrenderer/scene/r_light.h"
+
+struct FSWColormap;
+struct FLightNode;
+struct TriLight;
+
+namespace swrenderer
+{
+	class SWPixelFormatDrawers;
+	class DrawerArgs;
+
+	struct ShadeConstants
+	{
+		uint16_t light_alpha;
+		uint16_t light_red;
+		uint16_t light_green;
+		uint16_t light_blue;
+		uint16_t fade_alpha;
+		uint16_t fade_red;
+		uint16_t fade_green;
+		uint16_t fade_blue;
+		uint16_t desaturate;
+		bool simple_shade;
+	};
+
+	typedef void(SWPixelFormatDrawers::*DrawerFunc)(const DrawerArgs &args);
+	typedef void(SWPixelFormatDrawers::*WallDrawerFunc)(const WallDrawerArgs &args);
+	typedef void(SWPixelFormatDrawers::*ColumnDrawerFunc)(const ColumnDrawerArgs &args);
+	typedef void(SWPixelFormatDrawers::*SpanDrawerFunc)(const SpanDrawerArgs &args);
+
+	class DrawerArgs
+	{
+	public:
+		DrawerArgs();
+
+		bool SetPatchStyle(FRenderStyle style, fixed_t alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap, fixed_t shadedlightshade = 0);
+		bool SetPatchStyle(FRenderStyle style, float alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap, fixed_t shadedlightshade = 0);
+		void SetSpanStyle(bool masked, bool additive, fixed_t alpha);
+
+		// Sets dc_colormap and dc_light to their appropriate values depending on the output format (pal vs true color)
+		void SetColorMapLight(FSWColormap *base_colormap, float light, int shade);
+		void SetTranslationMap(lighttable_t *translation);
+
+		SWPixelFormatDrawers *Drawers() const;
+
+		ColumnDrawerFunc colfunc;
+		ColumnDrawerFunc basecolfunc;
+		ColumnDrawerFunc fuzzcolfunc;
+		ColumnDrawerFunc transcolfunc;
+		SpanDrawerFunc spanfunc;
+
+		uint8_t *dc_colormap;
+		ShadeConstants dc_shade_constants;
+		fixed_t dc_light = 0;
+
+		uint8_t *dc_translation;
+
+		uint32_t *dc_srcblend;
+		uint32_t *dc_destblend;
+		fixed_t dc_srcalpha;
+		fixed_t dc_destalpha;
+
+		int dc_color = 0;
+		uint32_t dc_srccolor;
+		uint32_t dc_srccolor_bgra;
+
+	protected:
+		bool drawer_needs_pal_input = false;
+
+	private:
+		bool SetBlendFunc(int op, fixed_t fglevel, fixed_t bglevel, int flags);
+		static fixed_t GetAlpha(int type, fixed_t alpha);
+	};
+
+	class SkyDrawerArgs : public DrawerArgs
+	{
+	public:
+		const uint8_t *dc_wall_source[4];
+		const uint8_t *dc_wall_source2[4];
+		uint32_t dc_wall_sourceheight[4];
+		uint32_t dc_wall_texturefrac[4];
+		uint32_t dc_wall_iscale[4];
+		int dc_count;
+
+		void SetDest(int x, int y);
+
+		uint8_t *Dest() const { return dc_dest; }
+		int DestY() const { return dc_dest_y; }
+
+		void DrawSingleSkyColumn(uint32_t solid_top, uint32_t solid_bottom, bool fadeSky);
+		void DrawDoubleSkyColumn(uint32_t solid_top, uint32_t solid_bottom, bool fadeSky);
+
+	private:
+		uint8_t *dc_dest = nullptr;
+		int dc_dest_y = 0;
+	};
+
+	class WallDrawerArgs : public DrawerArgs
+	{
+	public:
+		void SetDest(int x, int y);
+
+		WallDrawerFunc GetTransMaskDrawer();
+
+		uint8_t *Dest() const { return dc_dest; }
+		int DestY() const { return dc_dest_y; }
+
+		fixed_t dc_iscale;
+		fixed_t dc_texturefrac;
+		uint32_t dc_texturefracx;
+		uint32_t dc_textureheight;
+		const uint8_t *dc_source;
+		const uint8_t *dc_source2;
+		int dc_count;
+
+		uint32_t dc_wall_texturefrac[4];
+		uint32_t dc_wall_iscale[4];
+		uint8_t *dc_wall_colormap[4];
+		fixed_t dc_wall_light[4];
+		const uint8_t *dc_wall_source[4];
+		const uint8_t *dc_wall_source2[4];
+		uint32_t dc_wall_texturefracx[4];
+		uint32_t dc_wall_sourceheight[4];
+		int dc_wall_fracbits;
+
+		FVector3 dc_normal;
+		FVector3 dc_viewpos;
+		FVector3 dc_viewpos_step;
+		TriLight *dc_lights = nullptr;
+		int dc_num_lights = 0;
+
+	private:
+		uint8_t *dc_dest = nullptr;
+		int dc_dest_y = 0;
+	};
+
+	class SpanDrawerArgs : public DrawerArgs
+	{
+	public:
+		void SetDSColorMapLight(FSWColormap *base_colormap, float light, int shade);
+
+		void SetSpanTexture(FTexture *tex);
+		void SetSpanColormap(FDynamicColormap *colormap, int shade);
+
+		void DrawTiltedSpan(int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap);
+		void DrawColoredSpan(int y, int x1, int x2);
+		void DrawFogBoundaryLine(int y, int x1, int x2);
+
+		int ds_y;
+		int ds_x1;
+		int ds_x2;
+		uint8_t * ds_colormap;
+		ShadeConstants ds_shade_constants;
+		dsfixed_t ds_light;
+		dsfixed_t ds_xfrac;
+		dsfixed_t ds_yfrac;
+		dsfixed_t ds_xstep;
+		dsfixed_t ds_ystep;
+		int ds_xbits;
+		int ds_ybits;
+		fixed_t ds_alpha;
+		double ds_lod;
+		const uint8_t *ds_source;
+		bool ds_source_mipmapped;
+		int ds_color = 0;
+
+		FVector3 dc_normal;
+		FVector3 dc_viewpos;
+		FVector3 dc_viewpos_step;
+		TriLight *dc_lights = nullptr;
+		int dc_num_lights = 0;
+	};
+
+	class ColumnDrawerArgs : public DrawerArgs
+	{
+	public:
+		void DrawMaskedColumn(int x, fixed_t iscale, FTexture *texture, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked = false);
+		void FillColumn();
+
+		void SetDest(int x, int y);
+
+		uint8_t *Dest() const { return dc_dest; }
+		int DestY() const { return dc_dest_y; }
+
+		int dc_x;
+		int dc_yl;
+		int dc_yh;
+		fixed_t dc_iscale;
+		fixed_t dc_texturefrac;
+		uint32_t dc_textureheight;
+		const uint8_t *dc_source;
+		const uint8_t *dc_source2;
+		uint32_t dc_texturefracx;
+		int dc_count;
+
+	private:
+		void DrawMaskedColumnBgra(int x, fixed_t iscale, FTexture *tex, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked);
+
+		uint8_t *dc_dest = nullptr;
+		int dc_dest_y = 0;
+	};
+
+	void R_InitColumnDrawers();
+}
diff --git a/src/swrenderer/line/r_fogboundary.h b/src/swrenderer/line/r_fogboundary.h
index 55f0e504e..4213cb146 100644
--- a/src/swrenderer/line/r_fogboundary.h
+++ b/src/swrenderer/line/r_fogboundary.h
@@ -26,6 +26,6 @@ namespace swrenderer
 		void RenderSection(int y, int y2, int x1);
 
 		short spanend[MAXHEIGHT];
-		DrawerArgs drawerargs;
+		SpanDrawerArgs drawerargs;
 	};
 }
diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp
index 3fbe7f091..6b604d827 100644
--- a/src/swrenderer/line/r_line.cpp
+++ b/src/swrenderer/line/r_line.cpp
@@ -930,7 +930,7 @@ namespace swrenderer
 		double yscale;
 		fixed_t xoffset = rw_offset;
 
-		DrawerArgs drawerargs;
+		WallDrawerArgs drawerargs;
 
 		// [RH] Color if not texturing line
 		drawerargs.dc_color = (((int)(curline - segs) * 8) + 4) & 255;
diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp
index 76dc170f1..faa635dd7 100644
--- a/src/swrenderer/line/r_renderdrawsegment.cpp
+++ b/src/swrenderer/line/r_renderdrawsegment.cpp
@@ -67,8 +67,13 @@ namespace swrenderer
 		curline = ds->curline;
 
 		FDynamicColormap *patchstylecolormap = nullptr;
-		DrawerArgs drawerargs;
-		bool visible = drawerargs.SetPatchStyle(LegacyRenderStyles[curline->linedef->flags & ML_ADDTRANS ? STYLE_Add : STYLE_Translucent],
+
+		WallDrawerArgs walldrawerargs;
+		walldrawerargs.SetPatchStyle(LegacyRenderStyles[curline->linedef->flags & ML_ADDTRANS ? STYLE_Add : STYLE_Translucent],
+			(float)MIN(curline->linedef->alpha, 1.), 0, 0, patchstylecolormap);
+
+		ColumnDrawerArgs columndrawerargs;
+		bool visible = columndrawerargs.SetPatchStyle(LegacyRenderStyles[curline->linedef->flags & ML_ADDTRANS ? STYLE_Add : STYLE_Translucent],
 			(float)MIN(curline->linedef->alpha, 1.), 0, 0, patchstylecolormap);
 
 		if (!visible && !ds->bFogBoundary && !ds->bFakeBoundary)
@@ -142,9 +147,15 @@ namespace swrenderer
 		rw_scalestep = ds->iscalestep;
 
 		if (cameraLight->fixedlightlev >= 0)
-			drawerargs.SetColorMapLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, FIXEDLIGHT2SHADE(cameraLight->fixedlightlev));
+		{
+			walldrawerargs.SetColorMapLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, FIXEDLIGHT2SHADE(cameraLight->fixedlightlev));
+			columndrawerargs.SetColorMapLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, FIXEDLIGHT2SHADE(cameraLight->fixedlightlev));
+		}
 		else if (cameraLight->fixedcolormap != nullptr)
-			drawerargs.SetColorMapLight(cameraLight->fixedcolormap, 0, 0);
+		{
+			walldrawerargs.SetColorMapLight(cameraLight->fixedcolormap, 0, 0);
+			columndrawerargs.SetColorMapLight(cameraLight->fixedcolormap, 0, 0);
+		}
 
 		// find positioning
 		texheight = tex->GetScaledHeightDouble();
@@ -273,7 +284,7 @@ namespace swrenderer
 				{
 					if (cameraLight->fixedcolormap == nullptr && cameraLight->fixedlightlev < 0)
 					{
-						drawerargs.SetColorMapLight(basecolormap, rw_light, wallshade);
+						columndrawerargs.SetColorMapLight(basecolormap, rw_light, wallshade);
 					}
 
 					fixed_t iscale = xs_Fix<16>::ToFix(MaskedSWall[x] * MaskedScaleY);
@@ -283,7 +294,7 @@ namespace swrenderer
 					else
 						sprtopscreen = CenterY - texturemid * spryscale;
 
-					drawerargs.DrawMaskedColumn(x, iscale, tex, maskedtexturecol[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip);
+					columndrawerargs.DrawMaskedColumn(x, iscale, tex, maskedtexturecol[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip);
 
 					rw_light += rw_lightstep;
 					spryscale += rw_scalestep;
@@ -349,7 +360,7 @@ namespace swrenderer
 			GetMaskedWallTopBottom(ds, top, bot);
 
 			RenderWallPart renderWallpart;
-			renderWallpart.Render(drawerargs, frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, texturemid, MaskedSWall, maskedtexturecol, ds->yscale, top, bot, true, wallshade, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap);
+			renderWallpart.Render(walldrawerargs, frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, texturemid, MaskedSWall, maskedtexturecol, ds->yscale, top, bot, true, wallshade, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap);
 		}
 
 	clearfog:
@@ -383,7 +394,7 @@ namespace swrenderer
 		double yscale;
 
 		fixed_t Alpha = Scale(rover->alpha, OPAQUE, 255);
-		DrawerArgs drawerargs;
+		WallDrawerArgs drawerargs;
 		bool visible = drawerargs.SetPatchStyle(LegacyRenderStyles[rover->flags & FF_ADDITIVETRANS ? STYLE_Add : STYLE_Translucent],
 			Alpha, 0, 0, basecolormap);
 
diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp
index 2a28b2312..796788a0e 100644
--- a/src/swrenderer/line/r_walldraw.cpp
+++ b/src/swrenderer/line/r_walldraw.cpp
@@ -168,7 +168,7 @@ namespace swrenderer
 	}
 
 	// Draw a column with support for non-power-of-two ranges
-	void RenderWallPart::Draw1Column(int x, int y1, int y2, WallSampler &sampler, DrawerFunc draw1column)
+	void RenderWallPart::Draw1Column(int x, int y1, int y2, WallSampler &sampler, WallDrawerFunc draw1column)
 	{
 		if (r_dynlights && light_list)
 		{
@@ -306,7 +306,7 @@ namespace swrenderer
 		}
 	}
 
-	void RenderWallPart::ProcessWallWorker(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal, DrawerFunc drawcolumn)
+	void RenderWallPart::ProcessWallWorker(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal, WallDrawerFunc drawcolumn)
 	{
 		if (rw_pic->UseType == FTexture::TEX_Null)
 			return;
@@ -388,7 +388,7 @@ namespace swrenderer
 
 	void RenderWallPart::ProcessTranslucentWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal)
 	{
-		DrawerFunc drawcol1 = drawerargs.GetTransMaskDrawer();
+		WallDrawerFunc drawcol1 = drawerargs.GetTransMaskDrawer();
 		if (drawcol1 == nullptr)
 		{
 			// The current translucency is unsupported, so draw with regular ProcessMaskedWall instead.
@@ -536,7 +536,7 @@ namespace swrenderer
 		}
 	}
 
-	void RenderWallPart::Render(const DrawerArgs &drawerargs, sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, FTexture *pic, int x1, int x2, const short *walltop, const short *wallbottom, double texturemid, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, int wallshade, fixed_t xoffset, float light, float lightstep, FLightNode *light_list, bool foggy, FDynamicColormap *basecolormap)
+	void RenderWallPart::Render(const WallDrawerArgs &drawerargs, sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, FTexture *pic, int x1, int x2, const short *walltop, const short *wallbottom, double texturemid, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, int wallshade, fixed_t xoffset, float light, float lightstep, FLightNode *light_list, bool foggy, FDynamicColormap *basecolormap)
 	{
 		this->drawerargs = drawerargs;
 		this->x1 = x1;
diff --git a/src/swrenderer/line/r_walldraw.h b/src/swrenderer/line/r_walldraw.h
index 24060129c..8b2c24491 100644
--- a/src/swrenderer/line/r_walldraw.h
+++ b/src/swrenderer/line/r_walldraw.h
@@ -34,7 +34,7 @@ namespace swrenderer
 	{
 	public:
 		void Render(
-			const DrawerArgs &drawerargs,
+			const WallDrawerArgs &drawerargs,
 			sector_t *frontsector,
 			seg_t *curline,
 			const FWallCoords &WallC,
@@ -65,8 +65,8 @@ namespace swrenderer
 		void ProcessTranslucentWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal);
 		void ProcessMaskedWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal);
 		void ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal);
-		void ProcessWallWorker(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal, DrawerFunc drawcolumn);
-		void Draw1Column(int x, int y1, int y2, WallSampler &sampler, DrawerFunc draw1column);
+		void ProcessWallWorker(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal, WallDrawerFunc drawcolumn);
+		void Draw1Column(int x, int y1, int y2, WallSampler &sampler, WallDrawerFunc draw1column);
 
 		int x1 = 0;
 		int x2 = 0;
@@ -85,7 +85,7 @@ namespace swrenderer
 		FLightNode *light_list = nullptr;
 		bool mask = false;
 
-		DrawerArgs drawerargs;
+		WallDrawerArgs drawerargs;
 	};
 
 	struct WallSampler
diff --git a/src/swrenderer/plane/r_flatplane.h b/src/swrenderer/plane/r_flatplane.h
index a47ccca27..385305cd0 100644
--- a/src/swrenderer/plane/r_flatplane.h
+++ b/src/swrenderer/plane/r_flatplane.h
@@ -42,7 +42,7 @@ namespace swrenderer
 		double basexfrac, baseyfrac;
 		VisiblePlaneLight *light_list;
 
-		DrawerArgs drawerargs;
+		SpanDrawerArgs drawerargs;
 
 		static float yslope[MAXHEIGHT];
 	};
@@ -55,6 +55,6 @@ namespace swrenderer
 	private:
 		void RenderLine(int y, int x1, int x2) override;
 
-		DrawerArgs drawerargs;
+		SpanDrawerArgs drawerargs;
 	};
 }
diff --git a/src/swrenderer/plane/r_skyplane.h b/src/swrenderer/plane/r_skyplane.h
index 969b8deae..e62032a9d 100644
--- a/src/swrenderer/plane/r_skyplane.h
+++ b/src/swrenderer/plane/r_skyplane.h
@@ -38,6 +38,6 @@ namespace swrenderer
 		double skymid = 0.0;
 		angle_t skyangle = 0;
 
-		DrawerArgs drawerargs;
+		SkyDrawerArgs drawerargs;
 	};
 }
diff --git a/src/swrenderer/plane/r_slopeplane.h b/src/swrenderer/plane/r_slopeplane.h
index dd0820ab2..ccdfb316d 100644
--- a/src/swrenderer/plane/r_slopeplane.h
+++ b/src/swrenderer/plane/r_slopeplane.h
@@ -33,6 +33,6 @@ namespace swrenderer
 		fixed_t pviewx, pviewy;
 		fixed_t xscale, yscale;
 		FDynamicColormap *basecolormap;
-		DrawerArgs drawerargs;
+		SpanDrawerArgs drawerargs;
 	};
 }
diff --git a/src/swrenderer/things/r_decal.cpp b/src/swrenderer/things/r_decal.cpp
index 9a831f59b..ad830101f 100644
--- a/src/swrenderer/things/r_decal.cpp
+++ b/src/swrenderer/things/r_decal.cpp
@@ -274,7 +274,7 @@ namespace swrenderer
 		{
 			int x = x1;
 
-			DrawerArgs drawerargs;
+			ColumnDrawerArgs drawerargs;
 
 			if (cameraLight->fixedlightlev >= 0)
 				drawerargs.SetColorMapLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, FIXEDLIGHT2SHADE(cameraLight->fixedlightlev));
@@ -315,7 +315,7 @@ namespace swrenderer
 		} while (needrepeat--);
 	}
 
-	void RenderDecal::DrawColumn(DrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip)
+	void RenderDecal::DrawColumn(ColumnDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip)
 	{
 		float iscale = walltexcoords.VStep[x] * maskedScaleY;
 		double spryscale = 1 / iscale;
diff --git a/src/swrenderer/things/r_decal.h b/src/swrenderer/things/r_decal.h
index 712436988..00f232651 100644
--- a/src/swrenderer/things/r_decal.h
+++ b/src/swrenderer/things/r_decal.h
@@ -20,7 +20,7 @@ namespace swrenderer
 {
 	struct DrawSegment;
 	class ProjectedWallTexcoords;
-	class DrawerArgs;
+	class ColumnDrawerArgs;
 
 	class RenderDecal
 	{
@@ -29,6 +29,6 @@ namespace swrenderer
 
 	private:
 		static void Render(side_t *wall, DBaseDecal *first, DrawSegment *clipper, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, int pass);
-		static void DrawColumn(DrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip);
+		static void DrawColumn(ColumnDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip);
 	};
 }
diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp
index 051fd403c..2d937bef7 100644
--- a/src/swrenderer/things/r_playersprite.cpp
+++ b/src/swrenderer/things/r_playersprite.cpp
@@ -587,7 +587,7 @@ namespace swrenderer
 			return;
 		}
 
-		DrawerArgs drawerargs;
+		ColumnDrawerArgs drawerargs;
 		drawerargs.SetColorMapLight(Light.BaseColormap, 0, Light.ColormapNum << FRACBITS);
 
 		FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(Light.BaseColormap);
diff --git a/src/swrenderer/things/r_sprite.cpp b/src/swrenderer/things/r_sprite.cpp
index 18aebe820..5110f550f 100644
--- a/src/swrenderer/things/r_sprite.cpp
+++ b/src/swrenderer/things/r_sprite.cpp
@@ -245,7 +245,7 @@ namespace swrenderer
 			return;
 		}
 
-		DrawerArgs drawerargs;
+		ColumnDrawerArgs drawerargs;
 		drawerargs.SetColorMapLight(vis->Light.BaseColormap, 0, vis->Light.ColormapNum << FRACBITS);
 
 		FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(vis->Light.BaseColormap);
diff --git a/src/swrenderer/things/r_voxel.cpp b/src/swrenderer/things/r_voxel.cpp
index d4ce96304..bc6e8ad65 100644
--- a/src/swrenderer/things/r_voxel.cpp
+++ b/src/swrenderer/things/r_voxel.cpp
@@ -187,7 +187,7 @@ namespace swrenderer
 
 		FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(sprite->Light.BaseColormap);
 
-		DrawerArgs drawerargs;
+		ColumnDrawerArgs drawerargs;
 		drawerargs.SetColorMapLight(sprite->Light.BaseColormap, 0, sprite->Light.ColormapNum << FRACBITS);
 
 		bool visible = drawerargs.SetPatchStyle(sprite->RenderStyle, sprite->Alpha, sprite->Translation, sprite->FillColor, basecolormap);
@@ -311,7 +311,7 @@ namespace swrenderer
 		return (kvxslab_t*)(((uint8_t*)slab) + 3 + slab->zleng);
 	}
 
-	void RenderVoxel::FillBox(DrawerArgs &drawerargs, DVector3 origin, double extentX, double extentY, int color, short *cliptop, short *clipbottom, bool viewspace, bool pixelstretch)
+	void RenderVoxel::FillBox(ColumnDrawerArgs &drawerargs, DVector3 origin, double extentX, double extentY, int color, short *cliptop, short *clipbottom, bool viewspace, bool pixelstretch)
 	{
 		double viewX, viewY, viewZ;
 		if (viewspace)
diff --git a/src/swrenderer/things/r_voxel.h b/src/swrenderer/things/r_voxel.h
index 7762330a2..f08f33654 100644
--- a/src/swrenderer/things/r_voxel.h
+++ b/src/swrenderer/things/r_voxel.h
@@ -31,7 +31,7 @@ struct FVoxel;
 
 namespace swrenderer
 {
-	class DrawerArgs;
+	class ColumnDrawerArgs;
 
 	// [RH] A c-buffer. Used for keeping track of offscreen voxel spans.
 	struct FCoverageBuffer
@@ -83,7 +83,7 @@ namespace swrenderer
 
 		enum { DVF_OFFSCREEN = 1, DVF_SPANSONLY = 2, DVF_MIRRORED = 4 };
 
-		static void FillBox(DrawerArgs &drawerargs, DVector3 origin, double extentX, double extentY, int color, short *cliptop, short *clipbottom, bool viewspace, bool pixelstretch);
+		static void FillBox(ColumnDrawerArgs &drawerargs, DVector3 origin, double extentX, double extentY, int color, short *cliptop, short *clipbottom, bool viewspace, bool pixelstretch);
 
 		static kvxslab_t *GetSlabStart(const FVoxelMipLevel &mip, int x, int y);
 		static kvxslab_t *GetSlabEnd(const FVoxelMipLevel &mip, int x, int y);
diff --git a/src/swrenderer/things/r_wallsprite.cpp b/src/swrenderer/things/r_wallsprite.cpp
index bad1f07e1..94a0d294c 100644
--- a/src/swrenderer/things/r_wallsprite.cpp
+++ b/src/swrenderer/things/r_wallsprite.cpp
@@ -179,7 +179,7 @@ namespace swrenderer
 			rereadcolormap = false;
 		}
 
-		DrawerArgs drawerargs;
+		ColumnDrawerArgs drawerargs;
 
 		int shade = LIGHT2SHADE(spr->sector->lightlevel + R_ActualExtraLight(spr->foggy));
 		double GlobVis = LightVisibility::Instance()->WallGlobVis();
@@ -245,7 +245,7 @@ namespace swrenderer
 		}
 	}
 
-	void RenderWallSprite::DrawColumn(DrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip)
+	void RenderWallSprite::DrawColumn(ColumnDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip)
 	{
 		float iscale = walltexcoords.VStep[x] * maskedScaleY;
 		double spryscale = 1 / iscale;
diff --git a/src/swrenderer/things/r_wallsprite.h b/src/swrenderer/things/r_wallsprite.h
index bc3fb3b41..ffdb36997 100644
--- a/src/swrenderer/things/r_wallsprite.h
+++ b/src/swrenderer/things/r_wallsprite.h
@@ -18,7 +18,7 @@
 namespace swrenderer
 {
 	class ProjectedWallTexcoords;
-	class DrawerArgs;
+	class ColumnDrawerArgs;
 
 	class RenderWallSprite : public VisibleSprite
 	{
@@ -30,7 +30,7 @@ namespace swrenderer
 		void Render(short *cliptop, short *clipbottom, int minZ, int maxZ) override;
 
 	private:
-		static void DrawColumn(DrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip);
+		static void DrawColumn(ColumnDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip);
 
 		FWallCoords wallc;
 		uint32_t Translation = 0;
diff --git a/src/v_draw.cpp b/src/v_draw.cpp
index d4e077eb6..c5240c34a 100644
--- a/src/v_draw.cpp
+++ b/src/v_draw.cpp
@@ -184,7 +184,7 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
 			translation = parms.remap->Remap;
 	}
 
-	DrawerArgs drawerargs;
+	ColumnDrawerArgs drawerargs;
 
 	if (translation != NULL)
 	{
@@ -1387,7 +1387,7 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints,
 	sinrot = sin(rotation.Radians());
 
 	// Setup constant texture mapping parameters.
-	DrawerArgs drawerargs;
+	SpanDrawerArgs drawerargs;
 	drawerargs.SetSpanTexture(tex);
 	if (colormap)
 		drawerargs.SetSpanColormap(colormap, clamp(shade >> FRACBITS, 0, NUMCOLORMAPS - 1));