diff --git a/src/polyrenderer/drawers/poly_triangle.cpp b/src/polyrenderer/drawers/poly_triangle.cpp index a28945715..e4cd81dac 100644 --- a/src/polyrenderer/drawers/poly_triangle.cpp +++ b/src/polyrenderer/drawers/poly_triangle.cpp @@ -34,6 +34,7 @@ #include "v_palette.h" #include "r_data/colormaps.h" #include "poly_triangle.h" +#include "polyrenderer/poly_renderer.h" #include "swrenderer/drawers/r_draw_rgba.h" #include "screen_triangle.h" @@ -81,7 +82,7 @@ void PolyTriangleDrawer::toggle_mirror() void PolyTriangleDrawer::draw(const PolyDrawArgs &args) { - DrawerCommandQueue::QueueCommand(args, mirror); + PolyRenderer::Instance()->Thread.DrawQueue->Push(args, mirror); } void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadData *thread) diff --git a/src/polyrenderer/poly_renderer.cpp b/src/polyrenderer/poly_renderer.cpp index 1de84530d..5c00ef4fb 100644 --- a/src/polyrenderer/poly_renderer.cpp +++ b/src/polyrenderer/poly_renderer.cpp @@ -50,6 +50,10 @@ PolyRenderer *PolyRenderer::Instance() return &scene; } +PolyRenderer::PolyRenderer() +{ +} + void PolyRenderer::RenderView(player_t *player) { using namespace swrenderer; @@ -71,10 +75,10 @@ void PolyRenderer::RenderView(player_t *player) CameraLight *cameraLight = CameraLight::Instance(); if (cameraLight->ShaderColormap() && viewport->RenderTarget->IsBgra() && !(r_shadercolormaps && screen->Accel2D)) { - R_BeginDrawerCommands(); - DrawerCommandQueue::QueueCommand(cameraLight->ShaderColormap(), screen); - R_EndDrawerCommands(); + Thread.DrawQueue->Push(cameraLight->ShaderColormap(), screen); } + + DrawerThreads::Execute({ Thread.DrawQueue }); } void PolyRenderer::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines) @@ -94,6 +98,7 @@ void PolyRenderer::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int canvas->Lock(true); RenderActorView(actor, dontmaplines); + DrawerThreads::Execute({ Thread.DrawQueue }); canvas->Unlock(); @@ -122,8 +127,6 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines) if (!r_showviewer) camera->renderflags |= RF_INVISIBLE; - R_BeginDrawerCommands(); - ClearBuffers(); SetSceneViewport(); SetupPerspectiveMatrix(); @@ -137,10 +140,6 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines) interpolator.RestoreInterpolations (); NetUpdate(); - - R_EndDrawerCommands(); - - NetUpdate(); } void PolyRenderer::RenderRemainingPlayerSprites() diff --git a/src/polyrenderer/poly_renderer.h b/src/polyrenderer/poly_renderer.h index 75e192e9c..565eec004 100644 --- a/src/polyrenderer/poly_renderer.h +++ b/src/polyrenderer/poly_renderer.h @@ -31,13 +31,18 @@ #include "scene/poly_portal.h" #include "scene/poly_playersprite.h" #include "scene/poly_sky.h" +#include "swrenderer/r_renderthread.h" class AActor; class DCanvas; +class DrawerCommandQueue; +typedef std::shared_ptr DrawerCommandQueuePtr; class PolyRenderer { public: + PolyRenderer(); + void RenderView(player_t *player); void RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines); void RenderRemainingPlayerSprites(); @@ -50,6 +55,8 @@ public: bool InsertSeenMirror(line_t *mirrorLine); bool DontMapLines = false; + + swrenderer::RenderThread Thread; private: void RenderActorView(AActor *actor, bool dontmaplines); diff --git a/src/swrenderer/drawers/r_draw.h b/src/swrenderer/drawers/r_draw.h index e813acaae..48185728b 100644 --- a/src/swrenderer/drawers/r_draw.h +++ b/src/swrenderer/drawers/r_draw.h @@ -17,6 +17,9 @@ EXTERN_CVAR(Bool, r_drawtrans); EXTERN_CVAR(Float, transsouls); EXTERN_CVAR(Bool, r_dynlights); +class DrawerCommandQueue; +typedef std::shared_ptr DrawerCommandQueuePtr; + namespace swrenderer { class DrawerArgs; @@ -46,6 +49,7 @@ namespace swrenderer class SWPixelFormatDrawers { public: + SWPixelFormatDrawers(DrawerCommandQueuePtr queue) : Queue(queue) { } virtual ~SWPixelFormatDrawers() { } virtual void DrawWallColumn(const WallDrawerArgs &args) = 0; virtual void DrawWallMaskedColumn(const WallDrawerArgs &args) = 0; @@ -82,6 +86,8 @@ namespace swrenderer 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; + + DrawerCommandQueuePtr Queue; }; void R_InitShadeMaps(); diff --git a/src/swrenderer/drawers/r_draw_pal.h b/src/swrenderer/drawers/r_draw_pal.h index cf955c607..efc6d6a17 100644 --- a/src/swrenderer/drawers/r_draw_pal.h +++ b/src/swrenderer/drawers/r_draw_pal.h @@ -244,53 +244,55 @@ namespace swrenderer class SWPalDrawers : public SWPixelFormatDrawers { public: - void DrawWallColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawWallMaskedColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } + using SWPixelFormatDrawers::SWPixelFormatDrawers; + + void DrawWallColumn(const WallDrawerArgs &args) override { Queue->Push(args); } + void DrawWallMaskedColumn(const WallDrawerArgs &args) override { Queue->Push(args); } void DrawWallAddColumn(const WallDrawerArgs &args) override { if (args.dc_num_lights == 0) - DrawerCommandQueue::QueueCommand(args); + Queue->Push(args); else - DrawerCommandQueue::QueueCommand(args); + Queue->Push(args); } - void DrawWallAddClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawWallSubClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawWallRevSubClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSingleSkyColumn(const SkyDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void FillColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void FillAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void FillAddClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void FillSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawFuzzColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); R_UpdateFuzzPos(args); } - void DrawAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawShadedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawAddClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSpan(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSpanMasked(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSpanTranslucent(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSpanAddClamp(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void FillSpan(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } + void DrawWallAddClampColumn(const WallDrawerArgs &args) override { Queue->Push(args); } + void DrawWallSubClampColumn(const WallDrawerArgs &args) override { Queue->Push(args); } + void DrawWallRevSubClampColumn(const WallDrawerArgs &args) override { Queue->Push(args); } + void DrawSingleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push(args); } + void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push(args); } + void DrawColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void FillColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void FillAddColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void FillAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void FillSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawFuzzColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); R_UpdateFuzzPos(args); } + void DrawAddColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawShadedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawSpan(const SpanDrawerArgs &args) override { Queue->Push(args); } + void DrawSpanMasked(const SpanDrawerArgs &args) override { Queue->Push(args); } + void DrawSpanTranslucent(const SpanDrawerArgs &args) override { Queue->Push(args); } + void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override { Queue->Push(args); } + void DrawSpanAddClamp(const SpanDrawerArgs &args) override { Queue->Push(args); } + void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override { Queue->Push(args); } + void FillSpan(const SpanDrawerArgs &args) override { Queue->Push(args); } 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(args, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy, basecolormap); + Queue->Push(args, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy, basecolormap); } - void DrawColoredSpan(const SpanDrawerArgs &args, int y, int x1, int x2) override { DrawerCommandQueue::QueueCommand(args, y, x1, x2); } - void DrawFogBoundaryLine(const SpanDrawerArgs &args, int y, int x1, int x2) override { DrawerCommandQueue::QueueCommand(args, y, x1, x2); } + void DrawColoredSpan(const SpanDrawerArgs &args, int y, int x1, int x2) override { Queue->Push(args, y, x1, x2); } + void DrawFogBoundaryLine(const SpanDrawerArgs &args, int y, int x1, int x2) override { Queue->Push(args, y, x1, x2); } }; } diff --git a/src/swrenderer/drawers/r_draw_rgba.h b/src/swrenderer/drawers/r_draw_rgba.h index 6ba67f5c1..8f3106649 100644 --- a/src/swrenderer/drawers/r_draw_rgba.h +++ b/src/swrenderer/drawers/r_draw_rgba.h @@ -357,46 +357,48 @@ namespace swrenderer class SWTruecolorDrawers : public SWPixelFormatDrawers { public: - void DrawWallColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawWallMaskedColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawWallAddColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawWallAddClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawWallSubClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawWallRevSubClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSingleSkyColumn(const SkyDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void FillColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void FillAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void FillAddClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void FillSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawFuzzColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); R_UpdateFuzzPos(args); } - void DrawAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawShadedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawAddClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSpan(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSpanMasked(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSpanTranslucent(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSpanAddClamp(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } - void FillSpan(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand(args); } + using SWPixelFormatDrawers::SWPixelFormatDrawers; + + void DrawWallColumn(const WallDrawerArgs &args) override { Queue->Push(args); } + void DrawWallMaskedColumn(const WallDrawerArgs &args) override { Queue->Push(args); } + void DrawWallAddColumn(const WallDrawerArgs &args) override { Queue->Push(args); } + void DrawWallAddClampColumn(const WallDrawerArgs &args) override { Queue->Push(args); } + void DrawWallSubClampColumn(const WallDrawerArgs &args) override { Queue->Push(args); } + void DrawWallRevSubClampColumn(const WallDrawerArgs &args) override { Queue->Push(args); } + void DrawSingleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push(args); } + void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push(args); } + void DrawColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void FillColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void FillAddColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void FillAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void FillSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawFuzzColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); R_UpdateFuzzPos(args); } + void DrawAddColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawShadedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawSpan(const SpanDrawerArgs &args) override { Queue->Push(args); } + void DrawSpanMasked(const SpanDrawerArgs &args) override { Queue->Push(args); } + void DrawSpanTranslucent(const SpanDrawerArgs &args) override { Queue->Push(args); } + void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override { Queue->Push(args); } + void DrawSpanAddClamp(const SpanDrawerArgs &args) override { Queue->Push(args); } + void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override { Queue->Push(args); } + void FillSpan(const SpanDrawerArgs &args) override { Queue->Push(args); } 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(args, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy); + Queue->Push(args, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy); } - void DrawColoredSpan(const SpanDrawerArgs &args, int y, int x1, int x2) override { DrawerCommandQueue::QueueCommand(args, y, x1, x2); } - void DrawFogBoundaryLine(const SpanDrawerArgs &args, int y, int x1, int x2) override { DrawerCommandQueue::QueueCommand(args, y, x1, x2); } + void DrawColoredSpan(const SpanDrawerArgs &args, int y, int x1, int x2) override { Queue->Push(args, y, x1, x2); } + void DrawFogBoundaryLine(const SpanDrawerArgs &args, int y, int x1, int x2) override { Queue->Push(args, y, x1, x2); } }; ///////////////////////////////////////////////////////////////////////////// diff --git a/src/swrenderer/drawers/r_thread.cpp b/src/swrenderer/drawers/r_thread.cpp index c35d59777..367783b56 100644 --- a/src/swrenderer/drawers/r_thread.cpp +++ b/src/swrenderer/drawers/r_thread.cpp @@ -31,80 +31,42 @@ #include "g_game.h" #include "g_level.h" #include "r_thread.h" +#include "swrenderer/r_memory.h" +#include "swrenderer/r_renderthread.h" CVAR(Bool, r_multithreaded, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); -void R_BeginDrawerCommands() -{ - DrawerCommandQueue::Begin(); -} - -void R_EndDrawerCommands() -{ - DrawerCommandQueue::End(); -} - ///////////////////////////////////////////////////////////////////////////// -DrawerCommandQueue *DrawerCommandQueue::Instance() +DrawerThreads *DrawerThreads::Instance() { - static DrawerCommandQueue queue; - return &queue; + static DrawerThreads threads; + return &threads; } -DrawerCommandQueue::DrawerCommandQueue() +DrawerThreads::DrawerThreads() { } -DrawerCommandQueue::~DrawerCommandQueue() +DrawerThreads::~DrawerThreads() { StopThreads(); } -void* DrawerCommandQueue::AllocMemory(size_t size) +void DrawerThreads::Execute(const std::vector &queues) { - // Make sure allocations remain 16-byte aligned - size = (size + 15) / 16 * 16; - - auto queue = Instance(); - if (queue->memorypool_pos + size > memorypool_size) - return nullptr; - - void *data = queue->memorypool + queue->memorypool_pos; - queue->memorypool_pos += size; - return data; -} - -void DrawerCommandQueue::Begin() -{ - auto queue = Instance(); - queue->Finish(); - queue->threaded_render++; -} - -void DrawerCommandQueue::End() -{ - auto queue = Instance(); - queue->Finish(); - if (queue->threaded_render > 0) - queue->threaded_render--; -} - -void DrawerCommandQueue::WaitForWorkers() -{ - Instance()->Finish(); -} - -void DrawerCommandQueue::Finish() -{ - auto queue = Instance(); - if (queue->commands.empty()) + bool hasWork = false; + for (const auto &queue : queues) + hasWork = hasWork || !queue->commands.empty(); + if (!hasWork) return; + + auto queue = Instance(); // Give worker threads something to do: std::unique_lock start_lock(queue->start_mutex); - queue->active_commands.swap(queue->commands); + queue->active_commands = queues; queue->run_id++; start_lock.unlock(); @@ -119,13 +81,15 @@ void DrawerCommandQueue::Finish() struct TryCatchData { - DrawerCommandQueue *queue; + DrawerThreads *queue; DrawerThread *thread; + size_t list_index; size_t command_index; } data; data.queue = queue; data.thread = &thread; + data.list_index = 0; data.command_index = 0; VectoredTryCatch(&data, [](void *data) @@ -139,18 +103,22 @@ void DrawerCommandQueue::Finish() if (pass + 1 == d->queue->num_passes) d->thread->pass_end_y = MAX(d->thread->pass_end_y, MAXHEIGHT); - size_t size = d->queue->active_commands.size(); - for (d->command_index = 0; d->command_index < size; d->command_index++) + for (auto &list : d->queue->active_commands) { - auto &command = d->queue->active_commands[d->command_index]; - command->Execute(d->thread); + size_t size = list->commands.size(); + for (d->command_index = 0; d->command_index < size; d->command_index++) + { + auto &command = list->commands[d->command_index]; + command->Execute(d->thread); + } + d->list_index++; } } }, [](void *data, const char *reason, bool fatal) { TryCatchData *d = (TryCatchData*)data; - ReportDrawerError(d->queue->active_commands[d->command_index], true, reason, fatal); + ReportDrawerError(d->queue->active_commands[d->list_index]->commands[d->command_index], true, reason, fatal); }); // Wait for everyone to finish: @@ -170,14 +138,17 @@ void DrawerCommandQueue::Finish() // Clean up batch: - for (auto &command : queue->active_commands) - command->~DrawerCommand(); + for (auto &list : queue->active_commands) + { + for (auto &command : list->commands) + command->~DrawerCommand(); + list->Clear(); + } queue->active_commands.clear(); - queue->memorypool_pos = 0; queue->finished_threads = 0; } -void DrawerCommandQueue::StartThreads() +void DrawerThreads::StartThreads() { if (!threads.empty()) return; @@ -190,7 +161,7 @@ void DrawerCommandQueue::StartThreads() for (int i = 0; i < num_threads - 1; i++) { - DrawerCommandQueue *queue = this; + DrawerThreads *queue = this; DrawerThread *thread = &threads[i]; thread->core = i + 1; thread->num_cores = num_threads; @@ -211,13 +182,15 @@ void DrawerCommandQueue::StartThreads() struct TryCatchData { - DrawerCommandQueue *queue; + DrawerThreads *queue; DrawerThread *thread; + size_t list_index; size_t command_index; } data; data.queue = queue; data.thread = thread; + data.list_index = 0; data.command_index = 0; VectoredTryCatch(&data, [](void *data) @@ -231,18 +204,22 @@ void DrawerCommandQueue::StartThreads() if (pass + 1 == d->queue->num_passes) d->thread->pass_end_y = MAX(d->thread->pass_end_y, MAXHEIGHT); - size_t size = d->queue->active_commands.size(); - for (d->command_index = 0; d->command_index < size; d->command_index++) + for (auto &list : d->queue->active_commands) { - auto &command = d->queue->active_commands[d->command_index]; - command->Execute(d->thread); + size_t size = list->commands.size(); + for (d->command_index = 0; d->command_index < size; d->command_index++) + { + auto &command = list->commands[d->command_index]; + command->Execute(d->thread); + } + d->list_index++; } } }, [](void *data, const char *reason, bool fatal) { TryCatchData *d = (TryCatchData*)data; - ReportDrawerError(d->queue->active_commands[d->command_index], true, reason, fatal); + ReportDrawerError(d->queue->active_commands[d->list_index]->commands[d->command_index], true, reason, fatal); }); // Notify main thread that we finished: @@ -255,7 +232,7 @@ void DrawerCommandQueue::StartThreads() } } -void DrawerCommandQueue::StopThreads() +void DrawerThreads::StopThreads() { std::unique_lock lock(start_mutex); shutdown_flag = true; @@ -268,7 +245,7 @@ void DrawerCommandQueue::StopThreads() shutdown_flag = false; } -void DrawerCommandQueue::ReportDrawerError(DrawerCommand *command, bool worker_thread, const char *reason, bool fatal) +void DrawerThreads::ReportDrawerError(DrawerCommand *command, bool worker_thread, const char *reason, bool fatal) { if (worker_thread) { @@ -298,3 +275,12 @@ void VectoredTryCatch(void *data, void(*tryBlock)(void *data), void(*catchBlock) } #endif + +DrawerCommandQueue::DrawerCommandQueue(swrenderer::RenderThread *renderthread) : renderthread(renderthread) +{ +} + +void *DrawerCommandQueue::AllocMemory(size_t size) +{ + return renderthread->FrameMemory->AllocMemory(size); +} diff --git a/src/swrenderer/drawers/r_thread.h b/src/swrenderer/drawers/r_thread.h index 8de57a32d..da24854eb 100644 --- a/src/swrenderer/drawers/r_thread.h +++ b/src/swrenderer/drawers/r_thread.h @@ -33,12 +33,6 @@ // Use multiple threads when drawing EXTERN_CVAR(Bool, r_multithreaded) -// Redirect drawer commands to worker threads -void R_BeginDrawerCommands(); - -// Wait until all drawers finished executing -void R_EndDrawerCommands(); - // Worker data for each thread executing drawer commands class DrawerThread { @@ -117,20 +111,30 @@ public: void VectoredTryCatch(void *data, void(*tryBlock)(void *data), void(*catchBlock)(void *data, const char *reason, bool fatal)); -// Manages queueing up commands and executing them on worker threads -class DrawerCommandQueue +class DrawerCommandQueue; +typedef std::shared_ptr DrawerCommandQueuePtr; + +class DrawerThreads { - enum { memorypool_size = 16 * 1024 * 1024 }; - char memorypool[memorypool_size]; - size_t memorypool_pos = 0; - - std::vector commands; +public: + // Runs the collected commands on worker threads + static void Execute(const std::vector &queues); + +private: + DrawerThreads(); + ~DrawerThreads(); + + void StartThreads(); + void StopThreads(); + static DrawerThreads *Instance(); + static void ReportDrawerError(DrawerCommand *command, bool worker_thread, const char *reason, bool fatal); + std::vector threads; std::mutex start_mutex; std::condition_variable start_condition; - std::vector active_commands; + std::vector active_commands; bool shutdown_flag = false; int run_id = 0; @@ -144,53 +148,45 @@ class DrawerCommandQueue DrawerThread single_core_thread; int num_passes = 1; int rows_in_pass = MAXHEIGHT; + + friend class DrawerCommandQueue; +}; - void StartThreads(); - void StopThreads(); - void Finish(); - - static DrawerCommandQueue *Instance(); - static void ReportDrawerError(DrawerCommand *command, bool worker_thread, const char *reason, bool fatal); - - DrawerCommandQueue(); - ~DrawerCommandQueue(); +namespace swrenderer { class RenderThread; } +class DrawerCommandQueue +{ public: - // Allocate memory valid for the duration of a command execution - static void* AllocMemory(size_t size); - + DrawerCommandQueue(swrenderer::RenderThread *renderthread); + + void Clear() { commands.clear(); } + // Queue command to be executed by drawer worker threads template - static void QueueCommand(Types &&... args) + void Push(Types &&... args) { - auto queue = Instance(); - if (queue->threaded_render == 0 || !r_multithreaded) + DrawerThreads *threads = DrawerThreads::Instance(); + if (ThreadedRender && r_multithreaded) { - T command(std::forward(args)...); - command.Execute(&Instance()->single_core_thread); + void *ptr = AllocMemory(sizeof(T)); + T *command = new (ptr)T(std::forward(args)...); + commands.push_back(command); } else { - void *ptr = AllocMemory(sizeof(T)); - if (!ptr) // Out of memory - render what we got - { - queue->Finish(); - ptr = AllocMemory(sizeof(T)); - if (!ptr) - return; - } - T *command = new (ptr)T(std::forward(args)...); - queue->commands.push_back(command); + T command(std::forward(args)...); + command.Execute(&threads->single_core_thread); } } - - // Redirects all drawing commands to worker threads until End is called - // Begin/End blocks can be nested. - static void Begin(); - - // End redirection and wait until all worker threads finished executing - static void End(); - - // Waits until all worker threads finished executing - static void WaitForWorkers(); + + bool ThreadedRender = true; + +private: + // Allocate memory valid for the duration of a command execution + void *AllocMemory(size_t size); + + std::vector commands; + swrenderer::RenderThread *renderthread; + + friend class DrawerThreads; }; diff --git a/src/swrenderer/line/r_fogboundary.cpp b/src/swrenderer/line/r_fogboundary.cpp index b75ce82ce..8bd907c70 100644 --- a/src/swrenderer/line/r_fogboundary.cpp +++ b/src/swrenderer/line/r_fogboundary.cpp @@ -45,7 +45,7 @@ namespace swrenderer { - void RenderFogBoundary::Render(int x1, int x2, short *uclip, short *dclip, int wallshade, float lightleft, float lightstep, FDynamicColormap *basecolormap) + void RenderFogBoundary::Render(RenderThread *thread, int x1, int x2, short *uclip, short *dclip, int wallshade, float lightleft, float lightstep, FDynamicColormap *basecolormap) { // This is essentially the same as R_MapVisPlane but with an extra step // to create new horizontal spans whenever the light changes enough that @@ -82,7 +82,7 @@ namespace swrenderer if (t2 < b2 && rcolormap != 0) { // Colormap 0 is always the identity map, so rendering it is // just a waste of time. - RenderSection(t2, b2, xr); + RenderSection(thread, t2, b2, xr); } if (t1 < t2) t2 = t1; if (b1 > b2) b2 = b1; @@ -102,13 +102,13 @@ namespace swrenderer while (t2 < stop) { int y = t2++; - drawerargs.DrawFogBoundaryLine(y, xr, spanend[y]); + drawerargs.DrawFogBoundaryLine(thread, y, xr, spanend[y]); } stop = MAX(b1, t2); while (b2 > stop) { int y = --b2; - drawerargs.DrawFogBoundaryLine(y, xr, spanend[y]); + drawerargs.DrawFogBoundaryLine(thread, y, xr, spanend[y]); } } else @@ -134,15 +134,15 @@ namespace swrenderer } if (t2 < b2 && rcolormap != 0) { - RenderSection(t2, b2, x1); + RenderSection(thread, t2, b2, x1); } } - void RenderFogBoundary::RenderSection(int y, int y2, int x1) + void RenderFogBoundary::RenderSection(RenderThread *thread, int y, int y2, int x1) { for (; y < y2; ++y) { - drawerargs.DrawFogBoundaryLine(y, x1, spanend[y]); + drawerargs.DrawFogBoundaryLine(thread, y, x1, spanend[y]); } } } diff --git a/src/swrenderer/line/r_fogboundary.h b/src/swrenderer/line/r_fogboundary.h index 487e77385..c7df265a4 100644 --- a/src/swrenderer/line/r_fogboundary.h +++ b/src/swrenderer/line/r_fogboundary.h @@ -17,13 +17,15 @@ namespace swrenderer { + class RenderThread; + class RenderFogBoundary { public: - void Render(int x1, int x2, short *uclip, short *dclip, int wallshade, float lightleft, float lightstep, FDynamicColormap *basecolormap); + void Render(RenderThread *thread, int x1, int x2, short *uclip, short *dclip, int wallshade, float lightleft, float lightstep, FDynamicColormap *basecolormap); private: - void RenderSection(int y, int y2, int x1); + void RenderSection(RenderThread *thread, int y, int y2, int x1); short spanend[MAXHEIGHT]; SpanDrawerArgs drawerargs; diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp index 203e02c44..85a55dc9e 100644 --- a/src/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/swrenderer/line/r_renderdrawsegment.cpp @@ -137,7 +137,7 @@ namespace swrenderer // [RH] Draw fog partition if (ds->bFogBoundary) { - renderfog.Render(x1, x2, mceilingclip, mfloorclip, wallshade, rw_light, rw_lightstep, basecolormap); + renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, wallshade, rw_light, rw_lightstep, basecolormap); if (ds->maskedtexturecol == nullptr) { goto clearfog; @@ -302,7 +302,7 @@ namespace swrenderer else sprtopscreen = viewport->CenterY - texturemid * spryscale; - columndrawerargs.DrawMaskedColumn(x, iscale, tex, maskedtexturecol[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip); + columndrawerargs.DrawMaskedColumn(Thread, x, iscale, tex, maskedtexturecol[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip); rw_light += rw_lightstep; spryscale += rw_scalestep; diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index ec7ea38f6..9a07198e5 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -251,7 +251,7 @@ namespace swrenderer drawerargs.SetCount(count); drawerargs.SetTextureVStep(sampler.uv_step); drawerargs.SetTextureVPos(sampler.uv_pos); - drawerargs.DrawColumn(); + drawerargs.DrawColumn(Thread); uint64_t step64 = sampler.uv_step; uint64_t pos64 = sampler.uv_pos; @@ -269,7 +269,7 @@ namespace swrenderer drawerargs.SetCount(count); drawerargs.SetTextureVStep(sampler.uv_step); drawerargs.SetTextureVPos(sampler.uv_pos); - drawerargs.DrawColumn(); + drawerargs.DrawColumn(Thread); uint64_t step64 = sampler.uv_step; uint64_t pos64 = sampler.uv_pos; @@ -294,7 +294,7 @@ namespace swrenderer drawerargs.SetCount(count); drawerargs.SetTextureVStep(sampler.uv_step); drawerargs.SetTextureVPos(uv_pos); - drawerargs.DrawColumn(); + drawerargs.DrawColumn(Thread); left -= count; uv_pos += sampler.uv_step * count; diff --git a/src/swrenderer/plane/r_flatplane.cpp b/src/swrenderer/plane/r_flatplane.cpp index 85e339e84..d7e493384 100644 --- a/src/swrenderer/plane/r_flatplane.cpp +++ b/src/swrenderer/plane/r_flatplane.cpp @@ -265,7 +265,7 @@ namespace swrenderer drawerargs.SetDestX1(x1); drawerargs.SetDestX2(x2); - drawerargs.DrawSpan(); + drawerargs.DrawSpan(Thread); } void RenderFlatPlane::StepColumn() @@ -319,6 +319,11 @@ namespace swrenderer float RenderFlatPlane::yslope[MAXHEIGHT]; ///////////////////////////////////////////////////////////////////////// + + RenderColoredPlane::RenderColoredPlane(RenderThread *thread) + { + Thread = thread; + } void RenderColoredPlane::Render(VisiblePlane *pl) { @@ -327,6 +332,6 @@ namespace swrenderer void RenderColoredPlane::RenderLine(int y, int x1, int x2) { - drawerargs.DrawColoredSpan(y, x1, x2); + drawerargs.DrawColoredSpan(Thread, y, x1, x2); } } diff --git a/src/swrenderer/plane/r_flatplane.h b/src/swrenderer/plane/r_flatplane.h index 72a48d334..95f24c93d 100644 --- a/src/swrenderer/plane/r_flatplane.h +++ b/src/swrenderer/plane/r_flatplane.h @@ -54,7 +54,10 @@ namespace swrenderer class RenderColoredPlane : PlaneRenderer { public: + RenderColoredPlane(RenderThread *thread); void Render(VisiblePlane *pl); + + RenderThread *Thread = nullptr; private: void RenderLine(int y, int x1, int x2) override; diff --git a/src/swrenderer/plane/r_skyplane.cpp b/src/swrenderer/plane/r_skyplane.cpp index 8eefdb708..dd1848f7a 100644 --- a/src/swrenderer/plane/r_skyplane.cpp +++ b/src/swrenderer/plane/r_skyplane.cpp @@ -209,9 +209,9 @@ namespace swrenderer drawerargs.SetSolidBottom(frontskytex->GetSkyCapColor(true)); if (!backskytex) - drawerargs.DrawSingleSkyColumn(); + drawerargs.DrawSingleSkyColumn(Thread); else - drawerargs.DrawDoubleSkyColumn(); + drawerargs.DrawDoubleSkyColumn(Thread); } void RenderSkyPlane::DrawSkyColumn(int start_x, int y1, int y2) diff --git a/src/swrenderer/plane/r_slopeplane.cpp b/src/swrenderer/plane/r_slopeplane.cpp index ccb7e6107..6be3b1a7b 100644 --- a/src/swrenderer/plane/r_slopeplane.cpp +++ b/src/swrenderer/plane/r_slopeplane.cpp @@ -192,6 +192,6 @@ namespace swrenderer void RenderSlopePlane::RenderLine(int y, int x1, int x2) { - drawerargs.DrawTiltedSpan(y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy, basecolormap); + drawerargs.DrawTiltedSpan(Thread, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy, basecolormap); } } diff --git a/src/swrenderer/r_renderthread.cpp b/src/swrenderer/r_renderthread.cpp index 096f64bf6..dd14c8902 100644 --- a/src/swrenderer/r_renderthread.cpp +++ b/src/swrenderer/r_renderthread.cpp @@ -47,6 +47,11 @@ #include "swrenderer/plane/r_visibleplanelist.h" #include "swrenderer/segments/r_drawsegment.h" #include "swrenderer/segments/r_clipsegment.h" +#include "swrenderer/drawers/r_thread.h" +#include "swrenderer/drawers/r_draw.h" +#include "swrenderer/drawers/r_draw_rgba.h" +#include "swrenderer/drawers/r_draw_pal.h" +#include "swrenderer/viewport/r_viewport.h" #include "r_memory.h" namespace swrenderer @@ -54,6 +59,7 @@ namespace swrenderer RenderThread::RenderThread() { FrameMemory = std::make_unique(); + DrawQueue = std::make_shared(this); OpaquePass = std::make_unique(this); TranslucentPass = std::make_unique(this); SpriteList = std::make_unique(); @@ -64,9 +70,19 @@ namespace swrenderer Scene = std::make_unique(this); DrawSegments = std::make_unique(this); ClipSegments = std::make_unique(); + tc_drawers = std::make_unique(DrawQueue); + pal_drawers = std::make_unique(DrawQueue); } RenderThread::~RenderThread() { } + + SWPixelFormatDrawers *RenderThread::Drawers() + { + if (RenderViewport::Instance()->RenderTarget->IsBgra()) + return tc_drawers.get(); + else + return pal_drawers.get(); + } } diff --git a/src/swrenderer/r_renderthread.h b/src/swrenderer/r_renderthread.h index 24b86e861..809fe080d 100644 --- a/src/swrenderer/r_renderthread.h +++ b/src/swrenderer/r_renderthread.h @@ -24,6 +24,9 @@ #include +class DrawerCommandQueue; +typedef std::shared_ptr DrawerCommandQueuePtr; + namespace swrenderer { class VisibleSpriteList; @@ -37,6 +40,9 @@ namespace swrenderer class DrawSegmentList; class RenderClipSegment; class RenderMemory; + class SWPixelFormatDrawers; + class SWTruecolorDrawers; + class SWPalDrawers; class RenderThread { @@ -55,5 +61,12 @@ namespace swrenderer std::unique_ptr Scene; std::unique_ptr DrawSegments; std::unique_ptr ClipSegments; + DrawerCommandQueuePtr DrawQueue; + + SWPixelFormatDrawers *Drawers(); + + private: + std::unique_ptr tc_drawers; + std::unique_ptr pal_drawers; }; } diff --git a/src/swrenderer/scene/r_scene.cpp b/src/swrenderer/scene/r_scene.cpp index 37eff0b2b..371936a69 100644 --- a/src/swrenderer/scene/r_scene.cpp +++ b/src/swrenderer/scene/r_scene.cpp @@ -93,17 +93,15 @@ namespace swrenderer } } - R_BeginDrawerCommands(); - RenderActorView(player->mo); // Apply special colormap if the target cannot do it if (CameraLight::Instance()->ShaderColormap() && viewport->RenderTarget->IsBgra() && !(r_shadercolormaps && screen->Accel2D)) { - DrawerCommandQueue::QueueCommand(CameraLight::Instance()->ShaderColormap(), screen); + Thread->DrawQueue->Push(CameraLight::Instance()->ShaderColormap(), screen); } - - R_EndDrawerCommands(); + + DrawerThreads::Execute({ Thread->DrawQueue }); } void RenderScene::RenderActorView(AActor *actor, bool dontmaplines) @@ -195,8 +193,6 @@ namespace swrenderer const bool savedviewactive = viewactive; - R_BeginDrawerCommands(); - viewwidth = width; viewport->RenderTarget = canvas; @@ -208,8 +204,8 @@ namespace swrenderer RenderActorView(actor, dontmaplines); - R_EndDrawerCommands(); - + DrawerThreads::Execute({ Thread->DrawQueue }); + viewport->RenderTarget = screen; R_ExecuteSetViewSize(); diff --git a/src/swrenderer/things/r_decal.cpp b/src/swrenderer/things/r_decal.cpp index 6e3fdb761..47a89727b 100644 --- a/src/swrenderer/things/r_decal.cpp +++ b/src/swrenderer/things/r_decal.cpp @@ -329,6 +329,6 @@ namespace swrenderer else sprtopscreen = viewport->CenterY - texturemid * spryscale; - drawerargs.DrawMaskedColumn(x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip); + drawerargs.DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip); } } diff --git a/src/swrenderer/things/r_particle.cpp b/src/swrenderer/things/r_particle.cpp index 529c57b41..9b9fbb484 100644 --- a/src/swrenderer/things/r_particle.cpp +++ b/src/swrenderer/things/r_particle.cpp @@ -247,7 +247,7 @@ namespace swrenderer if (translucentPass->ClipSpriteColumnWithPortals(x, vis)) continue; uint32_t *dest = (uint32_t*)viewport->GetDest(x, yl); - DrawerCommandQueue::QueueCommand(dest, yl, spacing, ycount, fg, alpha, fracposx); + thread->DrawQueue->Push(dest, yl, spacing, ycount, fg, alpha, fracposx); } } else @@ -257,7 +257,7 @@ namespace swrenderer if (translucentPass->ClipSpriteColumnWithPortals(x, vis)) continue; uint8_t *dest = viewport->GetDest(x, yl); - DrawerCommandQueue::QueueCommand(dest, yl, spacing, ycount, fg, alpha, fracposx); + thread->DrawQueue->Push(dest, yl, spacing, ycount, fg, alpha, fracposx); } } } diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index 3521f115f..78e9975e6 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -550,7 +550,7 @@ namespace swrenderer } } - vis.Render(); + vis.Render(Thread); } void RenderPlayerSprites::RenderRemaining() @@ -584,7 +584,7 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////// - void NoAccelPlayerSprite::Render() + void NoAccelPlayerSprite::Render(RenderThread *thread) { if (xscale == 0 || fabs(yscale) < (1.0f / 32000.0f)) { // scaled to 0; can't see @@ -627,7 +627,7 @@ namespace swrenderer fixed_t frac = startfrac; for (int x = x1; x < x2; x++) { - drawerargs.DrawMaskedColumn(x, iscale, pic, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false); + drawerargs.DrawMaskedColumn(thread, x, iscale, pic, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false); frac += xiscale; } diff --git a/src/swrenderer/things/r_playersprite.h b/src/swrenderer/things/r_playersprite.h index 0a3d8903d..09274702a 100644 --- a/src/swrenderer/things/r_playersprite.h +++ b/src/swrenderer/things/r_playersprite.h @@ -45,7 +45,7 @@ namespace swrenderer short renderflags = 0; - void Render(); + void Render(RenderThread *thread); }; class HWAccelPlayerSprite diff --git a/src/swrenderer/things/r_sprite.cpp b/src/swrenderer/things/r_sprite.cpp index 5e4a8f908..4fce83fc8 100644 --- a/src/swrenderer/things/r_sprite.cpp +++ b/src/swrenderer/things/r_sprite.cpp @@ -291,7 +291,7 @@ namespace swrenderer while (x < x2) { if (!translucentPass->ClipSpriteColumnWithPortals(x, vis)) - drawerargs.DrawMaskedColumn(x, iscale, tex, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false); + drawerargs.DrawMaskedColumn(thread, x, iscale, tex, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false); x++; frac += xiscale; } diff --git a/src/swrenderer/things/r_voxel.cpp b/src/swrenderer/things/r_voxel.cpp index 4214cdd5f..e91ae4ea8 100644 --- a/src/swrenderer/things/r_voxel.cpp +++ b/src/swrenderer/things/r_voxel.cpp @@ -292,7 +292,7 @@ namespace swrenderer voxel_pos.Y += dirY.X * x + dirY.Y * y; voxel_pos.Z += dirZ * z; - FillBox(drawerargs, voxel_pos, sprite_xscale, sprite_yscale, color, cliptop, clipbottom, false, false); + FillBox(thread, drawerargs, voxel_pos, sprite_xscale, sprite_yscale, color, cliptop, clipbottom, false, false); } } } @@ -315,7 +315,7 @@ namespace swrenderer return (kvxslab_t*)(((uint8_t*)slab) + 3 + slab->zleng); } - void RenderVoxel::FillBox(SpriteDrawerArgs &drawerargs, DVector3 origin, double extentX, double extentY, int color, short *cliptop, short *clipbottom, bool viewspace, bool pixelstretch) + void RenderVoxel::FillBox(RenderThread *thread, SpriteDrawerArgs &drawerargs, DVector3 origin, double extentX, double extentY, int color, short *cliptop, short *clipbottom, bool viewspace, bool pixelstretch) { auto viewport = RenderViewport::Instance(); @@ -345,7 +345,7 @@ namespace swrenderer drawerargs.SetDest(x, columnY1); drawerargs.SetSolidColor(color); drawerargs.SetCount(columnY2 - columnY1); - drawerargs.FillColumn(); + drawerargs.FillColumn(thread); } } } diff --git a/src/swrenderer/things/r_voxel.h b/src/swrenderer/things/r_voxel.h index 0bca0fb87..1d663d251 100644 --- a/src/swrenderer/things/r_voxel.h +++ b/src/swrenderer/things/r_voxel.h @@ -83,7 +83,7 @@ namespace swrenderer enum { DVF_OFFSCREEN = 1, DVF_SPANSONLY = 2, DVF_MIRRORED = 4 }; - static void FillBox(SpriteDrawerArgs &drawerargs, DVector3 origin, double extentX, double extentY, int color, short *cliptop, short *clipbottom, bool viewspace, bool pixelstretch); + static void FillBox(RenderThread *thread, SpriteDrawerArgs &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 699dcac52..38a26aab1 100644 --- a/src/swrenderer/things/r_wallsprite.cpp +++ b/src/swrenderer/things/r_wallsprite.cpp @@ -239,14 +239,14 @@ namespace swrenderer drawerargs.SetLight(usecolormap, light, shade); } if (!translucentPass->ClipSpriteColumnWithPortals(x, spr)) - DrawColumn(drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip); + DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip); light += lightstep; x++; } } } - void RenderWallSprite::DrawColumn(SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip) + void RenderWallSprite::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip) { auto viewport = RenderViewport::Instance(); @@ -258,6 +258,6 @@ namespace swrenderer else sprtopscreen = viewport->CenterY - texturemid * spryscale; - drawerargs.DrawMaskedColumn(x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip); + drawerargs.DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip); } } diff --git a/src/swrenderer/things/r_wallsprite.h b/src/swrenderer/things/r_wallsprite.h index 796a9a2bd..76bbdc6c0 100644 --- a/src/swrenderer/things/r_wallsprite.h +++ b/src/swrenderer/things/r_wallsprite.h @@ -30,7 +30,7 @@ namespace swrenderer void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override; private: - static void DrawColumn(SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip); + static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &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/swrenderer/viewport/r_skydrawer.cpp b/src/swrenderer/viewport/r_skydrawer.cpp index 70a64e651..74462b2fa 100644 --- a/src/swrenderer/viewport/r_skydrawer.cpp +++ b/src/swrenderer/viewport/r_skydrawer.cpp @@ -13,17 +13,18 @@ #include #include "r_skydrawer.h" +#include "swrenderer/r_renderthread.h" namespace swrenderer { - void SkyDrawerArgs::DrawSingleSkyColumn() + void SkyDrawerArgs::DrawSingleSkyColumn(RenderThread *thread) { - RenderViewport::Instance()->Drawers()->DrawSingleSkyColumn(*this); + thread->Drawers()->DrawSingleSkyColumn(*this); } - void SkyDrawerArgs::DrawDoubleSkyColumn() + void SkyDrawerArgs::DrawDoubleSkyColumn(RenderThread *thread) { - RenderViewport::Instance()->Drawers()->DrawDoubleSkyColumn(*this); + thread->Drawers()->DrawDoubleSkyColumn(*this); } void SkyDrawerArgs::SetDest(int x, int y) diff --git a/src/swrenderer/viewport/r_skydrawer.h b/src/swrenderer/viewport/r_skydrawer.h index 8321b4e04..938950968 100644 --- a/src/swrenderer/viewport/r_skydrawer.h +++ b/src/swrenderer/viewport/r_skydrawer.h @@ -9,6 +9,8 @@ struct TriLight; namespace swrenderer { + class RenderThread; + class SkyDrawerArgs : public DrawerArgs { public: @@ -38,8 +40,8 @@ namespace swrenderer int FrontTextureHeight() const { return dc_sourceheight; } int BackTextureHeight() const { return dc_sourceheight2; } - void DrawSingleSkyColumn(); - void DrawDoubleSkyColumn(); + void DrawSingleSkyColumn(RenderThread *thread); + void DrawDoubleSkyColumn(RenderThread *thread); private: uint8_t *dc_dest = nullptr; diff --git a/src/swrenderer/viewport/r_spandrawer.cpp b/src/swrenderer/viewport/r_spandrawer.cpp index 3c0acaab0..ac28c5242 100644 --- a/src/swrenderer/viewport/r_spandrawer.cpp +++ b/src/swrenderer/viewport/r_spandrawer.cpp @@ -13,6 +13,7 @@ #include #include "r_spandrawer.h" +#include "swrenderer/r_renderthread.h" namespace swrenderer { @@ -96,23 +97,23 @@ namespace swrenderer } } - void SpanDrawerArgs::DrawSpan() + void SpanDrawerArgs::DrawSpan(RenderThread *thread) { - (RenderViewport::Instance()->Drawers()->*spanfunc)(*this); + (thread->Drawers()->*spanfunc)(*this); } - 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) + void SpanDrawerArgs::DrawTiltedSpan(RenderThread *thread, 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) { - RenderViewport::Instance()->Drawers()->DrawTiltedSpan(*this, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy, basecolormap); + thread->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) + void SpanDrawerArgs::DrawFogBoundaryLine(RenderThread *thread, int y, int x1, int x2) { - RenderViewport::Instance()->Drawers()->DrawFogBoundaryLine(*this, y, x1, x2); + thread->Drawers()->DrawFogBoundaryLine(*this, y, x1, x2); } - void SpanDrawerArgs::DrawColoredSpan(int y, int x1, int x2) + void SpanDrawerArgs::DrawColoredSpan(RenderThread *thread, int y, int x1, int x2) { - RenderViewport::Instance()->Drawers()->DrawColoredSpan(*this, y, x1, x2); + thread->Drawers()->DrawColoredSpan(*this, y, x1, x2); } } diff --git a/src/swrenderer/viewport/r_spandrawer.h b/src/swrenderer/viewport/r_spandrawer.h index dcb348f20..8275cc6d5 100644 --- a/src/swrenderer/viewport/r_spandrawer.h +++ b/src/swrenderer/viewport/r_spandrawer.h @@ -9,6 +9,8 @@ struct TriLight; namespace swrenderer { + class RenderThread; + class SpanDrawerArgs : public DrawerArgs { public: @@ -26,10 +28,10 @@ namespace swrenderer void SetTextureVStep(dsfixed_t vstep) { ds_ystep = vstep; } void SetSolidColor(int colorIndex) { ds_color = colorIndex; } - void DrawSpan(); - 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); + void DrawSpan(RenderThread *thread); + void DrawTiltedSpan(RenderThread *thread, 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(RenderThread *thread, int y, int x1, int x2); + void DrawFogBoundaryLine(RenderThread *thread, int y, int x1, int x2); uint32_t *SrcBlend() const { return dc_srcblend; } uint32_t *DestBlend() const { return dc_destblend; } diff --git a/src/swrenderer/viewport/r_spritedrawer.cpp b/src/swrenderer/viewport/r_spritedrawer.cpp index e0f0ccb3f..2796f26bf 100644 --- a/src/swrenderer/viewport/r_spritedrawer.cpp +++ b/src/swrenderer/viewport/r_spritedrawer.cpp @@ -34,6 +34,7 @@ #include #include "r_spritedrawer.h" +#include "swrenderer/r_renderthread.h" namespace swrenderer { @@ -42,14 +43,14 @@ namespace swrenderer colfunc = &SWPixelFormatDrawers::DrawColumn; } - void SpriteDrawerArgs::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) + void SpriteDrawerArgs::DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked) { auto viewport = RenderViewport::Instance(); // Handle the linear filtered version in a different function to reduce chances of merge conflicts from zdoom. if (viewport->RenderTarget->IsBgra() && !drawer_needs_pal_input) // To do: add support to R_DrawColumnHoriz_rgba { - DrawMaskedColumnBgra(x, iscale, tex, col, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, unmasked); + DrawMaskedColumnBgra(thread, x, iscale, tex, col, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, unmasked); return; } @@ -115,13 +116,13 @@ namespace swrenderer else if (dc_iscale < 0) dc_count = MIN(dc_count, (dc_texturefrac - dc_iscale) / (-dc_iscale)); - (RenderViewport::Instance()->Drawers()->*colfunc)(*this); + (thread->Drawers()->*colfunc)(*this); } span++; } } - void SpriteDrawerArgs::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) + void SpriteDrawerArgs::DrawMaskedColumnBgra(RenderThread *thread, 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; @@ -230,7 +231,7 @@ namespace swrenderer double v = ((dc_yl + 0.5 - sprtopscreen) / spryscale) / tex->GetHeight(); dc_texturefrac = (uint32_t)(v * (1 << 30)); - (RenderViewport::Instance()->Drawers()->*colfunc)(*this); + (thread->Drawers()->*colfunc)(*this); } span++; } @@ -488,9 +489,9 @@ namespace swrenderer return SetStyle(style, FLOAT2FIXED(alpha), translation, color, basecolormap, shadedlightshade); } - void SpriteDrawerArgs::FillColumn() + void SpriteDrawerArgs::FillColumn(RenderThread *thread) { - RenderViewport::Instance()->Drawers()->FillColumn(*this); + thread->Drawers()->FillColumn(*this); } void SpriteDrawerArgs::SetDest(int x, int y) diff --git a/src/swrenderer/viewport/r_spritedrawer.h b/src/swrenderer/viewport/r_spritedrawer.h index 48911a179..50acc1c0e 100644 --- a/src/swrenderer/viewport/r_spritedrawer.h +++ b/src/swrenderer/viewport/r_spritedrawer.h @@ -9,6 +9,8 @@ struct TriLight; namespace swrenderer { + class RenderThread; + class SpriteDrawerArgs : public DrawerArgs { public: @@ -20,8 +22,8 @@ namespace swrenderer void SetCount(int count) { dc_count = count; } void SetSolidColor(int color) { dc_color = color; } - 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 DrawMaskedColumn(RenderThread *thread, 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(RenderThread *thread); uint8_t *Dest() const { return dc_dest; } int DestY() const { return dc_dest_y; } @@ -51,7 +53,7 @@ namespace swrenderer private: bool SetBlendFunc(int op, fixed_t fglevel, fixed_t bglevel, int flags); static fixed_t GetAlpha(int type, fixed_t alpha); - 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); + void DrawMaskedColumnBgra(RenderThread *thread, 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; diff --git a/src/swrenderer/viewport/r_viewport.cpp b/src/swrenderer/viewport/r_viewport.cpp index 5cafc6f99..e0f0e396c 100644 --- a/src/swrenderer/viewport/r_viewport.cpp +++ b/src/swrenderer/viewport/r_viewport.cpp @@ -48,22 +48,12 @@ namespace swrenderer RenderViewport::RenderViewport() { - tc_drawers = std::make_unique(); - pal_drawers = std::make_unique(); } RenderViewport::~RenderViewport() { } - SWPixelFormatDrawers *RenderViewport::Drawers() - { - if (RenderTarget->IsBgra()) - return tc_drawers.get(); - else - return pal_drawers.get(); - } - void RenderViewport::SetViewport(int fullWidth, int fullHeight, float trueratio) { int virtheight, virtwidth, virtwidth2, virtheight2; diff --git a/src/swrenderer/viewport/r_viewport.h b/src/swrenderer/viewport/r_viewport.h index a61709d61..34f00c277 100644 --- a/src/swrenderer/viewport/r_viewport.h +++ b/src/swrenderer/viewport/r_viewport.h @@ -19,10 +19,6 @@ namespace swrenderer { - class SWPixelFormatDrawers; - class SWTruecolorDrawers; - class SWPalDrawers; - class RenderViewport { public: @@ -63,15 +59,10 @@ namespace swrenderer DVector2 PointWorldToView(const DVector2 &worldPos) const; DVector2 ScaleViewToScreen(const DVector2 &scale, double viewZ, bool pixelstretch = true) const; - SWPixelFormatDrawers *Drawers(); - private: void InitTextureMapping(); void SetupBuffer(); double BaseYaspectMul = 0.0; // yaspectmul without a forced aspect ratio - - std::unique_ptr tc_drawers; - std::unique_ptr pal_drawers; }; } diff --git a/src/swrenderer/viewport/r_walldrawer.cpp b/src/swrenderer/viewport/r_walldrawer.cpp index 8672c4cf5..aaada0604 100644 --- a/src/swrenderer/viewport/r_walldrawer.cpp +++ b/src/swrenderer/viewport/r_walldrawer.cpp @@ -13,6 +13,7 @@ #include #include "r_walldrawer.h" +#include "swrenderer/r_renderthread.h" namespace swrenderer { @@ -23,9 +24,9 @@ namespace swrenderer dc_dest_y = y; } - void WallDrawerArgs::DrawColumn() + void WallDrawerArgs::DrawColumn(RenderThread *thread) { - (RenderViewport::Instance()->Drawers()->*wallfunc)(*this); + (thread->Drawers()->*wallfunc)(*this); } void WallDrawerArgs::SetStyle(bool masked, bool additive, fixed_t alpha) diff --git a/src/swrenderer/viewport/r_walldrawer.h b/src/swrenderer/viewport/r_walldrawer.h index 678463b13..68a3ea46f 100644 --- a/src/swrenderer/viewport/r_walldrawer.h +++ b/src/swrenderer/viewport/r_walldrawer.h @@ -9,6 +9,8 @@ struct TriLight; namespace swrenderer { + class RenderThread; + class WallDrawerArgs : public DrawerArgs { public: @@ -28,7 +30,7 @@ namespace swrenderer bool IsMaskedDrawer() const; - void DrawColumn(); + void DrawColumn(RenderThread *thread); uint8_t *Dest() const { return dc_dest; } int DestY() const { return dc_dest_y; } diff --git a/src/v_draw.cpp b/src/v_draw.cpp index fe345a7ab..9a1c841ce 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -47,6 +47,7 @@ #include "swrenderer/drawers/r_draw_rgba.h" #include "swrenderer/scene/r_light.h" #include "swrenderer/viewport/r_viewport.h" +#include "swrenderer/r_renderthread.h" #endif #include "r_data/r_translate.h" #include "doomstat.h" @@ -278,9 +279,11 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms) int x2_i = int(x2); fixed_t xiscale_i = FLOAT2FIXED(xiscale); + static RenderThread thread; + thread.DrawQueue->ThreadedRender = false; while (x < x2_i) { - drawerargs.DrawMaskedColumn(x, iscale, img, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, !parms.masked); + drawerargs.DrawMaskedColumn(&thread, x, iscale, img, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, !parms.masked); x++; frac += xiscale_i; } @@ -1426,6 +1429,9 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, pt1 = pt2; pt2++; if (pt2 > npoints) pt2 = 0; } while (pt1 != botpt); + + static RenderThread thread; + thread.DrawQueue->ThreadedRender = false; // Travel down the left edge and fill it in. pt1 = toppt; @@ -1472,7 +1478,7 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, drawerargs.SetTextureUPos(xs_RoundToInt(tex.X * scalex)); drawerargs.SetTextureVPos(xs_RoundToInt(tex.Y * scaley)); - drawerargs.DrawSpan(); + drawerargs.DrawSpan(&thread); #endif } x += xinc;