diff --git a/Source/engine/render/blit_impl.hpp b/Source/engine/render/blit_impl.hpp
index f352b5a19fd9..5d6bb8e72c9b 100644
--- a/Source/engine/render/blit_impl.hpp
+++ b/Source/engine/render/blit_impl.hpp
@@ -10,12 +10,6 @@
 
 namespace devilution {
 
-#if __cpp_lib_execution >= 201902L
-#define DEVILUTIONX_BLIT_EXECUTION_POLICY std::execution::unseq,
-#else
-#define DEVILUTIONX_BLIT_EXECUTION_POLICY
-#endif
-
 DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void BlitFillDirect(uint8_t *dst, unsigned length, uint8_t color)
 {
 	DVL_ASSUME(length != 0);
@@ -48,7 +42,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void BlitFillWithMap(uint8_t *dst, unsigned
 DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void BlitPixelsWithMap(uint8_t *DVL_RESTRICT dst, const uint8_t *DVL_RESTRICT src, unsigned length, const uint8_t *DVL_RESTRICT colorMap)
 {
 	DVL_ASSUME(length != 0);
-	std::transform(DEVILUTIONX_BLIT_EXECUTION_POLICY src, src + length, dst, [colorMap](uint8_t srcColor) { return colorMap[srcColor]; });
+	std::transform(DVL_EXECUTION_UNSEQ src, src + length, dst, [colorMap](uint8_t srcColor) { return colorMap[srcColor]; });
 }
 
 struct BlitWithMap {
@@ -67,7 +61,7 @@ struct BlitWithMap {
 DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void BlitFillBlended(uint8_t *dst, unsigned length, uint8_t color)
 {
 	DVL_ASSUME(length != 0);
-	std::for_each(DEVILUTIONX_BLIT_EXECUTION_POLICY dst, dst + length, [tbl = paletteTransparencyLookup[color]](uint8_t &dstColor) {
+	std::for_each(DVL_EXECUTION_UNSEQ dst, dst + length, [tbl = paletteTransparencyLookup[color]](uint8_t &dstColor) {
 		dstColor = tbl[dstColor];
 	});
 }
@@ -75,7 +69,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void BlitFillBlended(uint8_t *dst, unsigned
 DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void BlitPixelsBlended(uint8_t *DVL_RESTRICT dst, const uint8_t *DVL_RESTRICT src, unsigned length)
 {
 	DVL_ASSUME(length != 0);
-	std::transform(DEVILUTIONX_BLIT_EXECUTION_POLICY src, src + length, dst, dst, [pal = paletteTransparencyLookup](uint8_t srcColor, uint8_t dstColor) {
+	std::transform(DVL_EXECUTION_UNSEQ src, src + length, dst, dst, [pal = paletteTransparencyLookup](uint8_t srcColor, uint8_t dstColor) {
 		return pal[srcColor][dstColor];
 	});
 }
@@ -94,7 +88,7 @@ struct BlitBlended {
 DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void BlitPixelsBlendedWithMap(uint8_t *DVL_RESTRICT dst, const uint8_t *DVL_RESTRICT src, unsigned length, const uint8_t *DVL_RESTRICT colorMap)
 {
 	DVL_ASSUME(length != 0);
-	std::transform(DEVILUTIONX_BLIT_EXECUTION_POLICY src, src + length, dst, dst, [colorMap, pal = paletteTransparencyLookup](uint8_t srcColor, uint8_t dstColor) {
+	std::transform(DVL_EXECUTION_UNSEQ src, src + length, dst, dst, [colorMap, pal = paletteTransparencyLookup](uint8_t srcColor, uint8_t dstColor) {
 		return pal[dstColor][colorMap[srcColor]];
 	});
 }
diff --git a/Source/engine/render/dun_render.cpp b/Source/engine/render/dun_render.cpp
index 2fda02f407da..be9e0dee83d2 100644
--- a/Source/engine/render/dun_render.cpp
+++ b/Source/engine/render/dun_render.cpp
@@ -14,14 +14,12 @@
 
 #include <SDL_endian.h>
 
-#include <algorithm>
 #include <climits>
 #include <cstdint>
+#include <cstring>
 
 #include "engine/render/blit_impl.hpp"
 #include "levels/dun_tile.hpp"
-#include "lighting.h"
-#include "options.h"
 #include "utils/attributes.h"
 #ifdef DEBUG_STR
 #include "engine/render/text_render.hpp"
@@ -282,16 +280,6 @@ DVL_ALWAYS_INLINE Clip CalculateClip(int_fast16_t x, int_fast16_t y, int_fast16_
 	return clip;
 }
 
-DVL_ALWAYS_INLINE bool IsFullyDark(const uint8_t *DVL_RESTRICT tbl)
-{
-	return tbl == FullyDarkLightTable;
-}
-
-DVL_ALWAYS_INLINE bool IsFullyLit(const uint8_t *DVL_RESTRICT tbl)
-{
-	return tbl == FullyLitLightTable;
-}
-
 template <LightType Light, bool Transparent>
 DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderSquareFull(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl)
 {
@@ -906,7 +894,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderRightTrapezoid(uint8_t *DVL_RESTR
 }
 
 template <LightType Light, bool Transparent>
-DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTileType(TileType tile, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip)
+void RenderTileType(TileType tile, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip)
 {
 	switch (tile) {
 	case TileType::Square:
@@ -997,7 +985,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderRightTrapezoidOrTransparentSquare
 }
 
 template <bool Transparent>
-DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTileDispatch(TileType tile, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip)
+void RenderTileDispatch(TileType tile, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip)
 {
 	if (IsFullyDark(tbl)) {
 		RenderTileType<LightType::FullyDark, Transparent>(tile, dst, dstPitch, src, tbl, clip);
@@ -1009,7 +997,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTileDispatch(TileType tile, uint8
 }
 
 // Blit with left and vertical clipping.
-void RenderBlackTileClipLeftAndVertical(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, int sx, DiamondClipY clipY)
+void RenderSingleColorTileClipLeftAndVertical(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, int sx, DiamondClipY clipY, uint8_t color)
 {
 	dst += XStep * (LowerHeight - clipY.lowerBottom - 1);
 	// Lower triangle (drawn bottom to top):
@@ -1018,9 +1006,9 @@ void RenderBlackTileClipLeftAndVertical(uint8_t *DVL_RESTRICT dst, uint16_t dstP
 		const auto w = 2 * XStep * i;
 		const auto curX = sx + TILE_WIDTH / 2 - XStep * i;
 		if (curX >= 0) {
-			memset(dst, 0, w);
+			memset(dst, color, w);
 		} else if (-curX <= w) {
-			memset(dst - curX, 0, w + curX);
+			memset(dst - curX, color, w + curX);
 		}
 	}
 	dst += 2 * XStep + XStep * clipY.upperBottom;
@@ -1030,9 +1018,9 @@ void RenderBlackTileClipLeftAndVertical(uint8_t *DVL_RESTRICT dst, uint16_t dstP
 		const auto w = 2 * XStep * (TriangleUpperHeight - i);
 		const auto curX = sx + TILE_WIDTH / 2 - XStep * (TriangleUpperHeight - i);
 		if (curX >= 0) {
-			memset(dst, 0, w);
+			memset(dst, color, w);
 		} else if (-curX <= w) {
-			memset(dst - curX, 0, w + curX);
+			memset(dst - curX, color, w + curX);
 		} else {
 			break;
 		}
@@ -1040,7 +1028,7 @@ void RenderBlackTileClipLeftAndVertical(uint8_t *DVL_RESTRICT dst, uint16_t dstP
 }
 
 // Blit with right and vertical clipping.
-void RenderBlackTileClipRightAndVertical(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, int_fast16_t maxWidth, DiamondClipY clipY)
+void RenderSingleColorTileClipRightAndVertical(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, int_fast16_t maxWidth, DiamondClipY clipY, uint8_t color)
 {
 	dst += XStep * (LowerHeight - clipY.lowerBottom - 1);
 	// Lower triangle (drawn bottom to top):
@@ -1050,7 +1038,7 @@ void RenderBlackTileClipRightAndVertical(uint8_t *DVL_RESTRICT dst, uint16_t dst
 		const auto endX = TILE_WIDTH / 2 + XStep * i;
 		const auto skip = endX > maxWidth ? endX - maxWidth : 0;
 		if (width > skip)
-			memset(dst, 0, width - skip);
+			memset(dst, color, width - skip);
 	}
 	dst += 2 * XStep + XStep * clipY.upperBottom;
 	// Upper triangle (drawn bottom to top):
@@ -1066,35 +1054,35 @@ void RenderBlackTileClipRightAndVertical(uint8_t *DVL_RESTRICT dst, uint16_t dst
 }
 
 // Blit with vertical clipping only.
-void RenderBlackTileClipY(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, DiamondClipY clipY)
+void RenderSingleColorTileClipY(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, DiamondClipY clipY, uint8_t color)
 {
 	dst += XStep * (LowerHeight - clipY.lowerBottom - 1);
 	// Lower triangle (drawn bottom to top):
 	const auto lowerMax = LowerHeight - clipY.lowerTop;
 	for (auto i = 1 + clipY.lowerBottom; i <= lowerMax; ++i, dst -= dstPitch + XStep) {
-		memset(dst, 0, 2 * XStep * i);
+		memset(dst, color, 2 * XStep * i);
 	}
 	dst += 2 * XStep + XStep * clipY.upperBottom;
 	// Upper triangle (drawn bottom to top):
 	const auto upperMax = TriangleUpperHeight - clipY.upperTop;
 	for (auto i = 1 + clipY.upperBottom; i <= upperMax; ++i, dst -= dstPitch - XStep) {
-		memset(dst, 0, TILE_WIDTH - 2 * XStep * i);
+		memset(dst, color, TILE_WIDTH - 2 * XStep * i);
 	}
 }
 
-// Blit a black tile without clipping (must be fully in bounds).
-void RenderBlackTileFull(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch)
+// Blit a single color tile without clipping (must be fully in bounds).
+void RenderSingleColorTileFull(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, uint8_t color)
 {
 	dst += XStep * (LowerHeight - 1);
 	// Tile is fully in bounds, can use constant loop boundaries.
 	// Lower triangle (drawn bottom to top):
 	for (unsigned i = 1; i <= LowerHeight; ++i, dst -= dstPitch + XStep) {
-		memset(dst, 0, 2 * XStep * i);
+		memset(dst, color, 2 * XStep * i);
 	}
 	dst += 2 * XStep;
 	// Upper triangle (drawn bottom to to top):
 	for (unsigned i = 1; i <= TriangleUpperHeight; ++i, dst -= dstPitch - XStep) {
-		memset(dst, 0, TILE_WIDTH - 2 * XStep * i);
+		memset(dst, color, TILE_WIDTH - 2 * XStep * i);
 	}
 }
 
@@ -1189,7 +1177,16 @@ void RenderTile(const Surface &out, Point position,
 #endif
 }
 
-void world_draw_black_tile(const Surface &out, int sx, int sy)
+void BlitFloorTileToBuffer(LevelCelBlock levelCelBlock, const uint8_t *tbl, uint8_t *out)
+{
+	const TileType tile = levelCelBlock.type();
+	const auto *pFrameTable = reinterpret_cast<const uint32_t *>(pDungeonCels.get());
+	const auto *src = reinterpret_cast<const uint8_t *>(&pDungeonCels[SDL_SwapLE32(pFrameTable[levelCelBlock.frame()])]);
+	const Clip clip { .top = 0, .bottom = 0, .left = 0, .right = 0, .width = Width, .height = GetTileHeight(tile) };
+	RenderTileDispatch</*Transparent=*/false>(tile, out, DunFrameWidth, src, tbl, clip);
+}
+
+void RenderSingleColorTile(const Surface &out, int sx, int sy, uint8_t color)
 {
 #ifdef DEBUG_RENDER_OFFSET_X
 	sx += DEBUG_RENDER_OFFSET_X;
@@ -1205,16 +1202,75 @@ void world_draw_black_tile(const Surface &out, int sx, int sy)
 	uint8_t *dst = out.at(sx, static_cast<int>(sy - clip.bottom));
 	if (clip.width == TILE_WIDTH) {
 		if (clip.height == TriangleHeight) {
-			RenderBlackTileFull(dst, out.pitch());
+			RenderSingleColorTileFull(dst, out.pitch(), color);
 		} else {
-			RenderBlackTileClipY(dst, out.pitch(), clipY);
+			RenderSingleColorTileClipY(dst, out.pitch(), clipY, color);
 		}
 	} else {
 		if (clip.right == 0) {
-			RenderBlackTileClipLeftAndVertical(dst, out.pitch(), sx, clipY);
+			RenderSingleColorTileClipLeftAndVertical(dst, out.pitch(), sx, clipY, color);
 		} else {
-			RenderBlackTileClipRightAndVertical(dst, out.pitch(), clip.width, clipY);
+			RenderSingleColorTileClipRightAndVertical(dst, out.pitch(), clip.width, clipY, color);
+		}
+	}
+}
+
+void RenderOpaqueTile(const Surface &out, Point position, LevelCelBlock levelCelBlock, const uint8_t *tbl)
+{
+	const TileType tile = levelCelBlock.type();
+	const Clip clip = CalculateClip(position.x, position.y, Width, GetTileHeight(tile), out);
+	if (clip.width <= 0 || clip.height <= 0) return;
+	const auto *pFrameTable = reinterpret_cast<const uint32_t *>(pDungeonCels.get());
+	const auto *src = reinterpret_cast<const uint8_t *>(&pDungeonCels[SDL_SwapLE32(pFrameTable[levelCelBlock.frame()])]);
+	uint8_t *dst = out.at(static_cast<int>(position.x + clip.left), static_cast<int>(position.y - clip.bottom));
+	const uint16_t dstPitch = out.pitch();
+	RenderTileDispatch</*Transparent=*/false>(tile, dst, dstPitch, src, tbl, clip);
+}
+
+void RenderFullyLitOpaqueTile(TileType tile, const Surface &out, Point position, const uint8_t *DVL_RESTRICT src)
+{
+	const Clip clip = CalculateClip(position.x, position.y, Width, GetTileHeight(tile), out);
+	if (clip.width <= 0 || clip.height <= 0) return;
+	uint8_t *dst = out.at(static_cast<int>(position.x + clip.left), static_cast<int>(position.y - clip.bottom));
+	const uint16_t dstPitch = out.pitch();
+	RenderTileType<LightType::FullyLit, /*Transparent=*/false>(tile, dst, dstPitch, src, nullptr, clip);
+}
+
+void DunTileApplyTrans(LevelCelBlock levelCelBlock, uint8_t *dst, const uint8_t *tbl)
+{
+	const TileType tile = levelCelBlock.type();
+	const auto *pFrameTable = reinterpret_cast<const uint32_t *>(pDungeonCels.get());
+	const auto *src = reinterpret_cast<const uint8_t *>(&pDungeonCels[SDL_SwapLE32(pFrameTable[levelCelBlock.frame()])]);
+
+	switch (tile) {
+	case TileType::Square:
+		BlitPixelsWithMap(dst, src, Width * Height, tbl);
+		break;
+	case TileType::TransparentSquare:
+		for (size_t i = 0; i < Height; ++i) {
+			uint_fast8_t drawWidth = Width;
+			while (drawWidth > 0) {
+				auto v = static_cast<int8_t>(*src++);
+				*dst++ = v;
+				if (v > 0) {
+					BlitPixelsWithMap(dst, src, v, tbl);
+					src += v;
+					dst += v;
+				} else {
+					v = static_cast<int8_t>(-v);
+				}
+				drawWidth -= v;
+			}
 		}
+		break;
+	case TileType::LeftTriangle:
+	case TileType::RightTriangle:
+		BlitPixelsWithMap(dst, src, 544, tbl);
+		break;
+	case TileType::LeftTrapezoid:
+	case TileType::RightTrapezoid:
+		BlitPixelsWithMap(dst, src, 800, tbl);
+		break;
 	}
 }
 
diff --git a/Source/engine/render/dun_render.hpp b/Source/engine/render/dun_render.hpp
index 684c83220949..43545539b342 100644
--- a/Source/engine/render/dun_render.hpp
+++ b/Source/engine/render/dun_render.hpp
@@ -7,11 +7,10 @@
 
 #include <cstdint>
 
-#include <SDL_endian.h>
-
 #include "engine/point.hpp"
 #include "engine/surface.hpp"
 #include "levels/dun_tile.hpp"
+#include "lighting.h"
 
 // #define DUN_RENDER_STATS
 #ifdef DUN_RENDER_STATS
@@ -175,11 +174,37 @@ void RenderTile(const Surface &out, Point position,
     LevelCelBlock levelCelBlock, MaskType maskType, const uint8_t *tbl);
 
 /**
- * @brief Render a black 64x31 tile ◆
+ * @brief Render a single color 64x31 tile ◆
  * @param out Target buffer
  * @param sx Target buffer coordinate (left corner of the tile)
  * @param sy Target buffer coordinate (bottom corner of the tile)
+ * @param color Color index
+ */
+void RenderSingleColorTile(const Surface &out, int sx, int sy, uint8_t color = 0);
+
+inline bool IsFullyDark(const uint8_t *DVL_RESTRICT tbl)
+{
+	return tbl == FullyDarkLightTable;
+}
+
+inline bool IsFullyLit(const uint8_t *DVL_RESTRICT tbl)
+{
+	return tbl == FullyLitLightTable;
+}
+
+/**
+ * @brief Renders a tile without masking.
+ */
+void RenderOpaqueTile(const Surface &out, Point position, LevelCelBlock levelCelBlock, const uint8_t *tbl);
+
+/**
+ * @brief Renders a tile without masking and without lighting.
+ */
+void RenderFullyLitOpaqueTile(TileType tile, const Surface &out, Point position, const uint8_t *DVL_RESTRICT src);
+
+/**
+ * @brief Writes a tile with the color swaps from `tbl` to `dst`.
  */
-void world_draw_black_tile(const Surface &out, int sx, int sy);
+void DunTileApplyTrans(LevelCelBlock levelCelBlock, uint8_t *DVL_RESTRICT dst, const uint8_t *tbl);
 
 } // namespace devilution
diff --git a/Source/engine/render/scrollrt.cpp b/Source/engine/render/scrollrt.cpp
index 32680101db96..2405c7cb347c 100644
--- a/Source/engine/render/scrollrt.cpp
+++ b/Source/engine/render/scrollrt.cpp
@@ -5,6 +5,8 @@
  */
 #include "engine/render/scrollrt.h"
 
+#include <algorithm>
+#include <array>
 #include <cmath>
 #include <cstdint>
 
@@ -19,6 +21,7 @@
 #include "doom.h"
 #include "engine/backbuffer_state.hpp"
 #include "engine/dx.h"
+#include "engine/point.hpp"
 #include "engine/render/clx_render.hpp"
 #include "engine/render/dun_render.hpp"
 #include "engine/render/text_render.hpp"
@@ -29,6 +32,7 @@
 #include "hwcursor.hpp"
 #include "init.h"
 #include "inv.h"
+#include "levels/dun_tile.hpp"
 #include "lighting.h"
 #include "lua/lua.hpp"
 #include "minitext.h"
@@ -48,9 +52,7 @@
 #include "stores.h"
 #include "towners.h"
 #include "utils/attributes.h"
-#include "utils/bitset2d.hpp"
 #include "utils/display.h"
-#include "utils/endian.hpp"
 #include "utils/log.hpp"
 #include "utils/str_cat.hpp"
 
@@ -543,59 +545,26 @@ void DrawCell(const Surface &out, Point tilePosition, Point targetBufferPosition
 	}
 
 	for (uint_fast8_t i = 2, n = MicroTileLen; i < n; i += 2) {
-		{
-			const LevelCelBlock levelCelBlock { pMap->mt[i] };
-			if (levelCelBlock.hasValue()) {
-				RenderTile(out, targetBufferPosition,
-				    levelCelBlock,
-				    transparency ? MaskType::Transparent : MaskType::Solid, tbl);
+		if (const LevelCelBlock levelCelBlock { pMap->mt[i] }; levelCelBlock.hasValue()) {
+			if (transparency) {
+				RenderTile(out, targetBufferPosition, levelCelBlock, MaskType::Transparent, tbl);
+			} else {
+				RenderOpaqueTile(out, targetBufferPosition, levelCelBlock, tbl);
 			}
 		}
-		{
-			const LevelCelBlock levelCelBlock { pMap->mt[i + 1] };
-			if (levelCelBlock.hasValue()) {
+		if (const LevelCelBlock levelCelBlock { pMap->mt[i + 1] }; levelCelBlock.hasValue()) {
+			if (transparency) {
 				RenderTile(out, targetBufferPosition + Displacement { TILE_WIDTH / 2, 0 },
-				    levelCelBlock,
-				    transparency ? MaskType::Transparent : MaskType::Solid, tbl);
+				    levelCelBlock, MaskType::Transparent, tbl);
+			} else {
+				RenderOpaqueTile(out, targetBufferPosition + Displacement { TILE_WIDTH / 2, 0 },
+				    levelCelBlock, tbl);
 			}
 		}
 		targetBufferPosition.y -= TILE_HEIGHT;
 	}
 }
 
-/**
- * @brief Render a floor tile.
- * @param out Target buffer
- * @param tilePosition dPiece coordinates
- * @param targetBufferPosition Target buffer coordinate
- */
-void DrawFloorTile(const Surface &out, Point tilePosition, Point targetBufferPosition)
-{
-	const int lightTableIndex = dLight[tilePosition.x][tilePosition.y];
-
-	const uint8_t *tbl = LightTables[lightTableIndex].data();
-#ifdef _DEBUG
-	if (DebugPath && MyPlayer->IsPositionInPath(tilePosition))
-		tbl = GetPauseTRN();
-#endif
-
-	const uint16_t levelPieceId = dPiece[tilePosition.x][tilePosition.y];
-	{
-		const LevelCelBlock levelCelBlock { DPieceMicros[levelPieceId].mt[0] };
-		if (levelCelBlock.hasValue()) {
-			RenderTile(out, targetBufferPosition,
-			    levelCelBlock, MaskType::Solid, tbl);
-		}
-	}
-	{
-		const LevelCelBlock levelCelBlock { DPieceMicros[levelPieceId].mt[1] };
-		if (levelCelBlock.hasValue()) {
-			RenderTile(out, targetBufferPosition + Displacement { TILE_WIDTH / 2, 0 },
-			    levelCelBlock, MaskType::Solid, tbl);
-		}
-	}
-}
-
 /**
  * @brief Draw item for a given tile
  * @param out Output buffer
@@ -823,8 +792,73 @@ void DrawDungeon(const Surface &out, Point tilePosition, Point targetBufferPosit
 	}
 }
 
+constexpr int MinFloorTileToBakeLight = 2;
+constexpr size_t FloorTilesBufferSize = 1024;
+struct FloorTilesBufferEntry {
+	PointOf<int16_t> targetBufferPosition;
+	uint32_t id;
+
+	FloorTilesBufferEntry(PointOf<int16_t> position,
+	    uint16_t levelCelBlock,
+	    uint8_t lightTableIndex)
+	    : targetBufferPosition(position)
+	    , id((levelCelBlock << 8) | lightTableIndex)
+	{
+	}
+
+	[[nodiscard]] LevelCelBlock levelCelBlock() const { return { static_cast<uint16_t>(id >> 8) }; }
+	[[nodiscard]] uint8_t lightTableIndex() const { return static_cast<uint8_t>(id); }
+};
+
+void DrawIdenticalFloorTiles(const Surface &out, FloorTilesBufferEntry *begin, FloorTilesBufferEntry *end)
+{
+	if (begin == end) return;
+	const LevelCelBlock levelCelBlock = begin->levelCelBlock();
+	const uint8_t lightTableIndex = begin->lightTableIndex();
+	const uint8_t *lightTable =
+#ifdef _DEBUG
+	    lightTableIndex == NumLightingLevels + 1
+	    ? GetPauseTRN()
+	    :
+#endif
+	    LightTables[lightTableIndex].data();
+	if (end - begin < MinFloorTileToBakeLight || IsFullyDark(lightTable) || IsFullyLit(lightTable)) {
+		for (FloorTilesBufferEntry *it = begin; it != end; ++it) {
+			RenderOpaqueTile(out, it->targetBufferPosition, levelCelBlock, lightTable);
+		}
+	} else {
+		uint8_t bakedLightTile[DunFrameHeight * DunFrameWidth];
+		DunTileApplyTrans(levelCelBlock, bakedLightTile, lightTable);
+		const TileType type = levelCelBlock.type();
+		for (FloorTilesBufferEntry *it = begin; it != end; ++it) {
+			RenderFullyLitOpaqueTile(type, out, it->targetBufferPosition, bakedLightTile);
+		}
+	}
+}
+
+void DrawFloorBuffer(const Surface &out,
+    StaticVector<FloorTilesBufferEntry, FloorTilesBufferSize> &buffer)
+{
+	if (buffer.empty()) return;
+	std::stable_sort(buffer.begin(), buffer.end(), [](const FloorTilesBufferEntry &a, const FloorTilesBufferEntry &b) {
+		return a.id < b.id;
+	});
+	uint32_t prevId = buffer[0].id;
+	size_t prevBegin = 0;
+	for (size_t i = 1; i < buffer.size(); ++i) {
+		const uint32_t id = buffer[i].id;
+		if (prevId != id) {
+			DrawIdenticalFloorTiles(out, buffer.begin() + prevBegin, buffer.begin() + i);
+			prevId = id;
+			prevBegin = i;
+		}
+	}
+	DrawIdenticalFloorTiles(out, buffer.begin() + prevBegin, buffer.end());
+	buffer.clear();
+}
+
 /**
- * @brief Render a row of tiles
+ * @brief Renders the floor tiles
  * @param out Buffer to render to
  * @param tilePosition dPiece coordinates
  * @param targetBufferPosition Target buffer coordinates
@@ -833,33 +867,50 @@ void DrawDungeon(const Surface &out, Point tilePosition, Point targetBufferPosit
  */
 void DrawFloor(const Surface &out, Point tilePosition, Point targetBufferPosition, int rows, int columns)
 {
+	StaticVector<FloorTilesBufferEntry, FloorTilesBufferSize> buffer;
+	PointOf<int16_t> position = targetBufferPosition;
 	for (int i = 0; i < rows; i++) {
-		for (int j = 0; j < columns; j++) {
-			if (InDungeonBounds(tilePosition)) {
-				if (!TileHasAny(tilePosition, TileProperties::Solid))
-					DrawFloorTile(out, tilePosition, targetBufferPosition);
-			} else {
-				world_draw_black_tile(out, targetBufferPosition.x, targetBufferPosition.y);
+		for (int j = 0; j < columns; ++j) {
+			if (!InDungeonBounds(tilePosition)) {
+				RenderSingleColorTile(out, position.x, position.y);
+			} else if (!TileHasAny(tilePosition, TileProperties::Solid)) {
+				const uint16_t levelPieceId = dPiece[tilePosition.x][tilePosition.y];
+				const uint8_t lightTableIndex =
+#ifdef _DEBUG
+				    DebugPath && MyPlayer->IsPositionInPath(tilePosition)
+				    ? NumLightingLevels + 1
+				    :
+#endif
+				    dLight[tilePosition.x][tilePosition.y];
+				if (buffer.size() + 2 >= FloorTilesBufferSize) DrawFloorBuffer(out, buffer);
+				if (const uint16_t pieceId = DPieceMicros[levelPieceId].mt[0].data; pieceId != 0) {
+					buffer.emplace_back(position, pieceId, lightTableIndex);
+				}
+				if (const uint16_t pieceId = DPieceMicros[levelPieceId].mt[1].data; pieceId != 0) {
+					buffer.emplace_back(position + Displacement { TILE_WIDTH / 2, 0 }, pieceId, lightTableIndex);
+				}
 			}
 			tilePosition += Direction::East;
-			targetBufferPosition.x += TILE_WIDTH;
+			position.x += TILE_WIDTH;
 		}
+
 		// Return to start of row
 		tilePosition += Displacement(Direction::West) * columns;
-		targetBufferPosition.x -= columns * TILE_WIDTH;
+		position.x -= columns * TILE_WIDTH;
 
 		// Jump to next row
-		targetBufferPosition.y += TILE_HEIGHT / 2;
+		position.y += TILE_HEIGHT / 2;
 		if ((i & 1) != 0) {
 			tilePosition.x++;
 			columns--;
-			targetBufferPosition.x += TILE_WIDTH / 2;
+			position.x += TILE_WIDTH / 2;
 		} else {
 			tilePosition.y++;
 			columns++;
-			targetBufferPosition.x -= TILE_WIDTH / 2;
+			position.x -= TILE_WIDTH / 2;
 		}
 	}
+	DrawFloorBuffer(out, buffer);
 }
 
 [[nodiscard]] DVL_ALWAYS_INLINE bool IsWall(Point position)
@@ -987,7 +1038,7 @@ void Zoom(const Surface &out)
 
 Displacement tileOffset;
 Displacement tileShift;
-int tileColums;
+int tileColumns;
 int tileRows;
 
 void CalcFirstTilePosition(Point &position, Displacement &offset)
@@ -1048,7 +1099,7 @@ void DrawGame(const Surface &fullOut, Point position, Displacement offset)
 	    ? fullOut.subregionY(0, gnViewportHeight)
 	    : fullOut.subregionY(0, (gnViewportHeight + 1) / 2);
 
-	int columns = tileColums;
+	int columns = tileColumns;
 	int rows = tileRows;
 
 	// Skip rendering parts covered by the panels
@@ -1511,7 +1562,7 @@ void CalcViewportGeometry()
 	const int viewportHeight = GetViewportHeight() / zoomFactor;
 	const Point renderStart = startPosition - Displacement { TILE_WIDTH / 2, TILE_HEIGHT / 2 };
 	tileRows = (viewportHeight - renderStart.y + TILE_HEIGHT / 2 - 1) / (TILE_HEIGHT / 2);
-	tileColums = (screenWidth - renderStart.x + TILE_WIDTH - 1) / TILE_WIDTH;
+	tileColumns = (screenWidth - renderStart.x + TILE_WIDTH - 1) / TILE_WIDTH;
 }
 
 Point GetScreenPosition(Point tile)
diff --git a/Source/utils/attributes.h b/Source/utils/attributes.h
index 2f40a9bcb6e6..d91b05a6c8ae 100644
--- a/Source/utils/attributes.h
+++ b/Source/utils/attributes.h
@@ -102,3 +102,9 @@
 #else
 #define DVL_UNREACHABLE()
 #endif
+
+#if __cpp_lib_execution >= 201902L
+#define DVL_EXECUTION_UNSEQ std::execution::unseq,
+#else
+#define DVL_EXECUTION_UNSEQ
+#endif