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 "v_palette.h"
#include "r_data/colormaps.h" #include "r_data/colormaps.h"
#include "poly_triangle.h" #include "poly_triangle.h"
#include "polyrenderer/poly_renderer.h"
#include "swrenderer/drawers/r_draw_rgba.h" #include "swrenderer/drawers/r_draw_rgba.h"
#include "screen_triangle.h" #include "screen_triangle.h"
@ -81,7 +82,7 @@ void PolyTriangleDrawer::toggle_mirror()
void PolyTriangleDrawer::draw(const PolyDrawArgs &args) 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) void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadData *thread)

View File

@ -50,6 +50,10 @@ PolyRenderer *PolyRenderer::Instance()
return &scene; return &scene;
} }
PolyRenderer::PolyRenderer()
{
}
void PolyRenderer::RenderView(player_t *player) void PolyRenderer::RenderView(player_t *player)
{ {
using namespace swrenderer; using namespace swrenderer;
@ -71,10 +75,10 @@ void PolyRenderer::RenderView(player_t *player)
CameraLight *cameraLight = CameraLight::Instance(); CameraLight *cameraLight = CameraLight::Instance();
if (cameraLight->ShaderColormap() && viewport->RenderTarget->IsBgra() && !(r_shadercolormaps && screen->Accel2D)) if (cameraLight->ShaderColormap() && viewport->RenderTarget->IsBgra() && !(r_shadercolormaps && screen->Accel2D))
{ {
R_BeginDrawerCommands(); Thread.DrawQueue->Push<ApplySpecialColormapRGBACommand>(cameraLight->ShaderColormap(), screen);
DrawerCommandQueue::QueueCommand<ApplySpecialColormapRGBACommand>(cameraLight->ShaderColormap(), screen);
R_EndDrawerCommands();
} }
DrawerThreads::Execute({ Thread.DrawQueue });
} }
void PolyRenderer::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines) 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); canvas->Lock(true);
RenderActorView(actor, dontmaplines); RenderActorView(actor, dontmaplines);
DrawerThreads::Execute({ Thread.DrawQueue });
canvas->Unlock(); canvas->Unlock();
@ -122,8 +127,6 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
if (!r_showviewer) if (!r_showviewer)
camera->renderflags |= RF_INVISIBLE; camera->renderflags |= RF_INVISIBLE;
R_BeginDrawerCommands();
ClearBuffers(); ClearBuffers();
SetSceneViewport(); SetSceneViewport();
SetupPerspectiveMatrix(); SetupPerspectiveMatrix();
@ -137,10 +140,6 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
interpolator.RestoreInterpolations (); interpolator.RestoreInterpolations ();
NetUpdate(); NetUpdate();
R_EndDrawerCommands();
NetUpdate();
} }
void PolyRenderer::RenderRemainingPlayerSprites() void PolyRenderer::RenderRemainingPlayerSprites()

View File

@ -31,13 +31,18 @@
#include "scene/poly_portal.h" #include "scene/poly_portal.h"
#include "scene/poly_playersprite.h" #include "scene/poly_playersprite.h"
#include "scene/poly_sky.h" #include "scene/poly_sky.h"
#include "swrenderer/r_renderthread.h"
class AActor; class AActor;
class DCanvas; class DCanvas;
class DrawerCommandQueue;
typedef std::shared_ptr<DrawerCommandQueue> DrawerCommandQueuePtr;
class PolyRenderer class PolyRenderer
{ {
public: public:
PolyRenderer();
void RenderView(player_t *player); void RenderView(player_t *player);
void RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines); void RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines);
void RenderRemainingPlayerSprites(); void RenderRemainingPlayerSprites();
@ -51,6 +56,8 @@ public:
bool DontMapLines = false; bool DontMapLines = false;
swrenderer::RenderThread Thread;
private: private:
void RenderActorView(AActor *actor, bool dontmaplines); void RenderActorView(AActor *actor, bool dontmaplines);
void ClearBuffers(); void ClearBuffers();

View File

@ -17,6 +17,9 @@ EXTERN_CVAR(Bool, r_drawtrans);
EXTERN_CVAR(Float, transsouls); EXTERN_CVAR(Float, transsouls);
EXTERN_CVAR(Bool, r_dynlights); EXTERN_CVAR(Bool, r_dynlights);
class DrawerCommandQueue;
typedef std::shared_ptr<DrawerCommandQueue> DrawerCommandQueuePtr;
namespace swrenderer namespace swrenderer
{ {
class DrawerArgs; class DrawerArgs;
@ -46,6 +49,7 @@ namespace swrenderer
class SWPixelFormatDrawers class SWPixelFormatDrawers
{ {
public: public:
SWPixelFormatDrawers(DrawerCommandQueuePtr queue) : Queue(queue) { }
virtual ~SWPixelFormatDrawers() { } virtual ~SWPixelFormatDrawers() { }
virtual void DrawWallColumn(const WallDrawerArgs &args) = 0; virtual void DrawWallColumn(const WallDrawerArgs &args) = 0;
virtual void DrawWallMaskedColumn(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 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 DrawColoredSpan(const SpanDrawerArgs &args, int y, int x1, int x2) = 0;
virtual void DrawFogBoundaryLine(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(); void R_InitShadeMaps();

View File

@ -244,53 +244,55 @@ namespace swrenderer
class SWPalDrawers : public SWPixelFormatDrawers class SWPalDrawers : public SWPixelFormatDrawers
{ {
public: public:
void DrawWallColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWall1PalCommand>(args); } using SWPixelFormatDrawers::SWPixelFormatDrawers;
void DrawWallMaskedColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallMasked1PalCommand>(args); }
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 void DrawWallAddColumn(const WallDrawerArgs &args) override
{ {
if (args.dc_num_lights == 0) if (args.dc_num_lights == 0)
DrawerCommandQueue::QueueCommand<DrawWallAdd1PalCommand>(args); Queue->Push<DrawWallAdd1PalCommand>(args);
else else
DrawerCommandQueue::QueueCommand<DrawWallAddClamp1PalCommand>(args); Queue->Push<DrawWallAddClamp1PalCommand>(args);
} }
void DrawWallAddClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallAddClamp1PalCommand>(args); } void DrawWallAddClampColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallAddClamp1PalCommand>(args); }
void DrawWallSubClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallSubClamp1PalCommand>(args); } void DrawWallSubClampColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallSubClamp1PalCommand>(args); }
void DrawWallRevSubClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallRevSubClamp1PalCommand>(args); } void DrawWallRevSubClampColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallRevSubClamp1PalCommand>(args); }
void DrawSingleSkyColumn(const SkyDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSingleSky1PalCommand>(args); } void DrawSingleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push<DrawSingleSky1PalCommand>(args); }
void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawDoubleSky1PalCommand>(args); } void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push<DrawDoubleSky1PalCommand>(args); }
void DrawColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnPalCommand>(args); } void DrawColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnPalCommand>(args); }
void FillColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnPalCommand>(args); } void FillColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnPalCommand>(args); }
void FillAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddPalCommand>(args); } void FillAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnAddPalCommand>(args); }
void FillAddClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddClampPalCommand>(args); } void FillAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnAddClampPalCommand>(args); }
void FillSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnSubClampPalCommand>(args); } void FillSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnSubClampPalCommand>(args); }
void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnRevSubClampPalCommand>(args); } void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnRevSubClampPalCommand>(args); }
void DrawFuzzColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawFuzzColumnPalCommand>(args); R_UpdateFuzzPos(args); } void DrawFuzzColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawFuzzColumnPalCommand>(args); R_UpdateFuzzPos(args); }
void DrawAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddPalCommand>(args); } void DrawAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddPalCommand>(args); }
void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTranslatedPalCommand>(args); } void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnTranslatedPalCommand>(args); }
void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTlatedAddPalCommand>(args); } void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnTlatedAddPalCommand>(args); }
void DrawShadedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnShadedPalCommand>(args); } void DrawShadedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnShadedPalCommand>(args); }
void DrawAddClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampPalCommand>(args); } void DrawAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddClampPalCommand>(args); }
void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampTranslatedPalCommand>(args); } void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddClampTranslatedPalCommand>(args); }
void DrawSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampPalCommand>(args); } void DrawSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnSubClampPalCommand>(args); }
void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampTranslatedPalCommand>(args); } void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnSubClampTranslatedPalCommand>(args); }
void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnRevSubClampPalCommand>(args); } void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampPalCommand>(args); }
void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnRevSubClampTranslatedPalCommand>(args); } void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampTranslatedPalCommand>(args); }
void DrawSpan(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanPalCommand>(args); } void DrawSpan(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanPalCommand>(args); }
void DrawSpanMasked(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedPalCommand>(args); } void DrawSpanMasked(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedPalCommand>(args); }
void DrawSpanTranslucent(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanTranslucentPalCommand>(args); } void DrawSpanTranslucent(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanTranslucentPalCommand>(args); }
void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedTranslucentPalCommand>(args); } void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedTranslucentPalCommand>(args); }
void DrawSpanAddClamp(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanAddClampPalCommand>(args); } void DrawSpanAddClamp(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanAddClampPalCommand>(args); }
void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedAddClampPalCommand>(args); } void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedAddClampPalCommand>(args); }
void FillSpan(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillSpanPalCommand>(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 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 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 { DrawerCommandQueue::QueueCommand<DrawFogBoundaryLinePalCommand>(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 class SWTruecolorDrawers : public SWPixelFormatDrawers
{ {
public: public:
void DrawWallColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWall1LLVMCommand>(args); } using SWPixelFormatDrawers::SWPixelFormatDrawers;
void DrawWallMaskedColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallMasked1LLVMCommand>(args); }
void DrawWallAddColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallAdd1LLVMCommand>(args); } void DrawWallColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWall1LLVMCommand>(args); }
void DrawWallAddClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallAddClamp1LLVMCommand>(args); } void DrawWallMaskedColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallMasked1LLVMCommand>(args); }
void DrawWallSubClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallSubClamp1LLVMCommand>(args); } void DrawWallAddColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallAdd1LLVMCommand>(args); }
void DrawWallRevSubClampColumn(const WallDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawWallRevSubClamp1LLVMCommand>(args); } void DrawWallAddClampColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallAddClamp1LLVMCommand>(args); }
void DrawSingleSkyColumn(const SkyDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSingleSky1LLVMCommand>(args); } void DrawWallSubClampColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallSubClamp1LLVMCommand>(args); }
void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawDoubleSky1LLVMCommand>(args); } void DrawWallRevSubClampColumn(const WallDrawerArgs &args) override { Queue->Push<DrawWallRevSubClamp1LLVMCommand>(args); }
void DrawColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnLLVMCommand>(args); } void DrawSingleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push<DrawSingleSky1LLVMCommand>(args); }
void FillColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnLLVMCommand>(args); } void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push<DrawDoubleSky1LLVMCommand>(args); }
void FillAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddLLVMCommand>(args); } void DrawColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnLLVMCommand>(args); }
void FillAddClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnAddClampLLVMCommand>(args); } void FillColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnLLVMCommand>(args); }
void FillSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnSubClampLLVMCommand>(args); } void FillAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnAddLLVMCommand>(args); }
void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillColumnRevSubClampLLVMCommand>(args); } void FillAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnAddClampLLVMCommand>(args); }
void DrawFuzzColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawFuzzColumnRGBACommand>(args); R_UpdateFuzzPos(args); } void FillSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnSubClampLLVMCommand>(args); }
void DrawAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddLLVMCommand>(args); } void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnRevSubClampLLVMCommand>(args); }
void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTranslatedLLVMCommand>(args); } void DrawFuzzColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawFuzzColumnRGBACommand>(args); R_UpdateFuzzPos(args); }
void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnTlatedAddLLVMCommand>(args); } void DrawAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddLLVMCommand>(args); }
void DrawShadedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnShadedLLVMCommand>(args); } void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnTranslatedLLVMCommand>(args); }
void DrawAddClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampLLVMCommand>(args); } void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnTlatedAddLLVMCommand>(args); }
void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnAddClampTranslatedLLVMCommand>(args); } void DrawShadedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnShadedLLVMCommand>(args); }
void DrawSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampLLVMCommand>(args); } void DrawAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddClampLLVMCommand>(args); }
void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnSubClampTranslatedLLVMCommand>(args); } void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddClampTranslatedLLVMCommand>(args); }
void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnRevSubClampLLVMCommand>(args); } void DrawSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnSubClampLLVMCommand>(args); }
void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawColumnRevSubClampTranslatedLLVMCommand>(args); } void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnSubClampTranslatedLLVMCommand>(args); }
void DrawSpan(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanLLVMCommand>(args); } void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampLLVMCommand>(args); }
void DrawSpanMasked(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedLLVMCommand>(args); } void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampTranslatedLLVMCommand>(args); }
void DrawSpanTranslucent(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanTranslucentLLVMCommand>(args); } void DrawSpan(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanLLVMCommand>(args); }
void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedTranslucentLLVMCommand>(args); } void DrawSpanMasked(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedLLVMCommand>(args); }
void DrawSpanAddClamp(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanAddClampLLVMCommand>(args); } void DrawSpanTranslucent(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanTranslucentLLVMCommand>(args); }
void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<DrawSpanMaskedAddClampLLVMCommand>(args); } void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedTranslucentLLVMCommand>(args); }
void FillSpan(const SpanDrawerArgs &args) override { DrawerCommandQueue::QueueCommand<FillSpanRGBACommand>(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 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 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 { DrawerCommandQueue::QueueCommand<DrawFogBoundaryLineRGBACommand>(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_game.h"
#include "g_level.h" #include "g_level.h"
#include "r_thread.h" #include "r_thread.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
CVAR(Bool, r_multithreaded, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); 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; static DrawerThreads threads;
return &queue; return &threads;
} }
DrawerCommandQueue::DrawerCommandQueue() DrawerThreads::DrawerThreads()
{ {
} }
DrawerCommandQueue::~DrawerCommandQueue() DrawerThreads::~DrawerThreads()
{ {
StopThreads(); StopThreads();
} }
void* DrawerCommandQueue::AllocMemory(size_t size) void DrawerThreads::Execute(const std::vector<DrawerCommandQueuePtr> &queues)
{ {
// Make sure allocations remain 16-byte aligned bool hasWork = false;
size = (size + 15) / 16 * 16; for (const auto &queue : queues)
hasWork = hasWork || !queue->commands.empty();
auto queue = Instance(); if (!hasWork)
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())
return; return;
auto queue = Instance();
// Give worker threads something to do: // Give worker threads something to do:
std::unique_lock<std::mutex> start_lock(queue->start_mutex); std::unique_lock<std::mutex> start_lock(queue->start_mutex);
queue->active_commands.swap(queue->commands); queue->active_commands = queues;
queue->run_id++; queue->run_id++;
start_lock.unlock(); start_lock.unlock();
@ -119,13 +81,15 @@ void DrawerCommandQueue::Finish()
struct TryCatchData struct TryCatchData
{ {
DrawerCommandQueue *queue; DrawerThreads *queue;
DrawerThread *thread; DrawerThread *thread;
size_t list_index;
size_t command_index; size_t command_index;
} data; } data;
data.queue = queue; data.queue = queue;
data.thread = &thread; data.thread = &thread;
data.list_index = 0;
data.command_index = 0; data.command_index = 0;
VectoredTryCatch(&data, VectoredTryCatch(&data,
[](void *data) [](void *data)
@ -139,18 +103,22 @@ void DrawerCommandQueue::Finish()
if (pass + 1 == d->queue->num_passes) if (pass + 1 == d->queue->num_passes)
d->thread->pass_end_y = MAX(d->thread->pass_end_y, MAXHEIGHT); 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++) 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); command->Execute(d->thread);
} }
d->list_index++;
}
} }
}, },
[](void *data, const char *reason, bool fatal) [](void *data, const char *reason, bool fatal)
{ {
TryCatchData *d = (TryCatchData*)data; 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: // Wait for everyone to finish:
@ -170,14 +138,17 @@ void DrawerCommandQueue::Finish()
// Clean up batch: // Clean up batch:
for (auto &command : queue->active_commands) for (auto &list : queue->active_commands)
{
for (auto &command : list->commands)
command->~DrawerCommand(); command->~DrawerCommand();
list->Clear();
}
queue->active_commands.clear(); queue->active_commands.clear();
queue->memorypool_pos = 0;
queue->finished_threads = 0; queue->finished_threads = 0;
} }
void DrawerCommandQueue::StartThreads() void DrawerThreads::StartThreads()
{ {
if (!threads.empty()) if (!threads.empty())
return; return;
@ -190,7 +161,7 @@ void DrawerCommandQueue::StartThreads()
for (int i = 0; i < num_threads - 1; i++) for (int i = 0; i < num_threads - 1; i++)
{ {
DrawerCommandQueue *queue = this; DrawerThreads *queue = this;
DrawerThread *thread = &threads[i]; DrawerThread *thread = &threads[i];
thread->core = i + 1; thread->core = i + 1;
thread->num_cores = num_threads; thread->num_cores = num_threads;
@ -211,13 +182,15 @@ void DrawerCommandQueue::StartThreads()
struct TryCatchData struct TryCatchData
{ {
DrawerCommandQueue *queue; DrawerThreads *queue;
DrawerThread *thread; DrawerThread *thread;
size_t list_index;
size_t command_index; size_t command_index;
} data; } data;
data.queue = queue; data.queue = queue;
data.thread = thread; data.thread = thread;
data.list_index = 0;
data.command_index = 0; data.command_index = 0;
VectoredTryCatch(&data, VectoredTryCatch(&data,
[](void *data) [](void *data)
@ -231,18 +204,22 @@ void DrawerCommandQueue::StartThreads()
if (pass + 1 == d->queue->num_passes) if (pass + 1 == d->queue->num_passes)
d->thread->pass_end_y = MAX(d->thread->pass_end_y, MAXHEIGHT); 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++) 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); command->Execute(d->thread);
} }
d->list_index++;
}
} }
}, },
[](void *data, const char *reason, bool fatal) [](void *data, const char *reason, bool fatal)
{ {
TryCatchData *d = (TryCatchData*)data; 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: // 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); std::unique_lock<std::mutex> lock(start_mutex);
shutdown_flag = true; shutdown_flag = true;
@ -268,7 +245,7 @@ void DrawerCommandQueue::StopThreads()
shutdown_flag = false; 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) if (worker_thread)
{ {
@ -298,3 +275,12 @@ void VectoredTryCatch(void *data, void(*tryBlock)(void *data), void(*catchBlock)
} }
#endif #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 // Use multiple threads when drawing
EXTERN_CVAR(Bool, r_multithreaded) 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 // Worker data for each thread executing drawer commands
class DrawerThread class DrawerThread
{ {
@ -117,20 +111,30 @@ public:
void VectoredTryCatch(void *data, void(*tryBlock)(void *data), void(*catchBlock)(void *data, const char *reason, bool fatal)); 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<DrawerCommandQueue> DrawerCommandQueuePtr;
{
enum { memorypool_size = 16 * 1024 * 1024 };
char memorypool[memorypool_size];
size_t memorypool_pos = 0;
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::vector<DrawerThread> threads;
std::mutex start_mutex; std::mutex start_mutex;
std::condition_variable start_condition; std::condition_variable start_condition;
std::vector<DrawerCommand *> active_commands; std::vector<DrawerCommandQueuePtr> active_commands;
bool shutdown_flag = false; bool shutdown_flag = false;
int run_id = 0; int run_id = 0;
@ -145,52 +149,44 @@ class DrawerCommandQueue
int num_passes = 1; int num_passes = 1;
int rows_in_pass = MAXHEIGHT; int rows_in_pass = MAXHEIGHT;
void StartThreads(); friend class DrawerCommandQueue;
void StopThreads(); };
void Finish();
static DrawerCommandQueue *Instance(); namespace swrenderer { class RenderThread; }
static void ReportDrawerError(DrawerCommand *command, bool worker_thread, const char *reason, bool fatal);
DrawerCommandQueue();
~DrawerCommandQueue();
class DrawerCommandQueue
{
public: public:
// Allocate memory valid for the duration of a command execution DrawerCommandQueue(swrenderer::RenderThread *renderthread);
static void* AllocMemory(size_t size);
void Clear() { commands.clear(); }
// Queue command to be executed by drawer worker threads // Queue command to be executed by drawer worker threads
template<typename T, typename... Types> template<typename T, typename... Types>
static void QueueCommand(Types &&... args) void Push(Types &&... args)
{ {
auto queue = Instance(); DrawerThreads *threads = DrawerThreads::Instance();
if (queue->threaded_render == 0 || !r_multithreaded) if (ThreadedRender && r_multithreaded)
{ {
T command(std::forward<Types>(args)...); void *ptr = AllocMemory(sizeof(T));
command.Execute(&Instance()->single_core_thread); T *command = new (ptr)T(std::forward<Types>(args)...);
commands.push_back(command);
} }
else else
{ {
void *ptr = AllocMemory(sizeof(T)); T command(std::forward<Types>(args)...);
if (!ptr) // Out of memory - render what we got command.Execute(&threads->single_core_thread);
{
queue->Finish();
ptr = AllocMemory(sizeof(T));
if (!ptr)
return;
}
T *command = new (ptr)T(std::forward<Types>(args)...);
queue->commands.push_back(command);
} }
} }
// Redirects all drawing commands to worker threads until End is called bool ThreadedRender = true;
// Begin/End blocks can be nested.
static void Begin();
// End redirection and wait until all worker threads finished executing private:
static void End(); // Allocate memory valid for the duration of a command execution
void *AllocMemory(size_t size);
// Waits until all worker threads finished executing std::vector<DrawerCommand *> commands;
static void WaitForWorkers(); swrenderer::RenderThread *renderthread;
friend class DrawerThreads;
}; };

View File

@ -45,7 +45,7 @@
namespace swrenderer 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 // This is essentially the same as R_MapVisPlane but with an extra step
// to create new horizontal spans whenever the light changes enough that // to create new horizontal spans whenever the light changes enough that
@ -82,7 +82,7 @@ namespace swrenderer
if (t2 < b2 && rcolormap != 0) if (t2 < b2 && rcolormap != 0)
{ // Colormap 0 is always the identity map, so rendering it is { // Colormap 0 is always the identity map, so rendering it is
// just a waste of time. // just a waste of time.
RenderSection(t2, b2, xr); RenderSection(thread, t2, b2, xr);
} }
if (t1 < t2) t2 = t1; if (t1 < t2) t2 = t1;
if (b1 > b2) b2 = b1; if (b1 > b2) b2 = b1;
@ -102,13 +102,13 @@ namespace swrenderer
while (t2 < stop) while (t2 < stop)
{ {
int y = t2++; int y = t2++;
drawerargs.DrawFogBoundaryLine(y, xr, spanend[y]); drawerargs.DrawFogBoundaryLine(thread, y, xr, spanend[y]);
} }
stop = MAX(b1, t2); stop = MAX(b1, t2);
while (b2 > stop) while (b2 > stop)
{ {
int y = --b2; int y = --b2;
drawerargs.DrawFogBoundaryLine(y, xr, spanend[y]); drawerargs.DrawFogBoundaryLine(thread, y, xr, spanend[y]);
} }
} }
else else
@ -134,15 +134,15 @@ namespace swrenderer
} }
if (t2 < b2 && rcolormap != 0) 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) 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 namespace swrenderer
{ {
class RenderThread;
class RenderFogBoundary class RenderFogBoundary
{ {
public: 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: private:
void RenderSection(int y, int y2, int x1); void RenderSection(RenderThread *thread, int y, int y2, int x1);
short spanend[MAXHEIGHT]; short spanend[MAXHEIGHT];
SpanDrawerArgs drawerargs; SpanDrawerArgs drawerargs;

View File

@ -137,7 +137,7 @@ namespace swrenderer
// [RH] Draw fog partition // [RH] Draw fog partition
if (ds->bFogBoundary) 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) if (ds->maskedtexturecol == nullptr)
{ {
goto clearfog; goto clearfog;
@ -302,7 +302,7 @@ namespace swrenderer
else else
sprtopscreen = viewport->CenterY - texturemid * spryscale; 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; rw_light += rw_lightstep;
spryscale += rw_scalestep; spryscale += rw_scalestep;

View File

@ -251,7 +251,7 @@ namespace swrenderer
drawerargs.SetCount(count); drawerargs.SetCount(count);
drawerargs.SetTextureVStep(sampler.uv_step); drawerargs.SetTextureVStep(sampler.uv_step);
drawerargs.SetTextureVPos(sampler.uv_pos); drawerargs.SetTextureVPos(sampler.uv_pos);
drawerargs.DrawColumn(); drawerargs.DrawColumn(Thread);
uint64_t step64 = sampler.uv_step; uint64_t step64 = sampler.uv_step;
uint64_t pos64 = sampler.uv_pos; uint64_t pos64 = sampler.uv_pos;
@ -269,7 +269,7 @@ namespace swrenderer
drawerargs.SetCount(count); drawerargs.SetCount(count);
drawerargs.SetTextureVStep(sampler.uv_step); drawerargs.SetTextureVStep(sampler.uv_step);
drawerargs.SetTextureVPos(sampler.uv_pos); drawerargs.SetTextureVPos(sampler.uv_pos);
drawerargs.DrawColumn(); drawerargs.DrawColumn(Thread);
uint64_t step64 = sampler.uv_step; uint64_t step64 = sampler.uv_step;
uint64_t pos64 = sampler.uv_pos; uint64_t pos64 = sampler.uv_pos;
@ -294,7 +294,7 @@ namespace swrenderer
drawerargs.SetCount(count); drawerargs.SetCount(count);
drawerargs.SetTextureVStep(sampler.uv_step); drawerargs.SetTextureVStep(sampler.uv_step);
drawerargs.SetTextureVPos(uv_pos); drawerargs.SetTextureVPos(uv_pos);
drawerargs.DrawColumn(); drawerargs.DrawColumn(Thread);
left -= count; left -= count;
uv_pos += sampler.uv_step * count; uv_pos += sampler.uv_step * count;

View File

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

View File

@ -209,9 +209,9 @@ namespace swrenderer
drawerargs.SetSolidBottom(frontskytex->GetSkyCapColor(true)); drawerargs.SetSolidBottom(frontskytex->GetSkyCapColor(true));
if (!backskytex) if (!backskytex)
drawerargs.DrawSingleSkyColumn(); drawerargs.DrawSingleSkyColumn(Thread);
else else
drawerargs.DrawDoubleSkyColumn(); drawerargs.DrawDoubleSkyColumn(Thread);
} }
void RenderSkyPlane::DrawSkyColumn(int start_x, int y1, int y2) 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) 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/plane/r_visibleplanelist.h"
#include "swrenderer/segments/r_drawsegment.h" #include "swrenderer/segments/r_drawsegment.h"
#include "swrenderer/segments/r_clipsegment.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" #include "r_memory.h"
namespace swrenderer namespace swrenderer
@ -54,6 +59,7 @@ namespace swrenderer
RenderThread::RenderThread() RenderThread::RenderThread()
{ {
FrameMemory = std::make_unique<RenderMemory>(); FrameMemory = std::make_unique<RenderMemory>();
DrawQueue = std::make_shared<DrawerCommandQueue>(this);
OpaquePass = std::make_unique<RenderOpaquePass>(this); OpaquePass = std::make_unique<RenderOpaquePass>(this);
TranslucentPass = std::make_unique<RenderTranslucentPass>(this); TranslucentPass = std::make_unique<RenderTranslucentPass>(this);
SpriteList = std::make_unique<VisibleSpriteList>(); SpriteList = std::make_unique<VisibleSpriteList>();
@ -64,9 +70,19 @@ namespace swrenderer
Scene = std::make_unique<RenderScene>(this); Scene = std::make_unique<RenderScene>(this);
DrawSegments = std::make_unique<DrawSegmentList>(this); DrawSegments = std::make_unique<DrawSegmentList>(this);
ClipSegments = std::make_unique<RenderClipSegment>(); ClipSegments = std::make_unique<RenderClipSegment>();
tc_drawers = std::make_unique<SWTruecolorDrawers>(DrawQueue);
pal_drawers = std::make_unique<SWPalDrawers>(DrawQueue);
} }
RenderThread::~RenderThread() 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> #include <memory>
class DrawerCommandQueue;
typedef std::shared_ptr<DrawerCommandQueue> DrawerCommandQueuePtr;
namespace swrenderer namespace swrenderer
{ {
class VisibleSpriteList; class VisibleSpriteList;
@ -37,6 +40,9 @@ namespace swrenderer
class DrawSegmentList; class DrawSegmentList;
class RenderClipSegment; class RenderClipSegment;
class RenderMemory; class RenderMemory;
class SWPixelFormatDrawers;
class SWTruecolorDrawers;
class SWPalDrawers;
class RenderThread class RenderThread
{ {
@ -55,5 +61,12 @@ namespace swrenderer
std::unique_ptr<RenderScene> Scene; std::unique_ptr<RenderScene> Scene;
std::unique_ptr<DrawSegmentList> DrawSegments; std::unique_ptr<DrawSegmentList> DrawSegments;
std::unique_ptr<RenderClipSegment> ClipSegments; 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); RenderActorView(player->mo);
// Apply special colormap if the target cannot do it // Apply special colormap if the target cannot do it
if (CameraLight::Instance()->ShaderColormap() && viewport->RenderTarget->IsBgra() && !(r_shadercolormaps && screen->Accel2D)) 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) void RenderScene::RenderActorView(AActor *actor, bool dontmaplines)
@ -195,8 +193,6 @@ namespace swrenderer
const bool savedviewactive = viewactive; const bool savedviewactive = viewactive;
R_BeginDrawerCommands();
viewwidth = width; viewwidth = width;
viewport->RenderTarget = canvas; viewport->RenderTarget = canvas;
@ -208,7 +204,7 @@ namespace swrenderer
RenderActorView(actor, dontmaplines); RenderActorView(actor, dontmaplines);
R_EndDrawerCommands(); DrawerThreads::Execute({ Thread->DrawQueue });
viewport->RenderTarget = screen; viewport->RenderTarget = screen;

View File

@ -329,6 +329,6 @@ namespace swrenderer
else else
sprtopscreen = viewport->CenterY - texturemid * spryscale; 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)) if (translucentPass->ClipSpriteColumnWithPortals(x, vis))
continue; continue;
uint32_t *dest = (uint32_t*)viewport->GetDest(x, yl); 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 else
@ -257,7 +257,7 @@ namespace swrenderer
if (translucentPass->ClipSpriteColumnWithPortals(x, vis)) if (translucentPass->ClipSpriteColumnWithPortals(x, vis))
continue; continue;
uint8_t *dest = viewport->GetDest(x, yl); 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() 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)) if (xscale == 0 || fabs(yscale) < (1.0f / 32000.0f))
{ // scaled to 0; can't see { // scaled to 0; can't see
@ -627,7 +627,7 @@ namespace swrenderer
fixed_t frac = startfrac; fixed_t frac = startfrac;
for (int x = x1; x < x2; x++) 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; frac += xiscale;
} }

View File

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

View File

@ -291,7 +291,7 @@ namespace swrenderer
while (x < x2) while (x < x2)
{ {
if (!translucentPass->ClipSpriteColumnWithPortals(x, vis)) 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++; x++;
frac += xiscale; frac += xiscale;
} }

View File

@ -292,7 +292,7 @@ namespace swrenderer
voxel_pos.Y += dirY.X * x + dirY.Y * y; voxel_pos.Y += dirY.X * x + dirY.Y * y;
voxel_pos.Z += dirZ * z; 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); 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(); auto viewport = RenderViewport::Instance();
@ -345,7 +345,7 @@ namespace swrenderer
drawerargs.SetDest(x, columnY1); drawerargs.SetDest(x, columnY1);
drawerargs.SetSolidColor(color); drawerargs.SetSolidColor(color);
drawerargs.SetCount(columnY2 - columnY1); 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 }; 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 *GetSlabStart(const FVoxelMipLevel &mip, int x, int y);
static kvxslab_t *GetSlabEnd(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); drawerargs.SetLight(usecolormap, light, shade);
} }
if (!translucentPass->ClipSpriteColumnWithPortals(x, spr)) 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; light += lightstep;
x++; 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(); auto viewport = RenderViewport::Instance();
@ -258,6 +258,6 @@ namespace swrenderer
else else
sprtopscreen = viewport->CenterY - texturemid * spryscale; 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; void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override;
private: 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; FWallCoords wallc;
uint32_t Translation = 0; uint32_t Translation = 0;

View File

@ -13,17 +13,18 @@
#include <stddef.h> #include <stddef.h>
#include "r_skydrawer.h" #include "r_skydrawer.h"
#include "swrenderer/r_renderthread.h"
namespace swrenderer 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) void SkyDrawerArgs::SetDest(int x, int y)

View File

@ -9,6 +9,8 @@ struct TriLight;
namespace swrenderer namespace swrenderer
{ {
class RenderThread;
class SkyDrawerArgs : public DrawerArgs class SkyDrawerArgs : public DrawerArgs
{ {
public: public:
@ -38,8 +40,8 @@ namespace swrenderer
int FrontTextureHeight() const { return dc_sourceheight; } int FrontTextureHeight() const { return dc_sourceheight; }
int BackTextureHeight() const { return dc_sourceheight2; } int BackTextureHeight() const { return dc_sourceheight2; }
void DrawSingleSkyColumn(); void DrawSingleSkyColumn(RenderThread *thread);
void DrawDoubleSkyColumn(); void DrawDoubleSkyColumn(RenderThread *thread);
private: private:
uint8_t *dc_dest = nullptr; uint8_t *dc_dest = nullptr;

View File

@ -13,6 +13,7 @@
#include <stddef.h> #include <stddef.h>
#include "r_spandrawer.h" #include "r_spandrawer.h"
#include "swrenderer/r_renderthread.h"
namespace swrenderer 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 namespace swrenderer
{ {
class RenderThread;
class SpanDrawerArgs : public DrawerArgs class SpanDrawerArgs : public DrawerArgs
{ {
public: public:
@ -26,10 +28,10 @@ namespace swrenderer
void SetTextureVStep(dsfixed_t vstep) { ds_ystep = vstep; } void SetTextureVStep(dsfixed_t vstep) { ds_ystep = vstep; }
void SetSolidColor(int colorIndex) { ds_color = colorIndex; } void SetSolidColor(int colorIndex) { ds_color = colorIndex; }
void DrawSpan(); void DrawSpan(RenderThread *thread);
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 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(int y, int x1, int x2); void DrawColoredSpan(RenderThread *thread, int y, int x1, int x2);
void DrawFogBoundaryLine(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 *SrcBlend() const { return dc_srcblend; }
uint32_t *DestBlend() const { return dc_destblend; } uint32_t *DestBlend() const { return dc_destblend; }

View File

@ -34,6 +34,7 @@
#include <stddef.h> #include <stddef.h>
#include "r_spritedrawer.h" #include "r_spritedrawer.h"
#include "swrenderer/r_renderthread.h"
namespace swrenderer namespace swrenderer
{ {
@ -42,14 +43,14 @@ namespace swrenderer
colfunc = &SWPixelFormatDrawers::DrawColumn; 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(); auto viewport = RenderViewport::Instance();
// Handle the linear filtered version in a different function to reduce chances of merge conflicts from zdoom. // 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 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; return;
} }
@ -115,13 +116,13 @@ namespace swrenderer
else if (dc_iscale < 0) else if (dc_iscale < 0)
dc_count = MIN(dc_count, (dc_texturefrac - dc_iscale) / (-dc_iscale)); dc_count = MIN(dc_count, (dc_texturefrac - dc_iscale) / (-dc_iscale));
(RenderViewport::Instance()->Drawers()->*colfunc)(*this); (thread->Drawers()->*colfunc)(*this);
} }
span++; 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_x = x;
dc_iscale = iscale; dc_iscale = iscale;
@ -230,7 +231,7 @@ namespace swrenderer
double v = ((dc_yl + 0.5 - sprtopscreen) / spryscale) / tex->GetHeight(); double v = ((dc_yl + 0.5 - sprtopscreen) / spryscale) / tex->GetHeight();
dc_texturefrac = (uint32_t)(v * (1 << 30)); dc_texturefrac = (uint32_t)(v * (1 << 30));
(RenderViewport::Instance()->Drawers()->*colfunc)(*this); (thread->Drawers()->*colfunc)(*this);
} }
span++; span++;
} }
@ -488,9 +489,9 @@ namespace swrenderer
return SetStyle(style, FLOAT2FIXED(alpha), translation, color, basecolormap, shadedlightshade); 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) void SpriteDrawerArgs::SetDest(int x, int y)

View File

@ -9,6 +9,8 @@ struct TriLight;
namespace swrenderer namespace swrenderer
{ {
class RenderThread;
class SpriteDrawerArgs : public DrawerArgs class SpriteDrawerArgs : public DrawerArgs
{ {
public: public:
@ -20,8 +22,8 @@ namespace swrenderer
void SetCount(int count) { dc_count = count; } void SetCount(int count) { dc_count = count; }
void SetSolidColor(int color) { dc_color = color; } 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 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(); void FillColumn(RenderThread *thread);
uint8_t *Dest() const { return dc_dest; } uint8_t *Dest() const { return dc_dest; }
int DestY() const { return dc_dest_y; } int DestY() const { return dc_dest_y; }
@ -51,7 +53,7 @@ namespace swrenderer
private: private:
bool SetBlendFunc(int op, fixed_t fglevel, fixed_t bglevel, int flags); bool SetBlendFunc(int op, fixed_t fglevel, fixed_t bglevel, int flags);
static fixed_t GetAlpha(int type, fixed_t alpha); 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; uint8_t *dc_dest = nullptr;
int dc_dest_y = 0; int dc_dest_y = 0;

View File

@ -48,22 +48,12 @@ namespace swrenderer
RenderViewport::RenderViewport() RenderViewport::RenderViewport()
{ {
tc_drawers = std::make_unique<SWTruecolorDrawers>();
pal_drawers = std::make_unique<SWPalDrawers>();
} }
RenderViewport::~RenderViewport() 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) void RenderViewport::SetViewport(int fullWidth, int fullHeight, float trueratio)
{ {
int virtheight, virtwidth, virtwidth2, virtheight2; int virtheight, virtwidth, virtwidth2, virtheight2;

View File

@ -19,10 +19,6 @@
namespace swrenderer namespace swrenderer
{ {
class SWPixelFormatDrawers;
class SWTruecolorDrawers;
class SWPalDrawers;
class RenderViewport class RenderViewport
{ {
public: public:
@ -63,15 +59,10 @@ namespace swrenderer
DVector2 PointWorldToView(const DVector2 &worldPos) const; DVector2 PointWorldToView(const DVector2 &worldPos) const;
DVector2 ScaleViewToScreen(const DVector2 &scale, double viewZ, bool pixelstretch = true) const; DVector2 ScaleViewToScreen(const DVector2 &scale, double viewZ, bool pixelstretch = true) const;
SWPixelFormatDrawers *Drawers();
private: private:
void InitTextureMapping(); void InitTextureMapping();
void SetupBuffer(); void SetupBuffer();
double BaseYaspectMul = 0.0; // yaspectmul without a forced aspect ratio 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 <stddef.h>
#include "r_walldrawer.h" #include "r_walldrawer.h"
#include "swrenderer/r_renderthread.h"
namespace swrenderer namespace swrenderer
{ {
@ -23,9 +24,9 @@ namespace swrenderer
dc_dest_y = y; 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) void WallDrawerArgs::SetStyle(bool masked, bool additive, fixed_t alpha)

View File

@ -9,6 +9,8 @@ struct TriLight;
namespace swrenderer namespace swrenderer
{ {
class RenderThread;
class WallDrawerArgs : public DrawerArgs class WallDrawerArgs : public DrawerArgs
{ {
public: public:
@ -28,7 +30,7 @@ namespace swrenderer
bool IsMaskedDrawer() const; bool IsMaskedDrawer() const;
void DrawColumn(); void DrawColumn(RenderThread *thread);
uint8_t *Dest() const { return dc_dest; } uint8_t *Dest() const { return dc_dest; }
int DestY() const { return dc_dest_y; } int DestY() const { return dc_dest_y; }

View File

@ -47,6 +47,7 @@
#include "swrenderer/drawers/r_draw_rgba.h" #include "swrenderer/drawers/r_draw_rgba.h"
#include "swrenderer/scene/r_light.h" #include "swrenderer/scene/r_light.h"
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_renderthread.h"
#endif #endif
#include "r_data/r_translate.h" #include "r_data/r_translate.h"
#include "doomstat.h" #include "doomstat.h"
@ -278,9 +279,11 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
int x2_i = int(x2); int x2_i = int(x2);
fixed_t xiscale_i = FLOAT2FIXED(xiscale); fixed_t xiscale_i = FLOAT2FIXED(xiscale);
static RenderThread thread;
thread.DrawQueue->ThreadedRender = false;
while (x < x2_i) 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++; x++;
frac += xiscale_i; frac += xiscale_i;
} }
@ -1427,6 +1430,9 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints,
pt2++; if (pt2 > npoints) pt2 = 0; pt2++; if (pt2 > npoints) pt2 = 0;
} while (pt1 != botpt); } while (pt1 != botpt);
static RenderThread thread;
thread.DrawQueue->ThreadedRender = false;
// Travel down the left edge and fill it in. // Travel down the left edge and fill it in.
pt1 = toppt; pt1 = toppt;
pt2 = toppt - 1; if (pt2 < 0) pt2 = npoints; 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.SetTextureUPos(xs_RoundToInt(tex.X * scalex));
drawerargs.SetTextureVPos(xs_RoundToInt(tex.Y * scaley)); drawerargs.SetTextureVPos(xs_RoundToInt(tex.Y * scaley));
drawerargs.DrawSpan(); drawerargs.DrawSpan(&thread);
#endif #endif
} }
x += xinc; x += xinc;