mirror of https://github.com/ZDoom/qzdoom.git
Split drawer command queue from drawer threads
This commit is contained in:
parent
ebb8da563a
commit
6f5e720576
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace swrenderer
|
||||||
|
|
||||||
short renderflags = 0;
|
short renderflags = 0;
|
||||||
|
|
||||||
void Render();
|
void Render(RenderThread *thread);
|
||||||
};
|
};
|
||||||
|
|
||||||
class HWAccelPlayerSprite
|
class HWAccelPlayerSprite
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue