diff --git a/src/r_defs.h b/src/r_defs.h
index 9e32777dfedaadf10585bc77ad7d752494630488..964956503b9e1503128b2c4ba549af5226de0e7c 100644
--- a/src/r_defs.h
+++ b/src/r_defs.h
@@ -740,9 +740,7 @@ typedef struct
 {
 	patch_t *patch[8][ROTANGLES];
 	boolean cached[8];
-#ifdef HWRENDER
 	aatree_t *hardware_patch[8];
-#endif
 } rotsprite_t;
 #endif
 
diff --git a/src/r_patch.c b/src/r_patch.c
index d4bfa9cbda29f84a07b234d91d13324a14979875..ec394e731f799446df2094e5b84980d5d3ab781f 100644
--- a/src/r_patch.c
+++ b/src/r_patch.c
@@ -1374,4 +1374,18 @@ void R_FreeSkinRotSprite(size_t skinnum)
 		skinsprites++;
 	}
 }
+
+//
+// R_FreeAllRotSprite
+//
+// Free ALL sprite rotation data from memory.
+//
+void R_FreeAllRotSprite(void)
+{
+	INT32 i;
+	for (i = 0; i < numsprites; i++)
+		R_FreeSingleRotSprite(&sprites[i]);
+	for (i = 0; i < numskins; ++i)
+		R_FreeSkinRotSprite(i);
+}
 #endif
diff --git a/src/r_patch.h b/src/r_patch.h
index 8a8ab5602bbebaa507a84cb129b82d5a35bac53d..53d306b8870e42adfed06e2004d24d87af9f4e8f 100644
--- a/src/r_patch.h
+++ b/src/r_patch.h
@@ -69,6 +69,7 @@ void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum);
 void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip);
 void R_FreeSingleRotSprite(spritedef_t *spritedef);
 void R_FreeSkinRotSprite(size_t skinnum);
+void R_FreeAllRotSprite(void);
 extern fixed_t cosang2rad[ROTANGLES];
 extern fixed_t sinang2rad[ROTANGLES];
 #endif
diff --git a/src/r_things.c b/src/r_things.c
index aa2a73515adfd2d75d450e18b6d9d10c9b050f34..bbe62d88ae6639e886f8c5f7ae5bd01485de724a 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -125,10 +125,7 @@ static void R_InstallSpriteLump(UINT16 wad,            // graphics patch
 		sprtemp[frame].rotsprite.cached[r] = false;
 		for (ang = 0; ang < ROTANGLES; ang++)
 			sprtemp[frame].rotsprite.patch[r][ang] = NULL;
-#ifdef HWRENDER
-		if (rendermode == render_opengl)
-			sprtemp[frame].rotsprite.hardware_patch[r] = M_AATreeAlloc(AATREE_ZUSER);
-#endif // HWRENDER
+		sprtemp[frame].rotsprite.hardware_patch[r] = M_AATreeAlloc(AATREE_ZUSER);
 	}
 #endif
 
diff --git a/src/screen.c b/src/screen.c
index 94b6c2454a12d26856163cd986845ed35f6473a6..16ba130878d0547fae00f818b00899f598af27d4 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -200,6 +200,7 @@ void SCR_SetMode(void)
 	// Lactozilla: Renderer switching
 	if (setrenderneeded)
 	{
+		Z_PreparePatchFlush();
 		needpatchflush = true;
 		needpatchrecache = true;
 		VID_CheckRenderer();
diff --git a/src/z_zone.c b/src/z_zone.c
index e0c56ced69b63c393602ddf69da7f5f41e661661..5a0ff638bfd7e09512af622abf46d66565251029 100644
--- a/src/z_zone.c
+++ b/src/z_zone.c
@@ -27,6 +27,7 @@
 
 #include "doomdef.h"
 #include "doomstat.h"
+#include "r_patch.h"
 #include "i_system.h" // I_GetFreeMem
 #include "i_video.h" // rendermode
 #include "z_zone.h"
@@ -517,6 +518,15 @@ void Z_FlushCachedPatches(void)
 	Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED);
 }
 
+// happens before a renderer switch
+void Z_PreparePatchFlush(void)
+{
+	CONS_Debug(DBG_RENDER, "Z_PreparePatchFlush()...\n");
+#ifdef ROTSPRITE
+	R_FreeAllRotSprite();
+#endif
+}
+
 // starting value of nextcleanup
 #define CLEANUPCOUNT 2000
 
diff --git a/src/z_zone.h b/src/z_zone.h
index d70e9285b6bea0f01c76a8157bd59f77023ef614..9e5f74343aa0b009956ad13af57fa8e01be089a0 100644
--- a/src/z_zone.h
+++ b/src/z_zone.h
@@ -147,5 +147,6 @@ char *Z_StrDup(const char *in);
 extern boolean needpatchflush;
 extern boolean needpatchrecache;
 void Z_FlushCachedPatches(void);
+void Z_PreparePatchFlush(void);
 
 #endif