Split drawer command queue from drawer threads

This commit is contained in:
Magnus Norddahl 2017-02-04 12:38:05 +01:00
parent ebb8da563a
commit 6f5e720576
39 changed files with 333 additions and 300 deletions

View file

@ -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<DrawPolyTrianglesCommand>(args, mirror);
PolyRenderer::Instance()->Thread.DrawQueue->Push<DrawPolyTrianglesCommand>(args, mirror);
}
void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadData *thread)

View file

@ -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<ApplySpecialColormapRGBACommand>(cameraLight->ShaderColormap(), screen);
R_EndDrawerCommands();
Thread.DrawQueue->Push<ApplySpecialColormapRGBACommand>(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()

View file

@ -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<DrawerCommandQueue> 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();
@ -51,6 +56,8 @@ public:
bool DontMapLines = false;
swrenderer::RenderThread Thread;
private:
void RenderActorView(AActor *actor, bool dontmaplines);
void ClearBuffers();

View file

@ -17,6 +17,9 @@ EXTERN_CVAR(Bool, r_drawtrans);
EXTERN_CVAR(Float, transsouls);
EXTERN_CVAR(Bool, r_dynlights);
class DrawerCommandQueue;
typedef std::shared_ptr<DrawerCommandQueue> 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();

View file

@ -244,53 +244,55 @@ namespace swrenderer
class SWPalDrawers : public SWPixelFormatDrawers
{
public:
void DrawWallColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWall1PalCommand>(args); }
void DrawWallMaskedColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallMasked1PalCommand>(args); }
using SWPixelFormatDrawers::SWPixelFormatDrawers;
void DrawWallColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWall1PalCommand>(args); }
void DrawWallMaskedColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallMasked1PalCommand>(args); }
void DrawWallAddColumn(const WallDrawerArgs &args) override
{
if (args.dc_num_lights == 0)
DrawerCommandQueue::QueueCommand<DrawWallAdd1PalCommand>(args);
Queue->Push<DrawWallAdd1PalCommand>(args);
else
DrawerCommandQueue::QueueCommand<DrawWallAddClamp1PalCommand>(args);
Queue->Push<DrawWallAddClamp1PalCommand>(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) override { DrawerCommandQueue::QueueCommand<DrawSingleSky1PalCommand>(args); }
void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawDoubleSky1PalCommand>(args); }
void DrawColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnPalCommand>(args); }
void FillColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnPalCommand>(args); }
void FillAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddPalCommand>(args); }
void FillAddClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddClampPalCommand>(args); }
void FillSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnSubClampPalCommand>(args); }
void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnRevSubClampPalCommand>(args); }
void DrawFuzzColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawFuzzColumnPalCommand>(args); R_UpdateFuzzPos(args); }
void DrawAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddPalCommand>(args); }
void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTranslatedPalCommand>(args); }
void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTlatedAddPalCommand>(args); }
void DrawShadedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnShadedPalCommand>(args); }
void DrawAddClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampPalCommand>(args); }
void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampTranslatedPalCommand>(args); }
void DrawSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampPalCommand>(args); }
void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampTranslatedPalCommand>(args); }
void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnRevSubClampPalCommand>(args); }
void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &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 DrawWallAddClampColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallAddClamp1PalCommand>(args); }
void DrawWallSubClampColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallSubClamp1PalCommand>(args); }
void DrawWallRevSubClampColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallRevSubClamp1PalCommand>(args); }
void DrawSingleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push<DrawSingleSky1PalCommand>(args); }
void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push<DrawDoubleSky1PalCommand>(args); }
void DrawColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnPalCommand>(args); }
void FillColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnPalCommand>(args); }
void FillAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnAddPalCommand>(args); }
void FillAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnAddClampPalCommand>(args); }
void FillSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnSubClampPalCommand>(args); }
void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnRevSubClampPalCommand>(args); }
void DrawFuzzColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawFuzzColumnPalCommand>(args); R_UpdateFuzzPos(args); }
void DrawAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddPalCommand>(args); }
void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnTranslatedPalCommand>(args); }
void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnTlatedAddPalCommand>(args); }
void DrawShadedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnShadedPalCommand>(args); }
void DrawAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddClampPalCommand>(args); }
void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddClampTranslatedPalCommand>(args); }
void DrawSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnSubClampPalCommand>(args); }
void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnSubClampTranslatedPalCommand>(args); }
void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampPalCommand>(args); }
void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampTranslatedPalCommand>(args); }
void DrawSpan(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanPalCommand>(args); }
void DrawSpanMasked(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedPalCommand>(args); }
void DrawSpanTranslucent(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanTranslucentPalCommand>(args); }
void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedTranslucentPalCommand>(args); }
void DrawSpanAddClamp(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanAddClampPalCommand>(args); }
void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedAddClampPalCommand>(args); }
void FillSpan(const SpanDrawerArgs &args) override { Queue->Push<FillSpanPalCommand>(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<DrawTiltedSpanPalCommand>(args, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy, basecolormap);
Queue->Push<DrawTiltedSpanPalCommand>(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<DrawColoredSpanPalCommand>(args, y, x1, x2); }
void DrawFogBoundaryLine(const SpanDrawerArgs &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 { Queue->Push<DrawColoredSpanPalCommand>(args, y, x1, x2); }
void DrawFogBoundaryLine(const SpanDrawerArgs &args, int y, int x1, int x2) override { Queue->Push<DrawFogBoundaryLinePalCommand>(args, y, x1, x2); }
};
}

View file

@ -357,46 +357,48 @@ namespace swrenderer
class SWTruecolorDrawers : public SWPixelFormatDrawers
{
public:
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) override { DrawerCommandQueue::QueueCommand<DrawSingleSky1LLVMCommand>(args); }
void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawDoubleSky1LLVMCommand>(args); }
void DrawColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnLLVMCommand>(args); }
void FillColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnLLVMCommand>(args); }
void FillAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddLLVMCommand>(args); }
void FillAddClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddClampLLVMCommand>(args); }
void FillSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnSubClampLLVMCommand>(args); }
void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnRevSubClampLLVMCommand>(args); }
void DrawFuzzColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawFuzzColumnRGBACommand>(args); R_UpdateFuzzPos(args); }
void DrawAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddLLVMCommand>(args); }
void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTranslatedLLVMCommand>(args); }
void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTlatedAddLLVMCommand>(args); }
void DrawShadedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnShadedLLVMCommand>(args); }
void DrawAddClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampLLVMCommand>(args); }
void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampTranslatedLLVMCommand>(args); }
void DrawSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampLLVMCommand>(args); }
void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampTranslatedLLVMCommand>(args); }
void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnRevSubClampLLVMCommand>(args); }
void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &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); }
using SWPixelFormatDrawers::SWPixelFormatDrawers;
void DrawWallColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWall1LLVMCommand>(args); }
void DrawWallMaskedColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallMasked1LLVMCommand>(args); }
void DrawWallAddColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallAdd1LLVMCommand>(args); }
void DrawWallAddClampColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallAddClamp1LLVMCommand>(args); }
void DrawWallSubClampColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallSubClamp1LLVMCommand>(args); }
void DrawWallRevSubClampColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallRevSubClamp1LLVMCommand>(args); }
void DrawSingleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push<DrawSingleSky1LLVMCommand>(args); }
void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push<DrawDoubleSky1LLVMCommand>(args); }
void DrawColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnLLVMCommand>(args); }
void FillColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnLLVMCommand>(args); }
void FillAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnAddLLVMCommand>(args); }
void FillAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnAddClampLLVMCommand>(args); }
void FillSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnSubClampLLVMCommand>(args); }
void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnRevSubClampLLVMCommand>(args); }
void DrawFuzzColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawFuzzColumnRGBACommand>(args); R_UpdateFuzzPos(args); }
void DrawAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddLLVMCommand>(args); }
void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnTranslatedLLVMCommand>(args); }
void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnTlatedAddLLVMCommand>(args); }
void DrawShadedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnShadedLLVMCommand>(args); }
void DrawAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddClampLLVMCommand>(args); }
void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddClampTranslatedLLVMCommand>(args); }
void DrawSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnSubClampLLVMCommand>(args); }
void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnSubClampTranslatedLLVMCommand>(args); }
void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampLLVMCommand>(args); }
void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampTranslatedLLVMCommand>(args); }
void DrawSpan(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanLLVMCommand>(args); }
void DrawSpanMasked(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedLLVMCommand>(args); }
void DrawSpanTranslucent(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanTranslucentLLVMCommand>(args); }
void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedTranslucentLLVMCommand>(args); }
void DrawSpanAddClamp(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanAddClampLLVMCommand>(args); }
void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedAddClampLLVMCommand>(args); }
void FillSpan(const SpanDrawerArgs &args) override { Queue->Push<FillSpanRGBACommand>(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<DrawTiltedSpanRGBACommand>(args, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy);
Queue->Push<DrawTiltedSpanRGBACommand>(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<DrawColoredSpanRGBACommand>(args, y, x1, x2); }
void DrawFogBoundaryLine(const SpanDrawerArgs &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 { Queue->Push<DrawColoredSpanRGBACommand>(args, y, x1, x2); }
void DrawFogBoundaryLine(const SpanDrawerArgs &args, int y, int x1, int x2) override { Queue->Push<DrawFogBoundaryLineRGBACommand>(args, y, x1, x2); }
};
/////////////////////////////////////////////////////////////////////////////

View file

@ -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<DrawerCommandQueuePtr> &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<std::mutex> 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 (auto &list : d->queue->active_commands)
{
size_t size = list->commands.size();
for (d->command_index = 0; d->command_index < size; d->command_index++)
{
auto &command = d->queue->active_commands[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)
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 (auto &list : d->queue->active_commands)
{
size_t size = list->commands.size();
for (d->command_index = 0; d->command_index < size; d->command_index++)
{
auto &command = d->queue->active_commands[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<std::mutex> 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<uint8_t>(size);
}

View file

@ -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
{
enum { memorypool_size = 16 * 1024 * 1024 };
char memorypool[memorypool_size];
size_t memorypool_pos = 0;
class DrawerCommandQueue;
typedef std::shared_ptr<DrawerCommandQueue> DrawerCommandQueuePtr;
std::vector<DrawerCommand *> commands;
class DrawerThreads
{
public:
// Runs the collected commands on worker threads
static void Execute(const std::vector<DrawerCommandQueuePtr> &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<DrawerThread> threads;
std::mutex start_mutex;
std::condition_variable start_condition;
std::vector<DrawerCommand *> active_commands;
std::vector<DrawerCommandQueuePtr> active_commands;
bool shutdown_flag = false;
int run_id = 0;
@ -145,52 +149,44 @@ class DrawerCommandQueue
int num_passes = 1;
int rows_in_pass = MAXHEIGHT;
void StartThreads();
void StopThreads();
void Finish();
friend class DrawerCommandQueue;
};
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<typename T, typename... Types>
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<Types>(args)...);
command.Execute(&Instance()->single_core_thread);
void *ptr = AllocMemory(sizeof(T));
T *command = new (ptr)T(std::forward<Types>(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<Types>(args)...);
queue->commands.push_back(command);
T command(std::forward<Types>(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();
bool ThreadedRender = true;
// End redirection and wait until all worker threads finished executing
static void End();
private:
// Allocate memory valid for the duration of a command execution
void *AllocMemory(size_t size);
// Waits until all worker threads finished executing
static void WaitForWorkers();
std::vector<DrawerCommand *> commands;
swrenderer::RenderThread *renderthread;
friend class DrawerThreads;
};

View file

@ -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]);
}
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -265,7 +265,7 @@ namespace swrenderer
drawerargs.SetDestX1(x1);
drawerargs.SetDestX2(x2);
drawerargs.DrawSpan();
drawerargs.DrawSpan(Thread);
}
void RenderFlatPlane::StepColumn()
@ -320,6 +320,11 @@ namespace swrenderer
/////////////////////////////////////////////////////////////////////////
RenderColoredPlane::RenderColoredPlane(RenderThread *thread)
{
Thread = thread;
}
void RenderColoredPlane::Render(VisiblePlane *pl)
{
RenderLines(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);
}
}

View file

@ -54,8 +54,11 @@ 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;

View file

@ -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)

View file

@ -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);
}
}

View file

@ -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<RenderMemory>();
DrawQueue = std::make_shared<DrawerCommandQueue>(this);
OpaquePass = std::make_unique<RenderOpaquePass>(this);
TranslucentPass = std::make_unique<RenderTranslucentPass>(this);
SpriteList = std::make_unique<VisibleSpriteList>();
@ -64,9 +70,19 @@ namespace swrenderer
Scene = std::make_unique<RenderScene>(this);
DrawSegments = std::make_unique<DrawSegmentList>(this);
ClipSegments = std::make_unique<RenderClipSegment>();
tc_drawers = std::make_unique<SWTruecolorDrawers>(DrawQueue);
pal_drawers = std::make_unique<SWPalDrawers>(DrawQueue);
}
RenderThread::~RenderThread()
{
}
SWPixelFormatDrawers *RenderThread::Drawers()
{
if (RenderViewport::Instance()->RenderTarget->IsBgra())
return tc_drawers.get();
else
return pal_drawers.get();
}
}

View file

@ -24,6 +24,9 @@
#include <memory>
class DrawerCommandQueue;
typedef std::shared_ptr<DrawerCommandQueue> 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<RenderScene> Scene;
std::unique_ptr<DrawSegmentList> DrawSegments;
std::unique_ptr<RenderClipSegment> ClipSegments;
DrawerCommandQueuePtr DrawQueue;
SWPixelFormatDrawers *Drawers();
private:
std::unique_ptr<SWTruecolorDrawers> tc_drawers;
std::unique_ptr<SWPalDrawers> pal_drawers;
};
}

View file

@ -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<ApplySpecialColormapRGBACommand>(CameraLight::Instance()->ShaderColormap(), screen);
Thread->DrawQueue->Push<ApplySpecialColormapRGBACommand>(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,7 +204,7 @@ namespace swrenderer
RenderActorView(actor, dontmaplines);
R_EndDrawerCommands();
DrawerThreads::Execute({ Thread->DrawQueue });
viewport->RenderTarget = screen;

View file

@ -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);
}
}

View file

@ -247,7 +247,7 @@ namespace swrenderer
if (translucentPass->ClipSpriteColumnWithPortals(x, vis))
continue;
uint32_t *dest = (uint32_t*)viewport->GetDest(x, yl);
DrawerCommandQueue::QueueCommand<DrawParticleColumnRGBACommand>(dest, yl, spacing, ycount, fg, alpha, fracposx);
thread->DrawQueue->Push<DrawParticleColumnRGBACommand>(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<DrawParticleColumnPalCommand>(dest, yl, spacing, ycount, fg, alpha, fracposx);
thread->DrawQueue->Push<DrawParticleColumnPalCommand>(dest, yl, spacing, ycount, fg, alpha, fracposx);
}
}
}

View file

@ -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;
}

View file

@ -45,7 +45,7 @@ namespace swrenderer
short renderflags = 0;
void Render();
void Render(RenderThread *thread);
};
class HWAccelPlayerSprite

View file

@ -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;
}

View file

@ -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);
}
}
}

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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;

View file

@ -13,17 +13,18 @@
#include <stddef.h>
#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)

View file

@ -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;

View file

@ -13,6 +13,7 @@
#include <stddef.h>
#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);
}
}

View file

@ -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; }

View file

@ -34,6 +34,7 @@
#include <stddef.h>
#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)

View file

@ -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;

View file

@ -48,22 +48,12 @@ namespace swrenderer
RenderViewport::RenderViewport()
{
tc_drawers = std::make_unique<SWTruecolorDrawers>();
pal_drawers = std::make_unique<SWPalDrawers>();
}
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;

View file

@ -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<SWTruecolorDrawers> tc_drawers;
std::unique_ptr<SWPalDrawers> pal_drawers;
};
}

View file

@ -13,6 +13,7 @@
#include <stddef.h>
#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)

View file

@ -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; }

View file

@ -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;
}
@ -1427,6 +1430,9 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints,
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;
pt2 = toppt - 1; if (pt2 < 0) pt2 = npoints;
@ -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;