Merge dpJudas's renderslices branch (#1356)

* Remove threading from the drawers

* Fix some r_scene_multithreaded related bugs

* Fix some r_scene_multithreaded crashes

* Fix fullbright shade bug

* Fix truecolor drawer crash

* Add debug code for showing the render slices

* Fix texture loading race condition and improve performance by only locking the load mutex if data hasn't already been updated for this frame

Co-authored-by: Magnus Norddahl <dpjudas@users.noreply.github.com>
This commit is contained in:
Xaser Acheron 2021-03-25 19:58:08 -05:00 committed by GitHub
parent c6073d9c9d
commit a5cba1aba5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 1346 additions and 1997 deletions

View file

@ -221,238 +221,7 @@ namespace swrenderer
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
DrawWallCommand::DrawWallCommand(const WallDrawerArgs& args) : wallargs(args) void SWPixelFormatDrawers::DrawDepthColumn(const WallColumnDrawerArgs& args, float idepth)
{
}
void DrawWallCommand::Execute(DrawerThread* thread)
{
if (!thread->columndrawer)
thread->columndrawer = std::make_shared<WallColumnDrawerArgs>();
WallColumnDrawerArgs& drawerargs = *thread->columndrawer.get();
drawerargs.wallargs = &wallargs;
bool haslights = r_dynlights && wallargs.lightlist;
if (haslights)
{
float dx = wallargs.WallC.tright.X - wallargs.WallC.tleft.X;
float dy = wallargs.WallC.tright.Y - wallargs.WallC.tleft.Y;
float length = sqrt(dx * dx + dy * dy);
drawerargs.dc_normal.X = dy / length;
drawerargs.dc_normal.Y = -dx / length;
drawerargs.dc_normal.Z = 0.0f;
}
drawerargs.SetTextureFracBits(wallargs.fracbits);
float curlight = wallargs.lightpos;
float lightstep = wallargs.lightstep;
int shade = wallargs.Shade();
if (wallargs.fixedlight)
{
curlight = wallargs.FixedLight();
lightstep = 0;
}
float upos = wallargs.texcoords.upos, ustepX = wallargs.texcoords.ustepX, ustepY = wallargs.texcoords.ustepY;
float vpos = wallargs.texcoords.vpos, vstepX = wallargs.texcoords.vstepX, vstepY = wallargs.texcoords.vstepY;
float wpos = wallargs.texcoords.wpos, wstepX = wallargs.texcoords.wstepX, wstepY = wallargs.texcoords.wstepY;
float startX = wallargs.texcoords.startX;
int x1 = wallargs.x1;
int x2 = wallargs.x2;
upos += ustepX * (x1 + 0.5f - startX);
vpos += vstepX * (x1 + 0.5f - startX);
wpos += wstepX * (x1 + 0.5f - startX);
float centerY = wallargs.CenterY;
centerY -= 0.5f;
auto uwal = wallargs.uwal;
auto dwal = wallargs.dwal;
for (int x = x1; x < x2; x++)
{
int y1 = uwal[x];
int y2 = dwal[x];
if (y2 > y1)
{
drawerargs.SetLight(curlight, shade);
if (haslights)
SetLights(drawerargs, x, y1);
else
drawerargs.dc_num_lights = 0;
float dy = (y1 - centerY);
float u = upos + ustepY * dy;
float v = vpos + vstepY * dy;
float w = wpos + wstepY * dy;
float scaleU = ustepX;
float scaleV = vstepY;
w = 1.0f / w;
u *= w;
v *= w;
scaleU *= w;
scaleV *= w;
uint32_t texelX = (uint32_t)(int64_t)((u - std::floor(u)) * 0x1'0000'0000LL);
uint32_t texelY = (uint32_t)(int64_t)((v - std::floor(v)) * 0x1'0000'0000LL);
uint32_t texelStepX = (uint32_t)(int64_t)(scaleU * 0x1'0000'0000LL);
uint32_t texelStepY = (uint32_t)(int64_t)(scaleV * 0x1'0000'0000LL);
if (wallargs.fracbits != 32)
DrawWallColumn8(thread, drawerargs, x, y1, y2, texelX, texelY, texelStepY);
else
DrawWallColumn32(thread, drawerargs, x, y1, y2, texelX, texelY, texelStepX, texelStepY);
}
upos += ustepX;
vpos += vstepX;
wpos += wstepX;
curlight += lightstep;
}
if (r_modelscene)
{
for (int x = x1; x < x2; x++)
{
int y1 = uwal[x];
int y2 = dwal[x];
if (y2 > y1)
{
int count = y2 - y1;
float w1 = 1.0f / wallargs.WallC.sz1;
float w2 = 1.0f / wallargs.WallC.sz2;
float t = (x - wallargs.WallC.sx1 + 0.5f) / (wallargs.WallC.sx2 - wallargs.WallC.sx1);
float wcol = w1 * (1.0f - t) + w2 * t;
float zcol = 1.0f / wcol;
float zbufferdepth = 1.0f / (zcol / wallargs.FocalTangent);
drawerargs.SetDest(x, y1);
drawerargs.SetCount(count);
DrawDepthColumn(thread, drawerargs, zbufferdepth);
}
}
}
}
void DrawWallCommand::DrawWallColumn32(DrawerThread* thread, WallColumnDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepX, uint32_t texelStepY)
{
int texwidth = wallargs.texwidth;
int texheight = wallargs.texheight;
double xmagnitude = fabs(static_cast<int32_t>(texelStepX)* (1.0 / 0x1'0000'0000LL));
double ymagnitude = fabs(static_cast<int32_t>(texelStepY)* (1.0 / 0x1'0000'0000LL));
double magnitude = MAX(ymagnitude, xmagnitude);
double min_lod = -1000.0;
double lod = MAX(log2(magnitude) + r_lod_bias, min_lod);
bool magnifying = lod < 0.0f;
int mipmap_offset = 0;
int mip_width = texwidth;
int mip_height = texheight;
if (wallargs.mipmapped && mip_width > 1 && mip_height > 1)
{
int level = (int)lod;
while (level > 0 && mip_width > 1 && mip_height > 1)
{
mipmap_offset += mip_width * mip_height;
level--;
mip_width = MAX(mip_width >> 1, 1);
mip_height = MAX(mip_height >> 1, 1);
}
}
const uint32_t* pixels = static_cast<const uint32_t*>(wallargs.texpixels) + mipmap_offset;
fixed_t xxoffset = (texelX >> 16)* mip_width;
const uint8_t* source;
const uint8_t* source2;
uint32_t texturefracx;
bool filter_nearest = (magnifying && !r_magfilter) || (!magnifying && !r_minfilter);
if (filter_nearest)
{
int tx = (xxoffset >> FRACBITS) % mip_width;
source = (uint8_t*)(pixels + tx * mip_height);
source2 = nullptr;
texturefracx = 0;
}
else
{
xxoffset -= FRACUNIT / 2;
int tx0 = (xxoffset >> FRACBITS) % mip_width;
if (tx0 < 0)
tx0 += mip_width;
int tx1 = (tx0 + 1) % mip_width;
source = (uint8_t*)(pixels + tx0 * mip_height);
source2 = (uint8_t*)(pixels + tx1 * mip_height);
texturefracx = (xxoffset >> (FRACBITS - 4)) & 15;
}
int count = y2 - y1;
drawerargs.SetDest(x, y1);
drawerargs.SetCount(count);
drawerargs.SetTexture(source, source2, mip_height);
drawerargs.SetTextureUPos(texturefracx);
drawerargs.SetTextureVPos(texelY);
drawerargs.SetTextureVStep(texelStepY);
DrawColumn(thread, drawerargs);
}
void DrawWallCommand::DrawWallColumn8(DrawerThread* thread, WallColumnDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepY)
{
int texwidth = wallargs.texwidth;
int texheight = wallargs.texheight;
int fracbits = wallargs.fracbits;
uint32_t uv_max = texheight << fracbits;
const uint8_t* pixels = static_cast<const uint8_t*>(wallargs.texpixels) + (((texelX >> 16)* texwidth) >> 16)* texheight;
texelY = (static_cast<uint64_t>(texelY)* texheight) >> (32 - fracbits);
texelStepY = (static_cast<uint64_t>(texelStepY)* texheight) >> (32 - fracbits);
drawerargs.SetTexture(pixels, nullptr, texheight);
drawerargs.SetTextureVStep(texelStepY);
if (uv_max == 0 || texelStepY == 0) // power of two
{
int count = y2 - y1;
drawerargs.SetDest(x, y1);
drawerargs.SetCount(count);
drawerargs.SetTextureVPos(texelY);
DrawColumn(thread, drawerargs);
}
else
{
uint32_t left = y2 - y1;
int y = y1;
while (left > 0)
{
uint32_t available = uv_max - texelY;
uint32_t next_uv_wrap = available / texelStepY;
if (available % texelStepY != 0)
next_uv_wrap++;
uint32_t count = MIN(left, next_uv_wrap);
drawerargs.SetDest(x, y);
drawerargs.SetCount(count);
drawerargs.SetTextureVPos(texelY);
DrawColumn(thread, drawerargs);
y += count;
left -= count;
texelY += texelStepY * count;
if (texelY >= uv_max)
texelY -= uv_max;
}
}
}
void DrawWallCommand::DrawDepthColumn(DrawerThread* thread, const WallColumnDrawerArgs& args, float idepth)
{ {
int x, y, count; int x, y, count;
@ -477,15 +246,11 @@ namespace swrenderer
} }
count = args.Count(); count = args.Count();
auto zbuffer = PolyTriangleThreadData::Get(thread)->depthstencil; auto zbuffer = thread->Poly->depthstencil;
int pitch = zbuffer->Width(); int pitch = zbuffer->Width();
float* values = zbuffer->DepthValues() + y * pitch + x; float* values = zbuffer->DepthValues() + y * pitch + x;
int cnt = count; int cnt = count;
values = thread->dest_for_thread(y, pitch, values);
cnt = thread->count_for_thread(y, cnt);
pitch *= thread->num_cores;
float depth = idepth; float depth = idepth;
for (int i = 0; i < cnt; i++) for (int i = 0; i < cnt; i++)
{ {
@ -494,7 +259,7 @@ namespace swrenderer
} }
} }
void DrawWallCommand::SetLights(WallColumnDrawerArgs& drawerargs, int x, int y1) void SWPixelFormatDrawers::SetLights(WallColumnDrawerArgs& drawerargs, int x, int y1, const WallDrawerArgs& wallargs)
{ {
bool mirror = !!(wallargs.PortalMirrorFlags & RF_XFLIP); bool mirror = !!(wallargs.PortalMirrorFlags & RF_XFLIP);
int tx = x; int tx = x;
@ -560,130 +325,74 @@ namespace swrenderer
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
class DepthSkyColumnCommand : public DrawerCommand
{
public:
DepthSkyColumnCommand(const SkyDrawerArgs &args, float idepth) : idepth(idepth)
{
auto rendertarget = args.Viewport()->RenderTarget;
if (rendertarget->IsBgra())
{
uint32_t *destorg = (uint32_t*)rendertarget->GetPixels();
destorg += viewwindowx + viewwindowy * rendertarget->GetPitch();
uint32_t *dest = (uint32_t*)args.Dest();
int offset = (int)(ptrdiff_t)(dest - destorg);
x = offset % rendertarget->GetPitch();
y = offset / rendertarget->GetPitch();
}
else
{
uint8_t *destorg = rendertarget->GetPixels();
destorg += viewwindowx + viewwindowy * rendertarget->GetPitch();
uint8_t *dest = (uint8_t*)args.Dest();
int offset = (int)(ptrdiff_t)(dest - destorg);
x = offset % rendertarget->GetPitch();
y = offset / rendertarget->GetPitch();
}
count = args.Count();
}
void Execute(DrawerThread *thread) override
{
auto zbuffer = PolyTriangleThreadData::Get(thread)->depthstencil;
int pitch = zbuffer->Width();
float *values = zbuffer->DepthValues() + y * pitch + x;
int cnt = count;
values = thread->dest_for_thread(y, pitch, values);
cnt = thread->count_for_thread(y, cnt);
pitch *= thread->num_cores;
float depth = idepth;
for (int i = 0; i < cnt; i++)
{
*values = depth;
values += pitch;
}
}
private:
int x, y, count;
float idepth;
};
// #define DEPTH_DEBUG
class DepthSpanCommand : public DrawerCommand
{
public:
DepthSpanCommand(const SpanDrawerArgs &args, float idepth1, float idepth2) : idepth1(idepth1), idepth2(idepth2)
{
y = args.DestY();
x1 = args.DestX1();
x2 = args.DestX2();
#ifdef DEPTH_DEBUG
dest = (uint32_t*)args.Viewport()->GetDest(0, args.DestY());
#endif
}
void Execute(DrawerThread *thread) override
{
if (thread->skipped_by_thread(y))
return;
auto zbuffer = PolyTriangleThreadData::Get(thread)->depthstencil;
int pitch = zbuffer->Width();
float *values = zbuffer->DepthValues() + y * pitch;
int end = x2;
if (idepth1 == idepth2)
{
float depth = idepth1;
#ifdef DEPTH_DEBUG
uint32_t gray = clamp<int32_t>((int32_t)(1.0f / depth / 4.0f), 0, 255);
uint32_t color = MAKEARGB(255, gray, gray, gray);
#endif
for (int x = x1; x <= end; x++)
{
values[x] = depth;
#ifdef DEPTH_DEBUG
dest[x] = color;
#endif
}
}
else
{
float depth = idepth1;
float step = (idepth2 - idepth1) / (x2 - x1 + 1);
for (int x = x1; x <= end; x++)
{
#ifdef DEPTH_DEBUG
uint32_t gray = clamp<int32_t>((int32_t)(1.0f / depth / 4.0f), 0, 255);
uint32_t color = MAKEARGB(255, gray, gray, gray);
dest[x] = color;
#endif
values[x] = depth;
depth += step;
}
}
}
private:
int y, x1, x2;
float idepth1, idepth2;
#ifdef DEPTH_DEBUG
uint32_t *dest;
#endif
};
void SWPixelFormatDrawers::DrawDepthSkyColumn(const SkyDrawerArgs &args, float idepth) void SWPixelFormatDrawers::DrawDepthSkyColumn(const SkyDrawerArgs &args, float idepth)
{ {
Queue->Push<DepthSkyColumnCommand>(args, idepth); int x, y, count;
auto rendertarget = args.Viewport()->RenderTarget;
if (rendertarget->IsBgra())
{
uint32_t* destorg = (uint32_t*)rendertarget->GetPixels();
destorg += viewwindowx + viewwindowy * rendertarget->GetPitch();
uint32_t* dest = (uint32_t*)args.Dest();
int offset = (int)(ptrdiff_t)(dest - destorg);
x = offset % rendertarget->GetPitch();
y = offset / rendertarget->GetPitch();
}
else
{
uint8_t* destorg = rendertarget->GetPixels();
destorg += viewwindowx + viewwindowy * rendertarget->GetPitch();
uint8_t* dest = (uint8_t*)args.Dest();
int offset = (int)(ptrdiff_t)(dest - destorg);
x = offset % rendertarget->GetPitch();
y = offset / rendertarget->GetPitch();
}
count = args.Count();
auto zbuffer = thread->Poly->depthstencil;
int pitch = zbuffer->Width();
float* values = zbuffer->DepthValues() + y * pitch + x;
int cnt = count;
float depth = idepth;
for (int i = 0; i < cnt; i++)
{
*values = depth;
values += pitch;
}
} }
void SWPixelFormatDrawers::DrawDepthSpan(const SpanDrawerArgs &args, float idepth1, float idepth2) void SWPixelFormatDrawers::DrawDepthSpan(const SpanDrawerArgs &args, float idepth1, float idepth2)
{ {
Queue->Push<DepthSpanCommand>(args, idepth1, idepth2); int y = args.DestY();
int x1 = args.DestX1();
int x2 = args.DestX2();
auto zbuffer = thread->Poly->depthstencil;
int pitch = zbuffer->Width();
float *values = zbuffer->DepthValues() + x1 + y * pitch;
int count = x2 - x1 + 1;
if (idepth1 == idepth2)
{
float depth = idepth1;
for (int i = 0; i < count; i++)
{
*values = depth;
values++;
}
}
else
{
float depth = idepth1;
float step = (idepth2 - idepth1) / (x2 - x1 + 1);
for (int i = 0; i < count; i++)
{
*values = depth;
values++;
depth += step;
}
}
} }
} }

View file

@ -19,14 +19,12 @@ EXTERN_CVAR(Float, transsouls);
EXTERN_CVAR(Bool, r_dynlights); EXTERN_CVAR(Bool, r_dynlights);
EXTERN_CVAR(Bool, r_fuzzscale); EXTERN_CVAR(Bool, r_fuzzscale);
class DrawerCommandQueue;
typedef std::shared_ptr<DrawerCommandQueue> DrawerCommandQueuePtr;
namespace swrenderer namespace swrenderer
{ {
class DrawerArgs; class DrawerArgs;
class SkyDrawerArgs; class SkyDrawerArgs;
class WallDrawerArgs; class WallDrawerArgs;
class WallColumnDrawerArgs;
class SpanDrawerArgs; class SpanDrawerArgs;
class SpriteDrawerArgs; class SpriteDrawerArgs;
class VoxelBlock; class VoxelBlock;
@ -55,8 +53,8 @@ namespace swrenderer
class SWPixelFormatDrawers class SWPixelFormatDrawers
{ {
public: public:
SWPixelFormatDrawers(DrawerCommandQueuePtr queue) : Queue(queue) { } SWPixelFormatDrawers(RenderThread* thread) : thread(thread) { }
virtual ~SWPixelFormatDrawers() { } virtual ~SWPixelFormatDrawers() = default;
virtual void DrawWall(const WallDrawerArgs &args) = 0; virtual void DrawWall(const WallDrawerArgs &args) = 0;
virtual void DrawWallMasked(const WallDrawerArgs &args) = 0; virtual void DrawWallMasked(const WallDrawerArgs &args) = 0;
virtual void DrawWallAdd(const WallDrawerArgs &args) = 0; virtual void DrawWallAdd(const WallDrawerArgs &args) = 0;
@ -94,11 +92,15 @@ namespace swrenderer
virtual void DrawTiltedSpan(const SpanDrawerArgs &args, 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, 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) = 0; virtual void DrawColoredSpan(const SpanDrawerArgs &args) = 0;
virtual void DrawFogBoundaryLine(const SpanDrawerArgs &args) = 0; virtual void DrawFogBoundaryLine(const SpanDrawerArgs &args) = 0;
virtual void DrawParticleColumn(int x, int yl, int ycount, uint32_t fg, uint32_t alpha, uint32_t fracposx) = 0;
void DrawDepthColumn(const WallColumnDrawerArgs& args, float idepth);
void DrawDepthSkyColumn(const SkyDrawerArgs &args, float idepth); void DrawDepthSkyColumn(const SkyDrawerArgs &args, float idepth);
void DrawDepthSpan(const SpanDrawerArgs &args, float idepth1, float idepth2); void DrawDepthSpan(const SpanDrawerArgs &args, float idepth1, float idepth2);
DrawerCommandQueuePtr Queue; void SetLights(WallColumnDrawerArgs& drawerargs, int x, int y1, const WallDrawerArgs& wallargs);
RenderThread* thread = nullptr;
}; };
void R_InitShadeMaps(); void R_InitShadeMaps();

File diff suppressed because it is too large Load diff

View file

@ -107,289 +107,81 @@ namespace swrenderer
int mShade = 0; int mShade = 0;
}; };
class DrawWallCommand : public DrawerCommand struct DrawWallModeNormal;
{ struct DrawWallModeMasked;
public: struct DrawWallModeAdd;
DrawWallCommand(const WallDrawerArgs& args); struct DrawWallModeAddClamp;
void Execute(DrawerThread* thread) override; struct DrawWallModeSubClamp;
struct DrawWallModeRevSubClamp;
protected:
virtual void DrawColumn(DrawerThread* thread, const WallColumnDrawerArgs& args) = 0;
private:
void DrawWallColumn32(DrawerThread* thread, WallColumnDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepX, uint32_t texelStepY);
void DrawWallColumn8(DrawerThread* thread, WallColumnDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepY);
void DrawDepthColumn(DrawerThread* thread, const WallColumnDrawerArgs& args, float idepth);
void SetLights(WallColumnDrawerArgs& drawerargs, int x, int y1);
WallDrawerArgs wallargs;
};
class PalWall1Command : public DrawWallCommand
{
public:
PalWall1Command(const WallDrawerArgs &args) : DrawWallCommand(args) { }
protected:
inline static uint8_t AddLights(const DrawerLight *lights, int num_lights, float viewpos_z, uint8_t fg, uint8_t material);
};
class DrawWall1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override; };
class DrawWallMasked1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override; };
class DrawWallAdd1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override; };
class DrawWallAddClamp1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override; };
class DrawWallSubClamp1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override; };
class DrawWallRevSubClamp1PalCommand : public PalWall1Command { public: using PalWall1Command::PalWall1Command; void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override; };
class PalSkyCommand : public DrawerCommand
{
public:
PalSkyCommand(const SkyDrawerArgs &args);
protected:
SkyDrawerArgs args;
};
class DrawSingleSky1PalCommand : public PalSkyCommand { public: using PalSkyCommand::PalSkyCommand; void Execute(DrawerThread *thread) override; };
class DrawDoubleSky1PalCommand : public PalSkyCommand { public: using PalSkyCommand::PalSkyCommand; void Execute(DrawerThread *thread) override; };
class PalColumnCommand : public DrawerCommand
{
public:
PalColumnCommand(const SpriteDrawerArgs &args);
SpriteDrawerArgs args;
protected:
uint8_t AddLights(uint8_t fg, uint8_t material, uint32_t lit_r, uint32_t lit_g, uint32_t lit_b);
};
class DrawColumnPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class FillColumnPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class FillColumnAddPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class FillColumnAddClampPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class FillColumnSubClampPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class FillColumnRevSubClampPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class DrawColumnAddPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class DrawColumnTranslatedPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class DrawColumnTlatedAddPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class DrawColumnShadedPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class DrawColumnAddClampShadedPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class DrawColumnAddClampPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class DrawColumnAddClampTranslatedPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class DrawColumnSubClampPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class DrawColumnSubClampTranslatedPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class DrawColumnRevSubClampPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class DrawColumnRevSubClampTranslatedPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
class DrawFuzzColumnPalCommand : public DrawerCommand
{
public:
DrawFuzzColumnPalCommand(const SpriteDrawerArgs &args);
void Execute(DrawerThread *thread) override;
private:
int _yl;
int _yh;
int _x;
uint8_t *_destorg;
int _pitch;
int _fuzzpos;
int _fuzzviewheight;
};
class DrawScaledFuzzColumnPalCommand : public DrawerCommand
{
public:
DrawScaledFuzzColumnPalCommand(const SpriteDrawerArgs &drawerargs);
void Execute(DrawerThread *thread) override;
private:
int _x;
int _yl;
int _yh;
uint8_t *_destorg;
int _pitch;
int _fuzzpos;
int _fuzzviewheight;
};
class PalSpanCommand : public DrawerCommand
{
public:
PalSpanCommand(const SpanDrawerArgs &args);
protected:
inline static uint8_t AddLights(const DrawerLight *lights, int num_lights, float viewpos_x, uint8_t fg, uint8_t material);
const uint8_t *_source;
const uint8_t *_colormap;
uint32_t _xfrac;
uint32_t _yfrac;
int _y;
int _x1;
int _x2;
uint8_t *_dest;
uint32_t _xstep;
uint32_t _ystep;
int _srcwidth;
int _srcheight;
uint32_t *_srcblend;
uint32_t *_destblend;
int _color;
fixed_t _srcalpha;
fixed_t _destalpha;
DrawerLight *_dynlights;
int _num_dynlights;
float _viewpos_x;
float _step_viewpos_x;
};
class DrawSpanPalCommand : public PalSpanCommand { public: using PalSpanCommand::PalSpanCommand; void Execute(DrawerThread *thread) override; };
class DrawSpanMaskedPalCommand : public PalSpanCommand { public: using PalSpanCommand::PalSpanCommand; void Execute(DrawerThread *thread) override; };
class DrawSpanTranslucentPalCommand : public PalSpanCommand { public: using PalSpanCommand::PalSpanCommand; void Execute(DrawerThread *thread) override; };
class DrawSpanMaskedTranslucentPalCommand : public PalSpanCommand { public: using PalSpanCommand::PalSpanCommand; void Execute(DrawerThread *thread) override; };
class DrawSpanAddClampPalCommand : public PalSpanCommand { public: using PalSpanCommand::PalSpanCommand; void Execute(DrawerThread *thread) override; };
class DrawSpanMaskedAddClampPalCommand : public PalSpanCommand { public: using PalSpanCommand::PalSpanCommand; void Execute(DrawerThread *thread) override; };
class FillSpanPalCommand : public PalSpanCommand { public: using PalSpanCommand::PalSpanCommand; void Execute(DrawerThread *thread) override; };
class DrawTiltedSpanPalCommand : public DrawerCommand
{
public:
DrawTiltedSpanPalCommand(const SpanDrawerArgs &args, 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 Execute(DrawerThread *thread) override;
private:
void CalcTiltedLighting(double lval, double lend, int width, DrawerThread *thread);
int y;
int x1;
int x2;
FVector3 plane_sz;
FVector3 plane_su;
FVector3 plane_sv;
bool plane_shade;
int planeshade;
float planelightfloat;
fixed_t pviewx;
fixed_t pviewy;
const uint8_t *_colormap;
uint8_t *_dest;
int _ybits;
int _xbits;
const uint8_t *_source;
uint8_t *basecolormapdata;
RenderViewport *viewport;
};
class DrawColoredSpanPalCommand : public PalSpanCommand
{
public:
DrawColoredSpanPalCommand(const SpanDrawerArgs &args);
void Execute(DrawerThread *thread) override;
private:
int y;
int x1;
int x2;
int color;
uint8_t *dest;
};
class DrawFogBoundaryLinePalCommand : public PalSpanCommand
{
public:
DrawFogBoundaryLinePalCommand(const SpanDrawerArgs &args);
void Execute(DrawerThread *thread) override;
private:
int y, x1, x2;
const uint8_t *_colormap;
uint8_t *_dest;
};
class DrawParticleColumnPalCommand : public DrawerCommand
{
public:
DrawParticleColumnPalCommand(uint8_t *dest, int dest_y, int pitch, int count, uint32_t fg, uint32_t alpha, uint32_t fracposx);
void Execute(DrawerThread *thread) override;
private:
uint8_t *_dest;
int _dest_y;
int _pitch;
int _count;
uint32_t _fg;
uint32_t _alpha;
uint32_t _fracposx;
};
class DrawVoxelBlocksPalCommand : public DrawerCommand
{
public:
DrawVoxelBlocksPalCommand(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount);
void Execute(DrawerThread *thread) override;
private:
SpriteDrawerArgs args;
const VoxelBlock *blocks;
int blockcount;
};
class SWPalDrawers : public SWPixelFormatDrawers class SWPalDrawers : public SWPixelFormatDrawers
{ {
public: public:
using SWPixelFormatDrawers::SWPixelFormatDrawers; using SWPixelFormatDrawers::SWPixelFormatDrawers;
void DrawWall(const WallDrawerArgs &args) override { Queue->Push<DrawWall1PalCommand>(args); } void DrawWall(const WallDrawerArgs &args) override { DrawWallColumns<DrawWallModeNormal>(args); }
void DrawWallMasked(const WallDrawerArgs &args) override { Queue->Push<DrawWallMasked1PalCommand>(args); } void DrawWallMasked(const WallDrawerArgs &args) override { DrawWallColumns<DrawWallModeMasked>(args); }
void DrawWallAdd(const WallDrawerArgs &args) override { Queue->Push<DrawWallAdd1PalCommand>(args); } void DrawWallAdd(const WallDrawerArgs &args) override { DrawWallColumns<DrawWallModeAdd>(args); }
void DrawWallAddClamp(const WallDrawerArgs &args) override { Queue->Push<DrawWallAddClamp1PalCommand>(args); } void DrawWallAddClamp(const WallDrawerArgs &args) override { DrawWallColumns<DrawWallModeAddClamp>(args); }
void DrawWallSubClamp(const WallDrawerArgs &args) override { Queue->Push<DrawWallSubClamp1PalCommand>(args); } void DrawWallSubClamp(const WallDrawerArgs &args) override { DrawWallColumns<DrawWallModeSubClamp>(args); }
void DrawWallRevSubClamp(const WallDrawerArgs &args) override { Queue->Push<DrawWallRevSubClamp1PalCommand>(args); } void DrawWallRevSubClamp(const WallDrawerArgs &args) override { DrawWallColumns<DrawWallModeRevSubClamp>(args); }
void DrawSingleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push<DrawSingleSky1PalCommand>(args); } void DrawSingleSkyColumn(const SkyDrawerArgs& args) override;
void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push<DrawDoubleSky1PalCommand>(args); } void DrawDoubleSkyColumn(const SkyDrawerArgs& args) override;
void DrawColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnPalCommand>(args); } void DrawColumn(const SpriteDrawerArgs& args) override;
void FillColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnPalCommand>(args); } void FillColumn(const SpriteDrawerArgs& args) override;
void FillAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnAddPalCommand>(args); } void FillAddColumn(const SpriteDrawerArgs& args) override;
void FillAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnAddClampPalCommand>(args); } void FillAddClampColumn(const SpriteDrawerArgs& args) override;
void FillSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnSubClampPalCommand>(args); } void FillSubClampColumn(const SpriteDrawerArgs& args) override;
void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnRevSubClampPalCommand>(args); } void FillRevSubClampColumn(const SpriteDrawerArgs& args) override;
void DrawFuzzColumn(const SpriteDrawerArgs &args) override void DrawFuzzColumn(const SpriteDrawerArgs &args) override
{ {
if (r_fuzzscale) if (r_fuzzscale)
Queue->Push<DrawScaledFuzzColumnPalCommand>(args); DrawScaledFuzzColumn(args);
else else
Queue->Push<DrawFuzzColumnPalCommand>(args); DrawUnscaledFuzzColumn(args);
R_UpdateFuzzPos(args); R_UpdateFuzzPos(args);
} }
void DrawAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddPalCommand>(args); } void DrawAddColumn(const SpriteDrawerArgs& args) override;
void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnTranslatedPalCommand>(args); } void DrawTranslatedColumn(const SpriteDrawerArgs& args) override;
void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnTlatedAddPalCommand>(args); } void DrawTranslatedAddColumn(const SpriteDrawerArgs& args) override;
void DrawShadedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnShadedPalCommand>(args); } void DrawShadedColumn(const SpriteDrawerArgs& args) override;
void DrawAddClampShadedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddClampShadedPalCommand>(args); } void DrawAddClampShadedColumn(const SpriteDrawerArgs& args) override;
void DrawAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddClampPalCommand>(args); } void DrawAddClampColumn(const SpriteDrawerArgs& args) override;
void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddClampTranslatedPalCommand>(args); } void DrawAddClampTranslatedColumn(const SpriteDrawerArgs& args) override;
void DrawSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnSubClampPalCommand>(args); } void DrawSubClampColumn(const SpriteDrawerArgs& args) override;
void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnSubClampTranslatedPalCommand>(args); } void DrawSubClampTranslatedColumn(const SpriteDrawerArgs& args) override;
void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampPalCommand>(args); } void DrawRevSubClampColumn(const SpriteDrawerArgs& args) override;
void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampTranslatedPalCommand>(args); } void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs& args) override;
void DrawVoxelBlocks(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount) override { Queue->Push<DrawVoxelBlocksPalCommand>(args, blocks, blockcount); } void DrawVoxelBlocks(const SpriteDrawerArgs& args, const VoxelBlock* blocks, int blockcount) override;
void DrawSpan(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanPalCommand>(args); } void DrawSpan(const SpanDrawerArgs& args) override;
void DrawSpanMasked(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedPalCommand>(args); } void DrawSpanMasked(const SpanDrawerArgs& args) override;
void DrawSpanTranslucent(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanTranslucentPalCommand>(args); } void DrawSpanTranslucent(const SpanDrawerArgs& args) override;
void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedTranslucentPalCommand>(args); } void DrawSpanMaskedTranslucent(const SpanDrawerArgs& args) override;
void DrawSpanAddClamp(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanAddClampPalCommand>(args); } void DrawSpanAddClamp(const SpanDrawerArgs& args) override;
void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedAddClampPalCommand>(args); } void DrawSpanMaskedAddClamp(const SpanDrawerArgs& args) override;
void FillSpan(const SpanDrawerArgs &args) override { Queue->Push<FillSpanPalCommand>(args); } void FillSpan(const SpanDrawerArgs& args) override;
void DrawTiltedSpan(const SpanDrawerArgs& args, 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 DrawColoredSpan(const SpanDrawerArgs& args) override;
void DrawFogBoundaryLine(const SpanDrawerArgs& args) override;
void DrawTiltedSpan(const SpanDrawerArgs &args, 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 DrawParticleColumn(int x, int yl, int ycount, uint32_t fg, uint32_t alpha, uint32_t fracposx) override;
{
Queue->Push<DrawTiltedSpanPalCommand>(args, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy, basecolormap);
}
void DrawColoredSpan(const SpanDrawerArgs &args) override { Queue->Push<DrawColoredSpanPalCommand>(args); } void DrawScaledFuzzColumn(const SpriteDrawerArgs& args);
void DrawFogBoundaryLine(const SpanDrawerArgs &args) override { Queue->Push<DrawFogBoundaryLinePalCommand>(args); } void DrawUnscaledFuzzColumn(const SpriteDrawerArgs& args);
inline static uint8_t AddLightsColumn(const DrawerLight* lights, int num_lights, float viewpos_z, uint8_t fg, uint8_t material);
inline static uint8_t AddLightsSpan(const DrawerLight* lights, int num_lights, float viewpos_z, uint8_t fg, uint8_t material);
inline static uint8_t AddLights(uint8_t fg, uint8_t material, uint32_t lit_r, uint32_t lit_g, uint32_t lit_b);
void CalcTiltedLighting(double lstart, double lend, int width, int planeshade, uint8_t* basecolormapdata);
template<typename DrawerT> void DrawWallColumns(const WallDrawerArgs& args);
template<typename DrawerT> void DrawWallColumn8(WallColumnDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepY);
template<typename DrawerT> void DrawWallColumn(const WallColumnDrawerArgs& args);
// Working buffer used by the tilted (sloped) span drawer
const uint8_t* tiltlighting[MAXWIDTH];
WallColumnDrawerArgs wallcolargs;
}; };
} }

View file

@ -82,193 +82,185 @@ namespace swrenderer
{ {
void SWTruecolorDrawers::DrawWall(const WallDrawerArgs &args) void SWTruecolorDrawers::DrawWall(const WallDrawerArgs &args)
{ {
Queue->Push<DrawWall32Command>(args); DrawWallColumns<DrawWall32Command>(args);
} }
void SWTruecolorDrawers::DrawWallMasked(const WallDrawerArgs &args) void SWTruecolorDrawers::DrawWallMasked(const WallDrawerArgs &args)
{ {
Queue->Push<DrawWallMasked32Command>(args); DrawWallColumns<DrawWallMasked32Command>(args);
} }
void SWTruecolorDrawers::DrawWallAdd(const WallDrawerArgs &args) void SWTruecolorDrawers::DrawWallAdd(const WallDrawerArgs &args)
{ {
Queue->Push<DrawWallAddClamp32Command>(args); DrawWallColumns<DrawWallAddClamp32Command>(args);
} }
void SWTruecolorDrawers::DrawWallAddClamp(const WallDrawerArgs &args) void SWTruecolorDrawers::DrawWallAddClamp(const WallDrawerArgs &args)
{ {
Queue->Push<DrawWallAddClamp32Command>(args); DrawWallColumns<DrawWallAddClamp32Command>(args);
} }
void SWTruecolorDrawers::DrawWallSubClamp(const WallDrawerArgs &args) void SWTruecolorDrawers::DrawWallSubClamp(const WallDrawerArgs &args)
{ {
Queue->Push<DrawWallSubClamp32Command>(args); DrawWallColumns<DrawWallSubClamp32Command>(args);
} }
void SWTruecolorDrawers::DrawWallRevSubClamp(const WallDrawerArgs &args) void SWTruecolorDrawers::DrawWallRevSubClamp(const WallDrawerArgs &args)
{ {
Queue->Push<DrawWallRevSubClamp32Command>(args); DrawWallColumns<DrawWallRevSubClamp32Command>(args);
} }
void SWTruecolorDrawers::DrawColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::DrawColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<DrawSprite32Command>(args); DrawSprite32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::FillColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::FillColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<FillSprite32Command>(args); FillSprite32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::FillAddColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::FillAddColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<FillSpriteAddClamp32Command>(args); FillSpriteAddClamp32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::FillAddClampColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::FillAddClampColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<FillSpriteAddClamp32Command>(args); FillSpriteAddClamp32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::FillSubClampColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::FillSubClampColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<FillSpriteSubClamp32Command>(args); FillSpriteSubClamp32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::FillRevSubClampColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::FillRevSubClampColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<FillSpriteRevSubClamp32Command>(args); FillSpriteRevSubClamp32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawFuzzColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::DrawFuzzColumn(const SpriteDrawerArgs &args)
{ {
if (r_fuzzscale) if (r_fuzzscale)
Queue->Push<DrawScaledFuzzColumnRGBACommand>(args); DrawScaledFuzzColumn(args);
else else
Queue->Push<DrawFuzzColumnRGBACommand>(args); DrawUnscaledFuzzColumn(args);
R_UpdateFuzzPos(args); R_UpdateFuzzPos(args);
} }
void SWTruecolorDrawers::DrawAddColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::DrawAddColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<DrawSpriteAddClamp32Command>(args); DrawSpriteAddClamp32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawTranslatedColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::DrawTranslatedColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<DrawSpriteTranslated32Command>(args); DrawSpriteTranslated32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawTranslatedAddColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::DrawTranslatedAddColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<DrawSpriteTranslatedAddClamp32Command>(args); DrawSpriteTranslatedAddClamp32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawShadedColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::DrawShadedColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<DrawSpriteShaded32Command>(args); DrawSpriteShaded32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawAddClampShadedColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::DrawAddClampShadedColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<DrawSpriteAddClampShaded32Command>(args); DrawSpriteAddClampShaded32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawAddClampColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::DrawAddClampColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<DrawSpriteAddClamp32Command>(args); DrawSpriteAddClamp32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<DrawSpriteTranslatedAddClamp32Command>(args); DrawSpriteTranslatedAddClamp32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawSubClampColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::DrawSubClampColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<DrawSpriteSubClamp32Command>(args); DrawSpriteSubClamp32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<DrawSpriteTranslatedSubClamp32Command>(args); DrawSpriteTranslatedSubClamp32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawRevSubClampColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::DrawRevSubClampColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<DrawSpriteRevSubClamp32Command>(args); DrawSpriteRevSubClamp32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) void SWTruecolorDrawers::DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args)
{ {
Queue->Push<DrawSpriteTranslatedRevSubClamp32Command>(args); DrawSpriteTranslatedRevSubClamp32Command::DrawColumn(args);
}
void SWTruecolorDrawers::DrawVoxelBlocks(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount)
{
Queue->Push<DrawVoxelBlocksRGBACommand>(args, blocks, blockcount);
} }
void SWTruecolorDrawers::DrawSpan(const SpanDrawerArgs &args) void SWTruecolorDrawers::DrawSpan(const SpanDrawerArgs &args)
{ {
Queue->Push<DrawSpan32Command>(args); DrawSpan32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawSpanMasked(const SpanDrawerArgs &args) void SWTruecolorDrawers::DrawSpanMasked(const SpanDrawerArgs &args)
{ {
Queue->Push<DrawSpanMasked32Command>(args); DrawSpanMasked32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawSpanTranslucent(const SpanDrawerArgs &args) void SWTruecolorDrawers::DrawSpanTranslucent(const SpanDrawerArgs &args)
{ {
Queue->Push<DrawSpanTranslucent32Command>(args); DrawSpanTranslucent32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) void SWTruecolorDrawers::DrawSpanMaskedTranslucent(const SpanDrawerArgs &args)
{ {
Queue->Push<DrawSpanAddClamp32Command>(args); DrawSpanAddClamp32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawSpanAddClamp(const SpanDrawerArgs &args) void SWTruecolorDrawers::DrawSpanAddClamp(const SpanDrawerArgs &args)
{ {
Queue->Push<DrawSpanTranslucent32Command>(args); DrawSpanTranslucent32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) void SWTruecolorDrawers::DrawSpanMaskedAddClamp(const SpanDrawerArgs &args)
{ {
Queue->Push<DrawSpanAddClamp32Command>(args); DrawSpanAddClamp32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawSingleSkyColumn(const SkyDrawerArgs &args) void SWTruecolorDrawers::DrawSingleSkyColumn(const SkyDrawerArgs &args)
{ {
Queue->Push<DrawSkySingle32Command>(args); DrawSkySingle32Command::DrawColumn(args);
} }
void SWTruecolorDrawers::DrawDoubleSkyColumn(const SkyDrawerArgs &args) void SWTruecolorDrawers::DrawDoubleSkyColumn(const SkyDrawerArgs &args)
{ {
Queue->Push<DrawSkyDouble32Command>(args); DrawSkyDouble32Command::DrawColumn(args);
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
DrawScaledFuzzColumnRGBACommand::DrawScaledFuzzColumnRGBACommand(const SpriteDrawerArgs &drawerargs) void SWTruecolorDrawers::DrawScaledFuzzColumn(const SpriteDrawerArgs& drawerargs)
{ {
_x = drawerargs.FuzzX(); int _x = drawerargs.FuzzX();
_yl = drawerargs.FuzzY1(); int _yl = drawerargs.FuzzY1();
_yh = drawerargs.FuzzY2(); int _yh = drawerargs.FuzzY2();
_destorg = drawerargs.Viewport()->GetDest(0, 0); uint8_t* RESTRICT _destorg = drawerargs.Viewport()->GetDest(0, 0);
_pitch = drawerargs.Viewport()->RenderTarget->GetPitch(); int _pitch = drawerargs.Viewport()->RenderTarget->GetPitch();
_fuzzpos = fuzzpos; int _fuzzpos = fuzzpos;
_fuzzviewheight = fuzzviewheight; int _fuzzviewheight = fuzzviewheight;
}
void DrawScaledFuzzColumnRGBACommand::Execute(DrawerThread *thread)
{
int x = _x; int x = _x;
int yl = MAX(_yl, 1); int yl = MAX(_yl, 1);
int yh = MIN(_yh, _fuzzviewheight); int yh = MIN(_yh, _fuzzviewheight);
int count = thread->count_for_thread(yl, yh - yl + 1); int count = yh - yl + 1;
if (count <= 0) return; if (count <= 0) return;
int pitch = _pitch; int pitch = _pitch;
@ -279,14 +271,7 @@ namespace swrenderer
fixed_t fuzzstep = (200 << FRACBITS) / _fuzzviewheight; fixed_t fuzzstep = (200 << FRACBITS) / _fuzzviewheight;
fixed_t fuzzcount = FUZZTABLE << FRACBITS; fixed_t fuzzcount = FUZZTABLE << FRACBITS;
fixed_t fuzz = (fuzz_x << FRACBITS) + yl * fuzzstep; fixed_t fuzz = ((fuzz_x << FRACBITS) + yl * fuzzstep) % fuzzcount;
dest = thread->dest_for_thread(yl, pitch, dest);
pitch *= thread->num_cores;
fuzz += fuzzstep * thread->skipped_by_thread(yl);
fuzz %= fuzzcount;
fuzzstep *= thread->num_cores;
while (count > 0) while (count > 0)
{ {
@ -309,33 +294,30 @@ namespace swrenderer
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
DrawFuzzColumnRGBACommand::DrawFuzzColumnRGBACommand(const SpriteDrawerArgs &drawerargs) void SWTruecolorDrawers::DrawUnscaledFuzzColumn(const SpriteDrawerArgs& drawerargs)
{ {
_x = drawerargs.FuzzX(); int _x = drawerargs.FuzzX();
_yl = drawerargs.FuzzY1(); int _yl = drawerargs.FuzzY1();
_yh = drawerargs.FuzzY2(); int _yh = drawerargs.FuzzY2();
_destorg = drawerargs.Viewport()->GetDest(0, 0); uint8_t* RESTRICT _destorg = drawerargs.Viewport()->GetDest(0, 0);
_pitch = drawerargs.Viewport()->RenderTarget->GetPitch(); int _pitch = drawerargs.Viewport()->RenderTarget->GetPitch();
_fuzzpos = fuzzpos; int _fuzzpos = fuzzpos;
_fuzzviewheight = fuzzviewheight; int _fuzzviewheight = fuzzviewheight;
}
void DrawFuzzColumnRGBACommand::Execute(DrawerThread *thread)
{
int yl = MAX(_yl, 1); int yl = MAX(_yl, 1);
int yh = MIN(_yh, _fuzzviewheight); int yh = MIN(_yh, _fuzzviewheight);
int count = thread->count_for_thread(yl, yh - yl + 1); int count = yh - yl + 1;
// Zero length. // Zero length.
if (count <= 0) if (count <= 0)
return; return;
uint32_t *dest = thread->dest_for_thread(yl, _pitch, _pitch * yl + _x + (uint32_t*)_destorg); uint32_t *dest = _pitch * yl + _x + (uint32_t*)_destorg;
int pitch = _pitch * thread->num_cores; int pitch = _pitch;
int fuzzstep = thread->num_cores; int fuzzstep = 1;
int fuzz = (_fuzzpos + thread->skipped_by_thread(yl)) % FUZZTABLE; int fuzz = _fuzzpos % FUZZTABLE;
#ifndef ORIGINAL_FUZZ #ifndef ORIGINAL_FUZZ
@ -367,8 +349,6 @@ namespace swrenderer
#else #else
yl += thread->skipped_by_thread(yl);
// Handle the case where we would go out of bounds at the top: // Handle the case where we would go out of bounds at the top:
if (yl < fuzzstep) if (yl < fuzzstep)
{ {
@ -443,20 +423,14 @@ namespace swrenderer
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
FillSpanRGBACommand::FillSpanRGBACommand(const SpanDrawerArgs &drawerargs) void SWTruecolorDrawers::FillSpan(const SpanDrawerArgs& drawerargs)
{ {
_x1 = drawerargs.DestX1(); int _x1 = drawerargs.DestX1();
_x2 = drawerargs.DestX2(); int _x2 = drawerargs.DestX2();
_y = drawerargs.DestY(); int _y = drawerargs.DestY();
_dest = drawerargs.Viewport()->GetDest(_x1, _y); uint8_t* RESTRICT _dest = drawerargs.Viewport()->GetDest(_x1, _y);
_light = drawerargs.Light(); fixed_t _light = drawerargs.Light();
_color = drawerargs.SolidColor(); int _color = drawerargs.SolidColor();
}
void FillSpanRGBACommand::Execute(DrawerThread *thread)
{
if (thread->line_skipped_by_thread(_y))
return;
uint32_t *dest = (uint32_t*)_dest; uint32_t *dest = (uint32_t*)_dest;
int count = (_x2 - _x1 + 1); int count = (_x2 - _x1 + 1);
@ -468,20 +442,14 @@ namespace swrenderer
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
DrawFogBoundaryLineRGBACommand::DrawFogBoundaryLineRGBACommand(const SpanDrawerArgs &drawerargs) void SWTruecolorDrawers::DrawFogBoundaryLine(const SpanDrawerArgs& drawerargs)
{ {
_y = drawerargs.DestY(); int _y = drawerargs.DestY();
_x = drawerargs.DestX1(); int _x = drawerargs.DestX1();
_x2 = drawerargs.DestX2(); int _x2 = drawerargs.DestX2();
_line = drawerargs.Viewport()->GetDest(0, _y); uint8_t* RESTRICT _line = drawerargs.Viewport()->GetDest(0, _y);
_light = drawerargs.Light(); fixed_t _light = drawerargs.Light();
_shade_constants = drawerargs.ColormapConstants(); ShadeConstants constants = drawerargs.ColormapConstants();
}
void DrawFogBoundaryLineRGBACommand::Execute(DrawerThread *thread)
{
if (thread->line_skipped_by_thread(_y))
return;
int y = _y; int y = _y;
int x = _x; int x = _x;
@ -490,7 +458,6 @@ namespace swrenderer
uint32_t *dest = (uint32_t*)_line; uint32_t *dest = (uint32_t*)_line;
uint32_t light = LightBgra::calc_light_multiplier(_light); uint32_t light = LightBgra::calc_light_multiplier(_light);
ShadeConstants constants = _shade_constants;
do do
{ {
@ -530,32 +497,18 @@ namespace swrenderer
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
DrawTiltedSpanRGBACommand::DrawTiltedSpanRGBACommand(const SpanDrawerArgs &drawerargs, 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) void SWTruecolorDrawers::DrawTiltedSpan(const SpanDrawerArgs& drawerargs, 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)
{ {
_x1 = drawerargs.DestX1(); int _x1 = drawerargs.DestX1();
_x2 = drawerargs.DestX2(); int _x2 = drawerargs.DestX2();
_y = drawerargs.DestY(); int _y = drawerargs.DestY();
_dest = drawerargs.Viewport()->GetDest(_x1, _y); uint8_t* _dest = drawerargs.Viewport()->GetDest(_x1, _y);
_light = drawerargs.Light(); fixed_t _light = drawerargs.Light();
_shade_constants = drawerargs.ColormapConstants(); ShadeConstants _shade_constants = drawerargs.ColormapConstants();
_plane_sz = plane_sz; const uint32_t* _source = (const uint32_t*)drawerargs.TexturePixels();
_plane_su = plane_su; int _xbits = drawerargs.TextureWidthBits();
_plane_sv = plane_sv; int _ybits = drawerargs.TextureHeightBits();
_plane_shade = plane_shade; RenderViewport* viewport = drawerargs.Viewport();
_planeshade = planeshade;
_planelightfloat = planelightfloat;
_pviewx = pviewx;
_pviewy = pviewy;
_source = (const uint32_t*)drawerargs.TexturePixels();
_xbits = drawerargs.TextureWidthBits();
_ybits = drawerargs.TextureHeightBits();
viewport = drawerargs.Viewport();
}
void DrawTiltedSpanRGBACommand::Execute(DrawerThread *thread)
{
if (thread->line_skipped_by_thread(_y))
return;
//#define SPANSIZE 32 //#define SPANSIZE 32
//#define INVSPAN 0.03125f //#define INVSPAN 0.03125f
@ -660,20 +613,14 @@ namespace swrenderer
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
DrawColoredSpanRGBACommand::DrawColoredSpanRGBACommand(const SpanDrawerArgs &drawerargs) void SWTruecolorDrawers::DrawColoredSpan(const SpanDrawerArgs& drawerargs)
{ {
_y = drawerargs.DestY(); int _y = drawerargs.DestY();
_x1 = drawerargs.DestX1(); int _x1 = drawerargs.DestX1();
_x2 = drawerargs.DestX2(); int _x2 = drawerargs.DestX2();
_dest = drawerargs.Viewport()->GetDest(_x1, _y); uint8_t* RESTRICT _dest = drawerargs.Viewport()->GetDest(_x1, _y);
_light = drawerargs.Light(); fixed_t _light = drawerargs.Light();
_color = drawerargs.SolidColor(); int _color = drawerargs.SolidColor();
}
void DrawColoredSpanRGBACommand::Execute(DrawerThread *thread)
{
if (thread->line_skipped_by_thread(_y))
return;
int y = _y; int y = _y;
int x1 = _x1; int x1 = _x1;
@ -690,12 +637,13 @@ namespace swrenderer
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#if 0 #if 0
ApplySpecialColormapRGBACommand::ApplySpecialColormapRGBACommand(FSpecialColormap *colormap, DFrameBuffer *screen) #ifdef NO_SSE
void SWTruecolorDrawers::ApplySpecialColormap(FSpecialColormap* colormap, DFrameBuffer* screen)
{ {
buffer = screen->GetBuffer(); uint8_t* buffer = screen->GetBuffer();
pitch = screen->GetPitch(); int pitch = screen->GetPitch();
width = screen->GetWidth(); int width = screen->GetWidth();
height = screen->GetHeight(); int height = screen->GetHeight();
start_red = (int)(colormap->ColorizeStart[0] * 255); start_red = (int)(colormap->ColorizeStart[0] * 255);
start_green = (int)(colormap->ColorizeStart[1] * 255); start_green = (int)(colormap->ColorizeStart[1] * 255);
@ -703,13 +651,9 @@ namespace swrenderer
end_red = (int)(colormap->ColorizeEnd[0] * 255); end_red = (int)(colormap->ColorizeEnd[0] * 255);
end_green = (int)(colormap->ColorizeEnd[1] * 255); end_green = (int)(colormap->ColorizeEnd[1] * 255);
end_blue = (int)(colormap->ColorizeEnd[2] * 255); end_blue = (int)(colormap->ColorizeEnd[2] * 255);
}
#ifdef NO_SSE int y = 0;
void ApplySpecialColormapRGBACommand::Execute(DrawerThread *thread) int count = height;
{
int y = thread->skipped_by_thread(0);
int count = thread->count_for_thread(0, height);
while (count > 0) while (count > 0)
{ {
uint8_t *pixels = buffer + y * pitch * 4; uint8_t *pixels = buffer + y * pitch * 4;
@ -734,15 +678,27 @@ namespace swrenderer
pixels += 4; pixels += 4;
} }
y += thread->num_cores; y++;
count--; count--;
} }
} }
#else #else
void ApplySpecialColormapRGBACommand::Execute(DrawerThread *thread) void SWTruecolorDrawers::ApplySpecialColormap(FSpecialColormap* colormap, DFrameBuffer* screen)
{ {
int y = thread->skipped_by_thread(0); uint8_t* buffer = screen->GetBuffer();
int count = thread->count_for_thread(0, height); int pitch = screen->GetPitch();
int width = screen->GetWidth();
int height = screen->GetHeight();
start_red = (int)(colormap->ColorizeStart[0] * 255);
start_green = (int)(colormap->ColorizeStart[1] * 255);
start_blue = (int)(colormap->ColorizeStart[2] * 255);
end_red = (int)(colormap->ColorizeEnd[0] * 255);
end_green = (int)(colormap->ColorizeEnd[1] * 255);
end_blue = (int)(colormap->ColorizeEnd[2] * 255);
int y = 0;
int count = height;
__m128i gray_weight = _mm_set_epi16(256, 77, 143, 37, 256, 77, 143, 37); __m128i gray_weight = _mm_set_epi16(256, 77, 143, 37, 256, 77, 143, 37);
__m128i start_end = _mm_set_epi16(255, start_red, start_green, start_blue, 255, end_red, end_green, end_blue); __m128i start_end = _mm_set_epi16(255, start_red, start_green, start_blue, 255, end_red, end_green, end_blue);
while (count > 0) while (count > 0)
@ -836,7 +792,7 @@ namespace swrenderer
pixels += 4; pixels += 4;
} }
y += thread->num_cores; y++;
count--; count--;
} }
} }
@ -845,33 +801,21 @@ namespace swrenderer
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
DrawParticleColumnRGBACommand::DrawParticleColumnRGBACommand(uint32_t *dest, int dest_y, int pitch, int count, uint32_t fg, uint32_t alpha, uint32_t fracposx) void SWTruecolorDrawers::DrawParticleColumn(int x, int _dest_y, int _count, uint32_t _fg, uint32_t _alpha, uint32_t _fracposx)
{ {
_dest = dest; uint32_t* dest = (uint32_t*)thread->Viewport->GetDest(x, _dest_y);
_pitch = pitch; int pitch = thread->Viewport->RenderTarget->GetPitch();
_count = count;
_fg = fg;
_alpha = alpha;
_fracposx = fracposx;
_dest_y = dest_y;
}
void DrawParticleColumnRGBACommand::Execute(DrawerThread *thread) int count = _count;
{
int count = thread->count_for_thread(_dest_y, _count);
if (count <= 0) if (count <= 0)
return; return;
uint32_t *dest = thread->dest_for_thread(_dest_y, _pitch, _dest);
int pitch = _pitch * thread->num_cores;
int particle_texture_index = MIN<int>(gl_particles_style, NUM_PARTICLE_TEXTURES - 1); int particle_texture_index = MIN<int>(gl_particles_style, NUM_PARTICLE_TEXTURES - 1);
const uint32_t *source = &particle_texture[particle_texture_index][(_fracposx >> FRACBITS) * PARTICLE_TEXTURE_SIZE]; const uint32_t *source = &particle_texture[particle_texture_index][(_fracposx >> FRACBITS) * PARTICLE_TEXTURE_SIZE];
uint32_t particle_alpha = _alpha; uint32_t particle_alpha = _alpha;
uint32_t fracstep = PARTICLE_TEXTURE_SIZE * FRACUNIT / _count; uint32_t fracstep = PARTICLE_TEXTURE_SIZE * FRACUNIT / _count;
uint32_t fracpos = fracstep * thread->skipped_by_thread(_dest_y) + fracstep / 2; uint32_t fracpos = fracstep / 2;
fracstep *= thread->num_cores;
uint32_t fg_red = (_fg >> 16) & 0xff; uint32_t fg_red = (_fg >> 16) & 0xff;
uint32_t fg_green = (_fg >> 8) & 0xff; uint32_t fg_green = (_fg >> 8) & 0xff;
@ -898,37 +842,208 @@ namespace swrenderer
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
DrawVoxelBlocksRGBACommand::DrawVoxelBlocksRGBACommand(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount) : args(args), blocks(blocks), blockcount(blockcount) void SWTruecolorDrawers::DrawVoxelBlocks(const SpriteDrawerArgs& args, const VoxelBlock* blocks, int blockcount)
{
}
void DrawVoxelBlocksRGBACommand::Execute(DrawerThread *thread)
{ {
int pitch = args.Viewport()->RenderTarget->GetPitch(); int pitch = args.Viewport()->RenderTarget->GetPitch();
uint8_t *destorig = args.Viewport()->RenderTarget->GetPixels(); uint8_t *destorig = args.Viewport()->RenderTarget->GetPixels();
DrawSprite32Command drawer(args); SpriteDrawerArgs drawerargs = args;
drawer.args.dc_texturefracx = 0; drawerargs.dc_texturefracx = 0;
drawer.args.dc_source2 = 0; drawerargs.dc_source2 = 0;
for (int i = 0; i < blockcount; i++) for (int i = 0; i < blockcount; i++)
{ {
const VoxelBlock &block = blocks[i]; const VoxelBlock &block = blocks[i];
double v = block.vPos / (double)block.voxelsCount / FRACUNIT; double v = block.vPos / (double)block.voxelsCount / FRACUNIT;
double vstep = block.vStep / (double)block.voxelsCount / FRACUNIT; double vstep = block.vStep / (double)block.voxelsCount / FRACUNIT;
drawer.args.dc_texturefrac = (int)(v * (1 << 30)); drawerargs.dc_texturefrac = (int)(v * (1 << 30));
drawer.args.dc_iscale = (int)(vstep * (1 << 30)); drawerargs.dc_iscale = (int)(vstep * (1 << 30));
drawer.args.dc_source = block.voxels; drawerargs.dc_source = block.voxels;
drawer.args.dc_textureheight = block.voxelsCount; drawerargs.dc_textureheight = block.voxelsCount;
drawer.args.dc_count = block.height; drawerargs.dc_count = block.height;
drawer.args.dc_dest_y = block.y; drawerargs.dc_dest_y = block.y;
drawer.args.dc_dest = destorig + (block.x + block.y * pitch) * 4; drawerargs.dc_dest = destorig + (block.x + block.y * pitch) * 4;
for (int j = 0; j < block.width; j++) for (int j = 0; j < block.width; j++)
{ {
drawer.Execute(thread); DrawSprite32Command::DrawColumn(drawerargs);
drawer.args.dc_dest += 4; drawerargs.dc_dest += 4;
} }
} }
} }
/////////////////////////////////////////////////////////////////////////////
template<typename DrawerT>
void SWTruecolorDrawers::DrawWallColumns(const WallDrawerArgs& wallargs)
{
wallcolargs.wallargs = &wallargs;
bool haslights = r_dynlights && wallargs.lightlist;
if (haslights)
{
float dx = wallargs.WallC.tright.X - wallargs.WallC.tleft.X;
float dy = wallargs.WallC.tright.Y - wallargs.WallC.tleft.Y;
float length = sqrt(dx * dx + dy * dy);
wallcolargs.dc_normal.X = dy / length;
wallcolargs.dc_normal.Y = -dx / length;
wallcolargs.dc_normal.Z = 0.0f;
}
wallcolargs.SetTextureFracBits(wallargs.fracbits);
float curlight = wallargs.lightpos;
float lightstep = wallargs.lightstep;
int shade = wallargs.Shade();
if (wallargs.fixedlight)
{
curlight = wallargs.FixedLight();
lightstep = 0;
}
float upos = wallargs.texcoords.upos, ustepX = wallargs.texcoords.ustepX, ustepY = wallargs.texcoords.ustepY;
float vpos = wallargs.texcoords.vpos, vstepX = wallargs.texcoords.vstepX, vstepY = wallargs.texcoords.vstepY;
float wpos = wallargs.texcoords.wpos, wstepX = wallargs.texcoords.wstepX, wstepY = wallargs.texcoords.wstepY;
float startX = wallargs.texcoords.startX;
int x1 = wallargs.x1;
int x2 = wallargs.x2;
upos += ustepX * (x1 + 0.5f - startX);
vpos += vstepX * (x1 + 0.5f - startX);
wpos += wstepX * (x1 + 0.5f - startX);
float centerY = wallargs.CenterY;
centerY -= 0.5f;
auto uwal = wallargs.uwal;
auto dwal = wallargs.dwal;
for (int x = x1; x < x2; x++)
{
int y1 = uwal[x];
int y2 = dwal[x];
if (y2 > y1)
{
wallcolargs.SetLight(curlight, shade);
if (haslights)
SetLights(wallcolargs, x, y1, wallargs);
else
wallcolargs.dc_num_lights = 0;
float dy = (y1 - centerY);
float u = upos + ustepY * dy;
float v = vpos + vstepY * dy;
float w = wpos + wstepY * dy;
float scaleU = ustepX;
float scaleV = vstepY;
w = 1.0f / w;
u *= w;
v *= w;
scaleU *= w;
scaleV *= w;
uint32_t texelX = (uint32_t)(int64_t)((u - std::floor(u)) * 0x1'0000'0000LL);
uint32_t texelY = (uint32_t)(int64_t)((v - std::floor(v)) * 0x1'0000'0000LL);
uint32_t texelStepX = (uint32_t)(int64_t)(scaleU * 0x1'0000'0000LL);
uint32_t texelStepY = (uint32_t)(int64_t)(scaleV * 0x1'0000'0000LL);
DrawWallColumn32<DrawerT>(wallcolargs, x, y1, y2, texelX, texelY, texelStepX, texelStepY);
}
upos += ustepX;
vpos += vstepX;
wpos += wstepX;
curlight += lightstep;
}
if (r_modelscene)
{
for (int x = x1; x < x2; x++)
{
int y1 = uwal[x];
int y2 = dwal[x];
if (y2 > y1)
{
int count = y2 - y1;
float w1 = 1.0f / wallargs.WallC.sz1;
float w2 = 1.0f / wallargs.WallC.sz2;
float t = (x - wallargs.WallC.sx1 + 0.5f) / (wallargs.WallC.sx2 - wallargs.WallC.sx1);
float wcol = w1 * (1.0f - t) + w2 * t;
float zcol = 1.0f / wcol;
float zbufferdepth = 1.0f / (zcol / wallargs.FocalTangent);
wallcolargs.SetDest(x, y1);
wallcolargs.SetCount(count);
DrawDepthColumn(wallcolargs, zbufferdepth);
}
}
}
}
template<typename DrawerT>
void SWTruecolorDrawers::DrawWallColumn32(WallColumnDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepX, uint32_t texelStepY)
{
auto& wallargs = *drawerargs.wallargs;
int texwidth = wallargs.texwidth;
int texheight = wallargs.texheight;
double xmagnitude = fabs(static_cast<int32_t>(texelStepX) * (1.0 / 0x1'0000'0000LL));
double ymagnitude = fabs(static_cast<int32_t>(texelStepY) * (1.0 / 0x1'0000'0000LL));
double magnitude = MAX(ymagnitude, xmagnitude);
double min_lod = -1000.0;
double lod = MAX(log2(magnitude) + r_lod_bias, min_lod);
bool magnifying = lod < 0.0f;
int mipmap_offset = 0;
int mip_width = texwidth;
int mip_height = texheight;
if (wallargs.mipmapped && mip_width > 1 && mip_height > 1)
{
int level = (int)lod;
while (level > 0 && mip_width > 1 && mip_height > 1)
{
mipmap_offset += mip_width * mip_height;
level--;
mip_width = MAX(mip_width >> 1, 1);
mip_height = MAX(mip_height >> 1, 1);
}
}
const uint32_t* pixels = static_cast<const uint32_t*>(wallargs.texpixels) + mipmap_offset;
fixed_t xxoffset = (texelX >> 16) * mip_width;
const uint8_t* source;
const uint8_t* source2;
uint32_t texturefracx;
bool filter_nearest = (magnifying && !r_magfilter) || (!magnifying && !r_minfilter);
if (filter_nearest)
{
int tx = (xxoffset >> FRACBITS) % mip_width;
source = (uint8_t*)(pixels + tx * mip_height);
source2 = nullptr;
texturefracx = 0;
}
else
{
xxoffset -= FRACUNIT / 2;
int tx0 = (xxoffset >> FRACBITS) % mip_width;
if (tx0 < 0)
tx0 += mip_width;
int tx1 = (tx0 + 1) % mip_width;
source = (uint8_t*)(pixels + tx0 * mip_height);
source2 = (uint8_t*)(pixels + tx1 * mip_height);
texturefracx = (xxoffset >> (FRACBITS - 4)) & 15;
}
int count = y2 - y1;
drawerargs.SetDest(x, y1);
drawerargs.SetCount(count);
drawerargs.SetTexture(source, source2, mip_height);
drawerargs.SetTextureUPos(texturefracx);
drawerargs.SetTextureVPos(texelY);
drawerargs.SetTextureVStep(texelStepY);
DrawerT::DrawColumn(drawerargs);
}
} }

View file

@ -25,6 +25,7 @@
#include "r_draw.h" #include "r_draw.h"
#include "v_palette.h" #include "v_palette.h"
#include "r_thread.h" #include "r_thread.h"
#include "r_draw_pal.h"
#include "swrenderer/viewport/r_skydrawer.h" #include "swrenderer/viewport/r_skydrawer.h"
#include "swrenderer/viewport/r_spandrawer.h" #include "swrenderer/viewport/r_spandrawer.h"
#include "swrenderer/viewport/r_walldrawer.h" #include "swrenderer/viewport/r_walldrawer.h"
@ -70,125 +71,6 @@ namespace swrenderer
#define VECTORCALL #define VECTORCALL
#endif #endif
class DrawFuzzColumnRGBACommand : public DrawerCommand
{
int _x;
int _yl;
int _yh;
uint8_t * RESTRICT _destorg;
int _pitch;
int _fuzzpos;
int _fuzzviewheight;
public:
DrawFuzzColumnRGBACommand(const SpriteDrawerArgs &drawerargs);
void Execute(DrawerThread *thread) override;
};
class DrawScaledFuzzColumnRGBACommand : public DrawerCommand
{
int _x;
int _yl;
int _yh;
uint8_t * RESTRICT _destorg;
int _pitch;
int _fuzzpos;
int _fuzzviewheight;
public:
DrawScaledFuzzColumnRGBACommand(const SpriteDrawerArgs &drawerargs);
void Execute(DrawerThread *thread) override;
};
class FillSpanRGBACommand : public DrawerCommand
{
int _x1;
int _x2;
int _y;
uint8_t * RESTRICT _dest;
fixed_t _light;
int _color;
public:
FillSpanRGBACommand(const SpanDrawerArgs &drawerargs);
void Execute(DrawerThread *thread) override;
};
class DrawFogBoundaryLineRGBACommand : public DrawerCommand
{
int _y;
int _x;
int _x2;
uint8_t * RESTRICT _line;
fixed_t _light;
ShadeConstants _shade_constants;
public:
DrawFogBoundaryLineRGBACommand(const SpanDrawerArgs &drawerargs);
void Execute(DrawerThread *thread) override;
};
class DrawTiltedSpanRGBACommand : public DrawerCommand
{
int _x1;
int _x2;
int _y;
uint8_t * RESTRICT _dest;
fixed_t _light;
ShadeConstants _shade_constants;
FVector3 _plane_sz;
FVector3 _plane_su;
FVector3 _plane_sv;
bool _plane_shade;
int _planeshade;
float _planelightfloat;
fixed_t _pviewx;
fixed_t _pviewy;
int _xbits;
int _ybits;
const uint32_t * RESTRICT _source;
RenderViewport *viewport;
public:
DrawTiltedSpanRGBACommand(const SpanDrawerArgs &drawerargs, 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);
void Execute(DrawerThread *thread) override;
};
class DrawColoredSpanRGBACommand : public DrawerCommand
{
int _y;
int _x1;
int _x2;
uint8_t * RESTRICT _dest;
fixed_t _light;
int _color;
public:
DrawColoredSpanRGBACommand(const SpanDrawerArgs &drawerargs);
void Execute(DrawerThread *thread) override;
};
#if 0
class ApplySpecialColormapRGBACommand : public DrawerCommand
{
uint8_t *buffer;
int pitch;
int width;
int height;
int start_red;
int start_green;
int start_blue;
int end_red;
int end_green;
int end_blue;
public:
ApplySpecialColormapRGBACommand(FSpecialColormap *colormap, DFrameBuffer *screen);
void Execute(DrawerThread *thread) override;
};
#endif
template<typename CommandType, typename BlendMode> template<typename CommandType, typename BlendMode>
class DrawerBlendCommand : public CommandType class DrawerBlendCommand : public CommandType
{ {
@ -207,38 +89,6 @@ namespace swrenderer
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
class DrawParticleColumnRGBACommand : public DrawerCommand
{
public:
DrawParticleColumnRGBACommand(uint32_t *dest, int dest_y, int pitch, int count, uint32_t fg, uint32_t alpha, uint32_t fracposx);
void Execute(DrawerThread *thread) override;
private:
uint32_t *_dest;
int _dest_y;
int _pitch;
int _count;
uint32_t _fg;
uint32_t _alpha;
uint32_t _fracposx;
};
/////////////////////////////////////////////////////////////////////////////
class DrawVoxelBlocksRGBACommand : public DrawerCommand
{
public:
DrawVoxelBlocksRGBACommand(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount);
void Execute(DrawerThread *thread) override;
private:
SpriteDrawerArgs args;
const VoxelBlock *blocks;
int blockcount;
};
/////////////////////////////////////////////////////////////////////////////
class SWTruecolorDrawers : public SWPixelFormatDrawers class SWTruecolorDrawers : public SWPixelFormatDrawers
{ {
public: public:
@ -277,15 +127,19 @@ namespace swrenderer
void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override; void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override;
void DrawSpanAddClamp(const SpanDrawerArgs &args) override; void DrawSpanAddClamp(const SpanDrawerArgs &args) override;
void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override; void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override;
void FillSpan(const SpanDrawerArgs &args) override { Queue->Push<FillSpanRGBACommand>(args); } void FillSpan(const SpanDrawerArgs& args) override;
void DrawTiltedSpan(const SpanDrawerArgs& args, 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 DrawColoredSpan(const SpanDrawerArgs& args) override;
void DrawFogBoundaryLine(const SpanDrawerArgs& args) override;
void DrawParticleColumn(int x, int yl, int ycount, uint32_t fg, uint32_t alpha, uint32_t fracposx) override;
void DrawTiltedSpan(const SpanDrawerArgs &args, 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 DrawScaledFuzzColumn(const SpriteDrawerArgs& args);
{ void DrawUnscaledFuzzColumn(const SpriteDrawerArgs& args);
Queue->Push<DrawTiltedSpanRGBACommand>(args, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy);
}
void DrawColoredSpan(const SpanDrawerArgs &args) override { Queue->Push<DrawColoredSpanRGBACommand>(args); } template<typename DrawerT> void DrawWallColumns(const WallDrawerArgs& args);
void DrawFogBoundaryLine(const SpanDrawerArgs &args) override { Queue->Push<DrawFogBoundaryLineRGBACommand>(args); } template<typename DrawerT> void DrawWallColumn32(WallColumnDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepX, uint32_t texelStepY);
WallColumnDrawerArgs wallcolargs;
}; };
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View file

@ -27,16 +27,10 @@
namespace swrenderer namespace swrenderer
{ {
class DrawSkySingle32Command
class DrawSkySingle32Command : public DrawerCommand
{ {
protected:
SkyDrawerArgs args;
public: public:
DrawSkySingle32Command(const SkyDrawerArgs &args) : args(args) { } static void DrawColumn(const SkyDrawerArgs& args)
void Execute(DrawerThread *thread) override
{ {
uint32_t *dest = (uint32_t *)args.Dest(); uint32_t *dest = (uint32_t *)args.Dest();
int pitch = args.Viewport()->RenderTarget->GetPitch(); int pitch = args.Viewport()->RenderTarget->GetPitch();
@ -50,9 +44,7 @@ namespace swrenderer
uint32_t solid_bottom = args.SolidBottomColor(); uint32_t solid_bottom = args.SolidBottomColor();
bool fadeSky = args.FadeSky(); bool fadeSky = args.FadeSky();
int num_cores = thread->num_cores; int count = args.Count();
int skipped = thread->skipped_by_thread(args.DestY());
int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores;
// Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color: // Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color:
int start_fade = 2; // How fast it should fade out int start_fade = 2; // How fast it should fade out
@ -66,15 +58,8 @@ namespace swrenderer
start_fadebottom_y = clamp(start_fadebottom_y, 0, count); start_fadebottom_y = clamp(start_fadebottom_y, 0, count);
end_fadebottom_y = clamp(end_fadebottom_y, 0, count); end_fadebottom_y = clamp(end_fadebottom_y, 0, count);
dest = thread->dest_for_thread(args.DestY(), pitch, dest);
frac += fracstep * skipped;
fracstep *= num_cores;
pitch *= num_cores;
if (!fadeSky) if (!fadeSky)
{ {
int count = thread->count_for_thread(args.DestY(), args.Count());
for (int index = 0; index < count; index++) for (int index = 0; index < count; index++)
{ {
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
@ -89,7 +74,7 @@ namespace swrenderer
BgraColor solid_top_fill = solid_top; BgraColor solid_top_fill = solid_top;
BgraColor solid_bottom_fill = solid_bottom; BgraColor solid_bottom_fill = solid_bottom;
int index = skipped; int index = 0;
// Top solid color: // Top solid color:
while (index < start_fadetop_y) while (index < start_fadetop_y)
@ -97,7 +82,7 @@ namespace swrenderer
*dest = solid_top; *dest = solid_top;
dest += pitch; dest += pitch;
frac += fracstep; frac += fracstep;
index += num_cores; index++;
} }
// Top fade: // Top fade:
@ -117,7 +102,7 @@ namespace swrenderer
frac += fracstep; frac += fracstep;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
// Textured center: // Textured center:
@ -128,7 +113,7 @@ namespace swrenderer
frac += fracstep; frac += fracstep;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
// Fade bottom: // Fade bottom:
@ -148,7 +133,7 @@ namespace swrenderer
frac += fracstep; frac += fracstep;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
// Bottom solid color: // Bottom solid color:
@ -156,20 +141,15 @@ namespace swrenderer
{ {
*dest = solid_bottom; *dest = solid_bottom;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
} }
}; };
class DrawSkyDouble32Command : public DrawerCommand class DrawSkyDouble32Command
{ {
protected:
SkyDrawerArgs args;
public: public:
DrawSkyDouble32Command(const SkyDrawerArgs &args) : args(args) { } static void DrawColumn(const SkyDrawerArgs& args)
void Execute(DrawerThread *thread) override
{ {
uint32_t *dest = (uint32_t *)args.Dest(); uint32_t *dest = (uint32_t *)args.Dest();
int pitch = args.Viewport()->RenderTarget->GetPitch(); int pitch = args.Viewport()->RenderTarget->GetPitch();
@ -181,9 +161,7 @@ namespace swrenderer
int32_t frac = args.TextureVPos(); int32_t frac = args.TextureVPos();
int32_t fracstep = args.TextureVStep(); int32_t fracstep = args.TextureVStep();
int num_cores = thread->num_cores; int count = args.Count();
int skipped = thread->skipped_by_thread(args.DestY());
int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores;
uint32_t solid_top = args.SolidTopColor(); uint32_t solid_top = args.SolidTopColor();
uint32_t solid_bottom = args.SolidBottomColor(); uint32_t solid_bottom = args.SolidBottomColor();
@ -201,15 +179,8 @@ namespace swrenderer
start_fadebottom_y = clamp(start_fadebottom_y, 0, count); start_fadebottom_y = clamp(start_fadebottom_y, 0, count);
end_fadebottom_y = clamp(end_fadebottom_y, 0, count); end_fadebottom_y = clamp(end_fadebottom_y, 0, count);
dest = thread->dest_for_thread(args.DestY(), pitch, dest);
frac += fracstep * skipped;
fracstep *= num_cores;
pitch *= num_cores;
if (!fadeSky) if (!fadeSky)
{ {
count = thread->count_for_thread(args.DestY(), count);
for (int index = 0; index < count; index++) for (int index = 0; index < count; index++)
{ {
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
@ -231,7 +202,7 @@ namespace swrenderer
BgraColor solid_top_fill = solid_top; BgraColor solid_top_fill = solid_top;
BgraColor solid_bottom_fill = solid_bottom; BgraColor solid_bottom_fill = solid_bottom;
int index = skipped; int index = 0;
// Top solid color: // Top solid color:
while (index < start_fadetop_y) while (index < start_fadetop_y)
@ -239,7 +210,7 @@ namespace swrenderer
*dest = solid_top; *dest = solid_top;
dest += pitch; dest += pitch;
frac += fracstep; frac += fracstep;
index += num_cores; index++;
} }
// Top fade: // Top fade:
@ -262,7 +233,7 @@ namespace swrenderer
frac += fracstep; frac += fracstep;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
// Textured center: // Textured center:
@ -279,7 +250,7 @@ namespace swrenderer
frac += fracstep; frac += fracstep;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
// Fade bottom: // Fade bottom:
@ -302,7 +273,7 @@ namespace swrenderer
frac += fracstep; frac += fracstep;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
// Bottom solid color: // Bottom solid color:
@ -310,7 +281,7 @@ namespace swrenderer
{ {
*dest = solid_bottom; *dest = solid_bottom;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
} }
}; };

View file

@ -27,15 +27,10 @@
namespace swrenderer namespace swrenderer
{ {
class DrawSkySingle32Command : public DrawerCommand class DrawSkySingle32Command
{ {
protected:
SkyDrawerArgs args;
public: public:
DrawSkySingle32Command(const SkyDrawerArgs &args) : args(args) { } static void DrawColumn(const SkyDrawerArgs& args)
void Execute(DrawerThread *thread) override
{ {
uint32_t *dest = (uint32_t *)args.Dest(); uint32_t *dest = (uint32_t *)args.Dest();
int pitch = args.Viewport()->RenderTarget->GetPitch(); int pitch = args.Viewport()->RenderTarget->GetPitch();
@ -49,9 +44,7 @@ namespace swrenderer
uint32_t solid_bottom = args.SolidBottomColor(); uint32_t solid_bottom = args.SolidBottomColor();
bool fadeSky = args.FadeSky(); bool fadeSky = args.FadeSky();
int num_cores = thread->num_cores; int count = args.Count();
int skipped = thread->skipped_by_thread(args.DestY());
int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores;
// Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color: // Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color:
int start_fade = 2; // How fast it should fade out int start_fade = 2; // How fast it should fade out
@ -65,15 +58,8 @@ namespace swrenderer
start_fadebottom_y = clamp(start_fadebottom_y, 0, count); start_fadebottom_y = clamp(start_fadebottom_y, 0, count);
end_fadebottom_y = clamp(end_fadebottom_y, 0, count); end_fadebottom_y = clamp(end_fadebottom_y, 0, count);
dest = thread->dest_for_thread(args.DestY(), pitch, dest);
frac += fracstep * skipped;
fracstep *= num_cores;
pitch *= num_cores;
if (!fadeSky) if (!fadeSky)
{ {
int count = thread->count_for_thread(args.DestY(), args.Count());
for (int index = 0; index < count; index++) for (int index = 0; index < count; index++)
{ {
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
@ -88,7 +74,7 @@ namespace swrenderer
__m128i solid_top_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_top), _mm_setzero_si128()); __m128i solid_top_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_top), _mm_setzero_si128());
__m128i solid_bottom_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_bottom), _mm_setzero_si128()); __m128i solid_bottom_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_bottom), _mm_setzero_si128());
int index = skipped; int index = 0;
// Top solid color: // Top solid color:
while (index < start_fadetop_y) while (index < start_fadetop_y)
@ -96,7 +82,7 @@ namespace swrenderer
*dest = solid_top; *dest = solid_top;
dest += pitch; dest += pitch;
frac += fracstep; frac += fracstep;
index += num_cores; index++;
} }
// Top fade: // Top fade:
@ -114,7 +100,7 @@ namespace swrenderer
frac += fracstep; frac += fracstep;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
// Textured center: // Textured center:
@ -125,7 +111,7 @@ namespace swrenderer
frac += fracstep; frac += fracstep;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
// Fade bottom: // Fade bottom:
@ -143,7 +129,7 @@ namespace swrenderer
frac += fracstep; frac += fracstep;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
// Bottom solid color: // Bottom solid color:
@ -151,20 +137,15 @@ namespace swrenderer
{ {
*dest = solid_bottom; *dest = solid_bottom;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
} }
}; };
class DrawSkyDouble32Command : public DrawerCommand class DrawSkyDouble32Command
{ {
protected:
SkyDrawerArgs args;
public: public:
DrawSkyDouble32Command(const SkyDrawerArgs &args) : args(args) { } static void DrawColumn(const SkyDrawerArgs& args)
void Execute(DrawerThread *thread) override
{ {
uint32_t *dest = (uint32_t *)args.Dest(); uint32_t *dest = (uint32_t *)args.Dest();
int pitch = args.Viewport()->RenderTarget->GetPitch(); int pitch = args.Viewport()->RenderTarget->GetPitch();
@ -176,35 +157,14 @@ namespace swrenderer
int32_t frac = args.TextureVPos(); int32_t frac = args.TextureVPos();
int32_t fracstep = args.TextureVStep(); int32_t fracstep = args.TextureVStep();
int num_cores = thread->num_cores; int count = args.Count();
int skipped = thread->skipped_by_thread(args.DestY());
int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores;
uint32_t solid_top = args.SolidTopColor(); uint32_t solid_top = args.SolidTopColor();
uint32_t solid_bottom = args.SolidBottomColor(); uint32_t solid_bottom = args.SolidBottomColor();
bool fadeSky = args.FadeSky(); bool fadeSky = args.FadeSky();
// Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color:
int start_fade = 2; // How fast it should fade out
int fade_length = (1 << (24 - start_fade));
int start_fadetop_y = (-frac) / fracstep;
int end_fadetop_y = (fade_length - frac) / fracstep;
int start_fadebottom_y = ((2 << 24) - fade_length - frac) / fracstep;
int end_fadebottom_y = ((2 << 24) - frac) / fracstep;
start_fadetop_y = clamp(start_fadetop_y, 0, count);
end_fadetop_y = clamp(end_fadetop_y, 0, count);
start_fadebottom_y = clamp(start_fadebottom_y, 0, count);
end_fadebottom_y = clamp(end_fadebottom_y, 0, count);
dest = thread->dest_for_thread(args.DestY(), pitch, dest);
frac += fracstep * skipped;
fracstep *= num_cores;
pitch *= num_cores;
if (!fadeSky) if (!fadeSky)
{ {
count = thread->count_for_thread(args.DestY(), count);
for (int index = 0; index < count; index++) for (int index = 0; index < count; index++)
{ {
uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS;
@ -223,10 +183,22 @@ namespace swrenderer
return; return;
} }
// Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color:
int start_fade = 2; // How fast it should fade out
int fade_length = (1 << (24 - start_fade));
int start_fadetop_y = (-frac) / fracstep;
int end_fadetop_y = (fade_length - frac) / fracstep;
int start_fadebottom_y = ((2 << 24) - fade_length - frac) / fracstep;
int end_fadebottom_y = ((2 << 24) - frac) / fracstep;
start_fadetop_y = clamp(start_fadetop_y, 0, count);
end_fadetop_y = clamp(end_fadetop_y, 0, count);
start_fadebottom_y = clamp(start_fadebottom_y, 0, count);
end_fadebottom_y = clamp(end_fadebottom_y, 0, count);
__m128i solid_top_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_top), _mm_setzero_si128()); __m128i solid_top_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_top), _mm_setzero_si128());
__m128i solid_bottom_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_bottom), _mm_setzero_si128()); __m128i solid_bottom_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_bottom), _mm_setzero_si128());
int index = skipped; int index = 0;
// Top solid color: // Top solid color:
while (index < start_fadetop_y) while (index < start_fadetop_y)
@ -234,7 +206,7 @@ namespace swrenderer
*dest = solid_top; *dest = solid_top;
dest += pitch; dest += pitch;
frac += fracstep; frac += fracstep;
index += num_cores; index++;
} }
// Top fade: // Top fade:
@ -257,7 +229,7 @@ namespace swrenderer
frac += fracstep; frac += fracstep;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
// Textured center: // Textured center:
@ -274,7 +246,7 @@ namespace swrenderer
frac += fracstep; frac += fracstep;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
// Fade bottom: // Fade bottom:
@ -297,7 +269,7 @@ namespace swrenderer
frac += fracstep; frac += fracstep;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
// Bottom solid color: // Bottom solid color:
@ -305,7 +277,7 @@ namespace swrenderer
{ {
*dest = solid_bottom; *dest = solid_bottom;
dest += pitch; dest += pitch;
index += num_cores; index++;
} }
} }
}; };

View file

@ -51,14 +51,9 @@ namespace swrenderer
} }
template<typename BlendT> template<typename BlendT>
class DrawSpan32T : public DrawerCommand class DrawSpan32T
{ {
protected:
SpanDrawerArgs args;
public: public:
DrawSpan32T(const SpanDrawerArgs &drawerargs) : args(drawerargs) { }
struct TextureData struct TextureData
{ {
uint32_t width; uint32_t width;
@ -72,12 +67,10 @@ namespace swrenderer
const uint32_t *source; const uint32_t *source;
}; };
void Execute(DrawerThread *thread) override static void DrawColumn(const SpanDrawerArgs& args)
{ {
using namespace DrawSpan32TModes; using namespace DrawSpan32TModes;
if (thread->line_skipped_by_thread(args.DestY())) return;
TextureData texdata; TextureData texdata;
texdata.width = args.TextureWidth(); texdata.width = args.TextureWidth();
texdata.height = args.TextureHeight(); texdata.height = args.TextureHeight();
@ -119,16 +112,16 @@ namespace swrenderer
if (is_nearest_filter) if (is_nearest_filter)
{ {
if (is_64x64) if (is_64x64)
Loop<SimpleShade, NearestFilter, TextureSize64x64>(thread, texdata, shade_constants); Loop<SimpleShade, NearestFilter, TextureSize64x64>(args, texdata, shade_constants);
else else
Loop<SimpleShade, NearestFilter, TextureSizeAny>(thread, texdata, shade_constants); Loop<SimpleShade, NearestFilter, TextureSizeAny>(args, texdata, shade_constants);
} }
else else
{ {
if (is_64x64) if (is_64x64)
Loop<SimpleShade, LinearFilter, TextureSize64x64>(thread, texdata, shade_constants); Loop<SimpleShade, LinearFilter, TextureSize64x64>(args, texdata, shade_constants);
else else
Loop<SimpleShade, LinearFilter, TextureSizeAny>(thread, texdata, shade_constants); Loop<SimpleShade, LinearFilter, TextureSizeAny>(args, texdata, shade_constants);
} }
} }
else else
@ -136,22 +129,22 @@ namespace swrenderer
if (is_nearest_filter) if (is_nearest_filter)
{ {
if (is_64x64) if (is_64x64)
Loop<AdvancedShade, NearestFilter, TextureSize64x64>(thread, texdata, shade_constants); Loop<AdvancedShade, NearestFilter, TextureSize64x64>(args, texdata, shade_constants);
else else
Loop<AdvancedShade, NearestFilter, TextureSizeAny>(thread, texdata, shade_constants); Loop<AdvancedShade, NearestFilter, TextureSizeAny>(args, texdata, shade_constants);
} }
else else
{ {
if (is_64x64) if (is_64x64)
Loop<AdvancedShade, LinearFilter, TextureSize64x64>(thread, texdata, shade_constants); Loop<AdvancedShade, LinearFilter, TextureSize64x64>(args, texdata, shade_constants);
else else
Loop<AdvancedShade, LinearFilter, TextureSizeAny>(thread, texdata, shade_constants); Loop<AdvancedShade, LinearFilter, TextureSizeAny>(args, texdata, shade_constants);
} }
} }
} }
template<typename ShadeModeT, typename FilterModeT, typename TextureSizeT> template<typename ShadeModeT, typename FilterModeT, typename TextureSizeT>
FORCEINLINE void Loop(DrawerThread *thread, TextureData texdata, ShadeConstants shade_constants) FORCEINLINE static void Loop(const SpanDrawerArgs& args, TextureData texdata, ShadeConstants shade_constants)
{ {
using namespace DrawSpan32TModes; using namespace DrawSpan32TModes;
@ -229,7 +222,7 @@ namespace swrenderer
} }
template<typename FilterModeT, typename TextureSizeT> template<typename FilterModeT, typename TextureSizeT>
FORCEINLINE uint32_t Sample(uint32_t width, uint32_t height, uint32_t xone, uint32_t yone, uint32_t xstep, uint32_t ystep, uint32_t xfrac, uint32_t yfrac, const uint32_t *source) FORCEINLINE static uint32_t Sample(uint32_t width, uint32_t height, uint32_t xone, uint32_t yone, uint32_t xstep, uint32_t ystep, uint32_t xfrac, uint32_t yfrac, const uint32_t *source)
{ {
using namespace DrawSpan32TModes; using namespace DrawSpan32TModes;
@ -291,7 +284,7 @@ namespace swrenderer
} }
template<typename ShadeModeT> template<typename ShadeModeT>
FORCEINLINE BgraColor Shade(BgraColor fgcolor, uint32_t light, uint32_t desaturate, uint32_t inv_desaturate, BgraColor shade_fade, BgraColor shade_light, const DrawerLight *lights, int num_lights, float viewpos_x) FORCEINLINE static BgraColor Shade(BgraColor fgcolor, uint32_t light, uint32_t desaturate, uint32_t inv_desaturate, BgraColor shade_fade, BgraColor shade_light, const DrawerLight *lights, int num_lights, float viewpos_x)
{ {
using namespace DrawSpan32TModes; using namespace DrawSpan32TModes;
@ -313,7 +306,7 @@ namespace swrenderer
return AddLights(material, fgcolor, lights, num_lights, viewpos_x); return AddLights(material, fgcolor, lights, num_lights, viewpos_x);
} }
FORCEINLINE BgraColor AddLights(BgraColor material, BgraColor fgcolor, const DrawerLight *lights, int num_lights, float viewpos_x) FORCEINLINE static BgraColor AddLights(BgraColor material, BgraColor fgcolor, const DrawerLight *lights, int num_lights, float viewpos_x)
{ {
using namespace DrawSpan32TModes; using namespace DrawSpan32TModes;
@ -365,7 +358,7 @@ namespace swrenderer
return fgcolor; return fgcolor;
} }
FORCEINLINE BgraColor Blend(BgraColor fgcolor, BgraColor bgcolor, uint32_t srcalpha, uint32_t destalpha, unsigned int ifgcolor) FORCEINLINE static BgraColor Blend(BgraColor fgcolor, BgraColor bgcolor, uint32_t srcalpha, uint32_t destalpha, unsigned int ifgcolor)
{ {
using namespace DrawSpan32TModes; using namespace DrawSpan32TModes;

View file

@ -51,14 +51,9 @@ namespace swrenderer
} }
template<typename BlendT> template<typename BlendT>
class DrawSpan32T : public DrawerCommand class DrawSpan32T
{ {
protected:
SpanDrawerArgs args;
public: public:
DrawSpan32T(const SpanDrawerArgs &drawerargs) : args(drawerargs) { }
struct TextureData struct TextureData
{ {
uint32_t width; uint32_t width;
@ -72,12 +67,10 @@ namespace swrenderer
const uint32_t *source; const uint32_t *source;
}; };
void Execute(DrawerThread *thread) override static void DrawColumn(const SpanDrawerArgs& args)
{ {
using namespace DrawSpan32TModes; using namespace DrawSpan32TModes;
if (thread->line_skipped_by_thread(args.DestY())) return;
TextureData texdata; TextureData texdata;
texdata.width = args.TextureWidth(); texdata.width = args.TextureWidth();
texdata.height = args.TextureHeight(); texdata.height = args.TextureHeight();
@ -119,16 +112,16 @@ namespace swrenderer
if (is_nearest_filter) if (is_nearest_filter)
{ {
if (is_64x64) if (is_64x64)
Loop<SimpleShade, NearestFilter, TextureSize64x64>(thread, texdata, shade_constants); Loop<SimpleShade, NearestFilter, TextureSize64x64>(args, texdata, shade_constants);
else else
Loop<SimpleShade, NearestFilter, TextureSizeAny>(thread, texdata, shade_constants); Loop<SimpleShade, NearestFilter, TextureSizeAny>(args, texdata, shade_constants);
} }
else else
{ {
if (is_64x64) if (is_64x64)
Loop<SimpleShade, LinearFilter, TextureSize64x64>(thread, texdata, shade_constants); Loop<SimpleShade, LinearFilter, TextureSize64x64>(args, texdata, shade_constants);
else else
Loop<SimpleShade, LinearFilter, TextureSizeAny>(thread, texdata, shade_constants); Loop<SimpleShade, LinearFilter, TextureSizeAny>(args, texdata, shade_constants);
} }
} }
else else
@ -136,22 +129,22 @@ namespace swrenderer
if (is_nearest_filter) if (is_nearest_filter)
{ {
if (is_64x64) if (is_64x64)
Loop<AdvancedShade, NearestFilter, TextureSize64x64>(thread, texdata, shade_constants); Loop<AdvancedShade, NearestFilter, TextureSize64x64>(args, texdata, shade_constants);
else else
Loop<AdvancedShade, NearestFilter, TextureSizeAny>(thread, texdata, shade_constants); Loop<AdvancedShade, NearestFilter, TextureSizeAny>(args, texdata, shade_constants);
} }
else else
{ {
if (is_64x64) if (is_64x64)
Loop<AdvancedShade, LinearFilter, TextureSize64x64>(thread, texdata, shade_constants); Loop<AdvancedShade, LinearFilter, TextureSize64x64>(args, texdata, shade_constants);
else else
Loop<AdvancedShade, LinearFilter, TextureSizeAny>(thread, texdata, shade_constants); Loop<AdvancedShade, LinearFilter, TextureSizeAny>(args, texdata, shade_constants);
} }
} }
} }
template<typename ShadeModeT, typename FilterModeT, typename TextureSizeT> template<typename ShadeModeT, typename FilterModeT, typename TextureSizeT>
FORCEINLINE void VECTORCALL Loop(DrawerThread *thread, TextureData texdata, ShadeConstants shade_constants) FORCEINLINE static void VECTORCALL Loop(const SpanDrawerArgs& args, TextureData texdata, ShadeConstants shade_constants)
{ {
using namespace DrawSpan32TModes; using namespace DrawSpan32TModes;
@ -263,7 +256,7 @@ namespace swrenderer
} }
template<typename FilterModeT, typename TextureSizeT> template<typename FilterModeT, typename TextureSizeT>
FORCEINLINE unsigned int VECTORCALL Sample(uint32_t width, uint32_t height, uint32_t xone, uint32_t yone, uint32_t xstep, uint32_t ystep, uint32_t xfrac, uint32_t yfrac, const uint32_t *source) FORCEINLINE static unsigned int VECTORCALL Sample(uint32_t width, uint32_t height, uint32_t xone, uint32_t yone, uint32_t xstep, uint32_t ystep, uint32_t xfrac, uint32_t yfrac, const uint32_t *source)
{ {
using namespace DrawSpan32TModes; using namespace DrawSpan32TModes;
@ -325,7 +318,7 @@ namespace swrenderer
} }
template<typename ShadeModeT> template<typename ShadeModeT>
FORCEINLINE __m128i VECTORCALL Shade(__m128i fgcolor, __m128i mlight, unsigned int ifgcolor0, unsigned int ifgcolor1, int desaturate, __m128i inv_desaturate, __m128i shade_fade, __m128i shade_light, const DrawerLight *lights, int num_lights, __m128 viewpos_x) FORCEINLINE static __m128i VECTORCALL Shade(__m128i fgcolor, __m128i mlight, unsigned int ifgcolor0, unsigned int ifgcolor1, int desaturate, __m128i inv_desaturate, __m128i shade_fade, __m128i shade_light, const DrawerLight *lights, int num_lights, __m128 viewpos_x)
{ {
using namespace DrawSpan32TModes; using namespace DrawSpan32TModes;
@ -357,7 +350,7 @@ namespace swrenderer
return AddLights(material, fgcolor, lights, num_lights, viewpos_x); return AddLights(material, fgcolor, lights, num_lights, viewpos_x);
} }
FORCEINLINE __m128i VECTORCALL AddLights(__m128i material, __m128i fgcolor, const DrawerLight *lights, int num_lights, __m128 viewpos_x) FORCEINLINE static __m128i VECTORCALL AddLights(__m128i material, __m128i fgcolor, const DrawerLight *lights, int num_lights, __m128 viewpos_x)
{ {
using namespace DrawSpan32TModes; using namespace DrawSpan32TModes;
@ -406,7 +399,7 @@ namespace swrenderer
return fgcolor; return fgcolor;
} }
FORCEINLINE __m128i VECTORCALL Blend(__m128i fgcolor, __m128i bgcolor, uint32_t srcalpha, uint32_t destalpha, unsigned int ifgcolor0, unsigned int ifgcolor1) FORCEINLINE static __m128i VECTORCALL Blend(__m128i fgcolor, __m128i bgcolor, uint32_t srcalpha, uint32_t destalpha, unsigned int ifgcolor0, unsigned int ifgcolor1)
{ {
using namespace DrawSpan32TModes; using namespace DrawSpan32TModes;

View file

@ -54,14 +54,10 @@ namespace swrenderer
} }
template<typename BlendT, typename SamplerT> template<typename BlendT, typename SamplerT>
class DrawSprite32T : public DrawerCommand class DrawSprite32T
{ {
public: public:
SpriteDrawerArgs args; static void DrawColumn(const SpriteDrawerArgs& args)
DrawSprite32T(const SpriteDrawerArgs &drawerargs) : args(drawerargs) { }
void Execute(DrawerThread *thread) override
{ {
using namespace DrawSprite32TModes; using namespace DrawSprite32TModes;
@ -74,33 +70,33 @@ namespace swrenderer
if (shade_constants.simple_shade) if (shade_constants.simple_shade)
{ {
if (is_nearest_filter) if (is_nearest_filter)
Loop<SimpleShade, NearestFilter>(thread, shade_constants); Loop<SimpleShade, NearestFilter>(args, shade_constants);
else else
Loop<SimpleShade, LinearFilter>(thread, shade_constants); Loop<SimpleShade, LinearFilter>(args, shade_constants);
} }
else else
{ {
if (is_nearest_filter) if (is_nearest_filter)
Loop<AdvancedShade, NearestFilter>(thread, shade_constants); Loop<AdvancedShade, NearestFilter>(args, shade_constants);
else else
Loop<AdvancedShade, LinearFilter>(thread, shade_constants); Loop<AdvancedShade, LinearFilter>(args, shade_constants);
} }
} }
else // no linear filtering for translated, shaded or fill else // no linear filtering for translated, shaded or fill
{ {
if (shade_constants.simple_shade) if (shade_constants.simple_shade)
{ {
Loop<SimpleShade, NearestFilter>(thread, shade_constants); Loop<SimpleShade, NearestFilter>(args, shade_constants);
} }
else else
{ {
Loop<AdvancedShade, NearestFilter>(thread, shade_constants); Loop<AdvancedShade, NearestFilter>(args, shade_constants);
} }
} }
} }
template<typename ShadeModeT, typename FilterModeT> template<typename ShadeModeT, typename FilterModeT>
FORCEINLINE void Loop(DrawerThread *thread, ShadeConstants shade_constants) FORCEINLINE static void Loop(const SpriteDrawerArgs& args, ShadeConstants shade_constants)
{ {
using namespace DrawSprite32TModes; using namespace DrawSprite32TModes;
@ -171,6 +167,8 @@ namespace swrenderer
} }
int count = args.Count(); int count = args.Count();
if (count <= 0) return;
int pitch = args.Viewport()->RenderTarget->GetPitch(); int pitch = args.Viewport()->RenderTarget->GetPitch();
uint32_t fracstep = args.TextureVStep(); uint32_t fracstep = args.TextureVStep();
uint32_t frac = args.TextureVPos(); uint32_t frac = args.TextureVPos();
@ -178,13 +176,6 @@ namespace swrenderer
uint32_t *dest = (uint32_t*)args.Dest(); uint32_t *dest = (uint32_t*)args.Dest();
int dest_y = args.DestY(); int dest_y = args.DestY();
count = thread->count_for_thread(dest_y, count);
if (count <= 0) return;
frac += thread->skipped_by_thread(dest_y) * fracstep;
dest = thread->dest_for_thread(dest_y, pitch, dest);
fracstep *= thread->num_cores;
pitch *= thread->num_cores;
if (FilterModeT::Mode == (int)FilterModes::Linear) if (FilterModeT::Mode == (int)FilterModes::Linear)
{ {
frac -= one / 2; frac -= one / 2;
@ -220,7 +211,7 @@ namespace swrenderer
} }
template<typename FilterModeT> template<typename FilterModeT>
FORCEINLINE BgraColor Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, const uint32_t *translation, int textureheight, uint32_t one, uint32_t texturefracx, uint32_t color, uint32_t srccolor) FORCEINLINE static BgraColor Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, const uint32_t *translation, int textureheight, uint32_t one, uint32_t texturefracx, uint32_t color, uint32_t srccolor)
{ {
using namespace DrawSprite32TModes; using namespace DrawSprite32TModes;
@ -269,7 +260,7 @@ namespace swrenderer
} }
} }
FORCEINLINE uint32_t SampleShade(uint32_t frac, const uint32_t *source, const uint8_t *colormap) FORCEINLINE static uint32_t SampleShade(uint32_t frac, const uint32_t *source, const uint8_t *colormap)
{ {
using namespace DrawSprite32TModes; using namespace DrawSprite32TModes;
@ -286,7 +277,7 @@ namespace swrenderer
} }
template<typename ShadeModeT> template<typename ShadeModeT>
FORCEINLINE BgraColor Shade(BgraColor fgcolor, BgraColor mlight, uint32_t desaturate, uint32_t inv_desaturate, BgraColor shade_fade, BgraColor shade_light, BgraColor lightcontrib) FORCEINLINE static BgraColor Shade(BgraColor fgcolor, BgraColor mlight, uint32_t desaturate, uint32_t inv_desaturate, BgraColor shade_fade, BgraColor shade_light, BgraColor lightcontrib)
{ {
using namespace DrawSprite32TModes; using namespace DrawSprite32TModes;
@ -316,7 +307,7 @@ namespace swrenderer
} }
} }
FORCEINLINE BgraColor Blend(BgraColor fgcolor, BgraColor bgcolor, uint32_t ifgcolor, uint32_t ifgshade, uint32_t srcalpha, uint32_t destalpha) FORCEINLINE static BgraColor Blend(BgraColor fgcolor, BgraColor bgcolor, uint32_t ifgcolor, uint32_t ifgshade, uint32_t srcalpha, uint32_t destalpha)
{ {
using namespace DrawSprite32TModes; using namespace DrawSprite32TModes;

View file

@ -54,14 +54,10 @@ namespace swrenderer
} }
template<typename BlendT, typename SamplerT> template<typename BlendT, typename SamplerT>
class DrawSprite32T : public DrawerCommand class DrawSprite32T
{ {
public: public:
SpriteDrawerArgs args; static void DrawColumn(const SpriteDrawerArgs& args)
DrawSprite32T(const SpriteDrawerArgs &drawerargs) : args(drawerargs) { }
void Execute(DrawerThread *thread) override
{ {
using namespace DrawSprite32TModes; using namespace DrawSprite32TModes;
@ -74,33 +70,33 @@ namespace swrenderer
if (shade_constants.simple_shade) if (shade_constants.simple_shade)
{ {
if (is_nearest_filter) if (is_nearest_filter)
Loop<SimpleShade, NearestFilter>(thread, shade_constants); Loop<SimpleShade, NearestFilter>(args, shade_constants);
else else
Loop<SimpleShade, LinearFilter>(thread, shade_constants); Loop<SimpleShade, LinearFilter>(args, shade_constants);
} }
else else
{ {
if (is_nearest_filter) if (is_nearest_filter)
Loop<AdvancedShade, NearestFilter>(thread, shade_constants); Loop<AdvancedShade, NearestFilter>(args, shade_constants);
else else
Loop<AdvancedShade, LinearFilter>(thread, shade_constants); Loop<AdvancedShade, LinearFilter>(args, shade_constants);
} }
} }
else // no linear filtering for translated, shaded or fill else // no linear filtering for translated, shaded or fill
{ {
if (shade_constants.simple_shade) if (shade_constants.simple_shade)
{ {
Loop<SimpleShade, NearestFilter>(thread, shade_constants); Loop<SimpleShade, NearestFilter>(args, shade_constants);
} }
else else
{ {
Loop<AdvancedShade, NearestFilter>(thread, shade_constants); Loop<AdvancedShade, NearestFilter>(args, shade_constants);
} }
} }
} }
template<typename ShadeModeT, typename FilterModeT> template<typename ShadeModeT, typename FilterModeT>
FORCEINLINE void VECTORCALL Loop(DrawerThread *thread, ShadeConstants shade_constants) FORCEINLINE static void VECTORCALL Loop(const SpriteDrawerArgs& args, ShadeConstants shade_constants)
{ {
using namespace DrawSprite32TModes; using namespace DrawSprite32TModes;
@ -162,6 +158,7 @@ namespace swrenderer
} }
int count = args.Count(); int count = args.Count();
if (count <= 0) return;
int pitch = args.Viewport()->RenderTarget->GetPitch(); int pitch = args.Viewport()->RenderTarget->GetPitch();
uint32_t fracstep = args.TextureVStep(); uint32_t fracstep = args.TextureVStep();
uint32_t frac = args.TextureVPos(); uint32_t frac = args.TextureVPos();
@ -169,13 +166,6 @@ namespace swrenderer
uint32_t *dest = (uint32_t*)args.Dest(); uint32_t *dest = (uint32_t*)args.Dest();
int dest_y = args.DestY(); int dest_y = args.DestY();
count = thread->count_for_thread(dest_y, count);
if (count <= 0) return;
frac += thread->skipped_by_thread(dest_y) * fracstep;
dest = thread->dest_for_thread(dest_y, pitch, dest);
fracstep *= thread->num_cores;
pitch *= thread->num_cores;
if (FilterModeT::Mode == (int)FilterModes::Linear) if (FilterModeT::Mode == (int)FilterModes::Linear)
{ {
frac -= one / 2; frac -= one / 2;
@ -255,7 +245,7 @@ namespace swrenderer
} }
template<typename FilterModeT> template<typename FilterModeT>
FORCEINLINE unsigned int VECTORCALL Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, const uint32_t *translation, int textureheight, uint32_t one, uint32_t texturefracx, uint32_t color, uint32_t srccolor) FORCEINLINE static unsigned int VECTORCALL Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, const uint32_t *translation, int textureheight, uint32_t one, uint32_t texturefracx, uint32_t color, uint32_t srccolor)
{ {
using namespace DrawSprite32TModes; using namespace DrawSprite32TModes;
@ -304,7 +294,7 @@ namespace swrenderer
} }
} }
FORCEINLINE unsigned int VECTORCALL SampleShade(uint32_t frac, const uint32_t *source, const uint8_t *colormap) FORCEINLINE static unsigned int VECTORCALL SampleShade(uint32_t frac, const uint32_t *source, const uint8_t *colormap)
{ {
using namespace DrawSprite32TModes; using namespace DrawSprite32TModes;
@ -321,7 +311,7 @@ namespace swrenderer
} }
template<typename ShadeModeT> template<typename ShadeModeT>
FORCEINLINE __m128i VECTORCALL Shade(__m128i fgcolor, __m128i mlight, unsigned int ifgcolor0, unsigned int ifgcolor1, int desaturate, __m128i inv_desaturate, __m128i shade_fade, __m128i shade_light, __m128i lightcontrib) FORCEINLINE static __m128i VECTORCALL Shade(__m128i fgcolor, __m128i mlight, unsigned int ifgcolor0, unsigned int ifgcolor1, int desaturate, __m128i inv_desaturate, __m128i shade_fade, __m128i shade_light, __m128i lightcontrib)
{ {
using namespace DrawSprite32TModes; using namespace DrawSprite32TModes;
@ -360,7 +350,7 @@ namespace swrenderer
} }
} }
FORCEINLINE __m128i VECTORCALL Blend(__m128i fgcolor, __m128i bgcolor, unsigned int ifgcolor0, unsigned int ifgcolor1, unsigned int ifgshade0, unsigned int ifgshade1, uint32_t srcalpha, uint32_t destalpha) FORCEINLINE static __m128i VECTORCALL Blend(__m128i fgcolor, __m128i bgcolor, unsigned int ifgcolor0, unsigned int ifgcolor1, unsigned int ifgshade0, unsigned int ifgshade1, uint32_t srcalpha, uint32_t destalpha)
{ {
using namespace DrawSprite32TModes; using namespace DrawSprite32TModes;

View file

@ -47,12 +47,10 @@ namespace swrenderer
} }
template<typename BlendT> template<typename BlendT>
class DrawWall32T : public DrawWallCommand class DrawWall32T
{ {
public: public:
DrawWall32T(const WallDrawerArgs &drawerargs) : DrawWallCommand(drawerargs) { } static void DrawColumn(const WallColumnDrawerArgs& args)
void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override
{ {
using namespace DrawWall32TModes; using namespace DrawWall32TModes;
@ -62,24 +60,27 @@ namespace swrenderer
if (shade_constants.simple_shade) if (shade_constants.simple_shade)
{ {
if (is_nearest_filter) if (is_nearest_filter)
Loop<SimpleShade, NearestFilter>(thread, args, shade_constants); Loop<SimpleShade, NearestFilter>(args, shade_constants);
else else
Loop<SimpleShade, LinearFilter>(thread, args, shade_constants); Loop<SimpleShade, LinearFilter>(args, shade_constants);
} }
else else
{ {
if (is_nearest_filter) if (is_nearest_filter)
Loop<AdvancedShade, NearestFilter>(thread, args, shade_constants); Loop<AdvancedShade, NearestFilter>(args, shade_constants);
else else
Loop<AdvancedShade, LinearFilter>(thread, args, shade_constants); Loop<AdvancedShade, LinearFilter>(args, shade_constants);
} }
} }
template<typename ShadeModeT, typename FilterModeT> template<typename ShadeModeT, typename FilterModeT>
FORCEINLINE void Loop(DrawerThread *thread, const WallColumnDrawerArgs& args, ShadeConstants shade_constants) FORCEINLINE static void Loop(const WallColumnDrawerArgs& args, ShadeConstants shade_constants)
{ {
using namespace DrawWall32TModes; using namespace DrawWall32TModes;
int count = args.Count();
if (count <= 0) return;
const uint32_t *source = (const uint32_t*)args.TexturePixels(); const uint32_t *source = (const uint32_t*)args.TexturePixels();
const uint32_t *source2 = (const uint32_t*)args.TexturePixels2(); const uint32_t *source2 = (const uint32_t*)args.TexturePixels2();
int textureheight = args.TextureHeight(); int textureheight = args.TextureHeight();
@ -115,7 +116,6 @@ namespace swrenderer
desaturate = 0; desaturate = 0;
} }
int count = args.Count();
int pitch = args.Viewport()->RenderTarget->GetPitch(); int pitch = args.Viewport()->RenderTarget->GetPitch();
uint32_t fracstep = args.TextureVStep(); uint32_t fracstep = args.TextureVStep();
uint32_t frac = args.TextureVPos(); uint32_t frac = args.TextureVPos();
@ -125,15 +125,8 @@ namespace swrenderer
auto lights = args.dc_lights; auto lights = args.dc_lights;
auto num_lights = args.dc_num_lights; auto num_lights = args.dc_num_lights;
float viewpos_z = args.dc_viewpos.Z + args.dc_viewpos_step.Z * thread->skipped_by_thread(dest_y); float viewpos_z = args.dc_viewpos.Z;
float step_viewpos_z = args.dc_viewpos_step.Z * thread->num_cores; float step_viewpos_z = args.dc_viewpos_step.Z;
count = thread->count_for_thread(dest_y, count);
if (count <= 0) return;
frac += thread->skipped_by_thread(dest_y) * fracstep;
dest = thread->dest_for_thread(dest_y, pitch, dest);
fracstep *= thread->num_cores;
pitch *= thread->num_cores;
if (FilterModeT::Mode == (int)FilterModes::Linear) if (FilterModeT::Mode == (int)FilterModes::Linear)
{ {
@ -167,7 +160,7 @@ namespace swrenderer
} }
template<typename FilterModeT> template<typename FilterModeT>
FORCEINLINE BgraColor Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, int textureheight, uint32_t one, uint32_t texturefracx) FORCEINLINE static BgraColor Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, int textureheight, uint32_t one, uint32_t texturefracx)
{ {
using namespace DrawWall32TModes; using namespace DrawWall32TModes;
@ -203,7 +196,7 @@ namespace swrenderer
} }
template<typename ShadeModeT> template<typename ShadeModeT>
FORCEINLINE BgraColor Shade(BgraColor fgcolor, uint32_t light, uint32_t desaturate, uint32_t inv_desaturate, BgraColor shade_fade, BgraColor shade_light, const DrawerLight *lights, int num_lights, float viewpos_z) FORCEINLINE static BgraColor Shade(BgraColor fgcolor, uint32_t light, uint32_t desaturate, uint32_t inv_desaturate, BgraColor shade_fade, BgraColor shade_light, const DrawerLight *lights, int num_lights, float viewpos_z)
{ {
using namespace DrawWall32TModes; using namespace DrawWall32TModes;
@ -225,7 +218,7 @@ namespace swrenderer
return AddLights(material, fgcolor, lights, num_lights, viewpos_z); return AddLights(material, fgcolor, lights, num_lights, viewpos_z);
} }
FORCEINLINE BgraColor AddLights(BgraColor material, BgraColor fgcolor, const DrawerLight *lights, int num_lights, float viewpos_z) FORCEINLINE static BgraColor AddLights(BgraColor material, BgraColor fgcolor, const DrawerLight *lights, int num_lights, float viewpos_z)
{ {
using namespace DrawWall32TModes; using namespace DrawWall32TModes;
@ -277,7 +270,7 @@ namespace swrenderer
return fgcolor; return fgcolor;
} }
FORCEINLINE BgraColor Blend(BgraColor fgcolor, BgraColor bgcolor, unsigned int ifgcolor, uint32_t srcalpha, uint32_t destalpha) FORCEINLINE static BgraColor Blend(BgraColor fgcolor, BgraColor bgcolor, unsigned int ifgcolor, uint32_t srcalpha, uint32_t destalpha)
{ {
using namespace DrawWall32TModes; using namespace DrawWall32TModes;

View file

@ -47,12 +47,10 @@ namespace swrenderer
} }
template<typename BlendT> template<typename BlendT>
class DrawWall32T : public DrawWallCommand class DrawWall32T
{ {
public: public:
DrawWall32T(const WallDrawerArgs &drawerargs) : DrawWallCommand(drawerargs) { } static void DrawColumn(const WallColumnDrawerArgs& args)
void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override
{ {
using namespace DrawWall32TModes; using namespace DrawWall32TModes;
@ -62,21 +60,21 @@ namespace swrenderer
if (shade_constants.simple_shade) if (shade_constants.simple_shade)
{ {
if (is_nearest_filter) if (is_nearest_filter)
Loop<SimpleShade, NearestFilter>(thread, args, shade_constants); Loop<SimpleShade, NearestFilter>(args, shade_constants);
else else
Loop<SimpleShade, LinearFilter>(thread, args, shade_constants); Loop<SimpleShade, LinearFilter>(args, shade_constants);
} }
else else
{ {
if (is_nearest_filter) if (is_nearest_filter)
Loop<AdvancedShade, NearestFilter>(thread, args, shade_constants); Loop<AdvancedShade, NearestFilter>(args, shade_constants);
else else
Loop<AdvancedShade, LinearFilter>(thread, args, shade_constants); Loop<AdvancedShade, LinearFilter>(args, shade_constants);
} }
} }
template<typename ShadeModeT, typename FilterModeT> template<typename ShadeModeT, typename FilterModeT>
FORCEINLINE void VECTORCALL Loop(DrawerThread *thread, const WallColumnDrawerArgs& args, ShadeConstants shade_constants) FORCEINLINE static void VECTORCALL Loop(const WallColumnDrawerArgs& args, ShadeConstants shade_constants)
{ {
using namespace DrawWall32TModes; using namespace DrawWall32TModes;
@ -110,6 +108,8 @@ namespace swrenderer
} }
int count = args.Count(); int count = args.Count();
if (count <= 0) return;
int pitch = args.Viewport()->RenderTarget->GetPitch(); int pitch = args.Viewport()->RenderTarget->GetPitch();
uint32_t fracstep = args.TextureVStep(); uint32_t fracstep = args.TextureVStep();
uint32_t frac = args.TextureVPos(); uint32_t frac = args.TextureVPos();
@ -119,18 +119,11 @@ namespace swrenderer
auto lights = args.dc_lights; auto lights = args.dc_lights;
auto num_lights = args.dc_num_lights; auto num_lights = args.dc_num_lights;
float vpz = args.dc_viewpos.Z + args.dc_viewpos_step.Z * thread->skipped_by_thread(dest_y); float vpz = args.dc_viewpos.Z;
float stepvpz = args.dc_viewpos_step.Z * thread->num_cores; float stepvpz = args.dc_viewpos_step.Z;
__m128 viewpos_z = _mm_setr_ps(vpz, vpz + stepvpz, 0.0f, 0.0f); __m128 viewpos_z = _mm_setr_ps(vpz, vpz + stepvpz, 0.0f, 0.0f);
__m128 step_viewpos_z = _mm_set1_ps(stepvpz * 2.0f); __m128 step_viewpos_z = _mm_set1_ps(stepvpz * 2.0f);
count = thread->count_for_thread(dest_y, count);
if (count <= 0) return;
frac += thread->skipped_by_thread(dest_y) * fracstep;
dest = thread->dest_for_thread(dest_y, pitch, dest);
fracstep *= thread->num_cores;
pitch *= thread->num_cores;
if (FilterModeT::Mode == (int)FilterModes::Linear) if (FilterModeT::Mode == (int)FilterModes::Linear)
{ {
frac -= one / 2; frac -= one / 2;
@ -203,7 +196,7 @@ namespace swrenderer
} }
template<typename FilterModeT> template<typename FilterModeT>
FORCEINLINE unsigned int VECTORCALL Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, int textureheight, uint32_t one, uint32_t texturefracx) FORCEINLINE static unsigned int VECTORCALL Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, int textureheight, uint32_t one, uint32_t texturefracx)
{ {
using namespace DrawWall32TModes; using namespace DrawWall32TModes;
@ -239,7 +232,7 @@ namespace swrenderer
} }
template<typename ShadeModeT> template<typename ShadeModeT>
FORCEINLINE __m128i VECTORCALL Shade(__m128i fgcolor, __m128i mlight, unsigned int ifgcolor0, unsigned int ifgcolor1, int desaturate, __m128i inv_desaturate, __m128i shade_fade, __m128i shade_light, const DrawerLight *lights, int num_lights, __m128 viewpos_z) FORCEINLINE static __m128i VECTORCALL Shade(__m128i fgcolor, __m128i mlight, unsigned int ifgcolor0, unsigned int ifgcolor1, int desaturate, __m128i inv_desaturate, __m128i shade_fade, __m128i shade_light, const DrawerLight *lights, int num_lights, __m128 viewpos_z)
{ {
using namespace DrawWall32TModes; using namespace DrawWall32TModes;
@ -271,7 +264,7 @@ namespace swrenderer
return AddLights(material, fgcolor, lights, num_lights, viewpos_z); return AddLights(material, fgcolor, lights, num_lights, viewpos_z);
} }
FORCEINLINE __m128i VECTORCALL AddLights(__m128i material, __m128i fgcolor, const DrawerLight *lights, int num_lights, __m128 viewpos_z) FORCEINLINE static __m128i VECTORCALL AddLights(__m128i material, __m128i fgcolor, const DrawerLight *lights, int num_lights, __m128 viewpos_z)
{ {
using namespace DrawWall32TModes; using namespace DrawWall32TModes;
@ -320,7 +313,7 @@ namespace swrenderer
return fgcolor; return fgcolor;
} }
FORCEINLINE __m128i VECTORCALL Blend(__m128i fgcolor, __m128i bgcolor, unsigned int ifgcolor0, unsigned int ifgcolor1, uint32_t srcalpha, uint32_t destalpha) FORCEINLINE static __m128i VECTORCALL Blend(__m128i fgcolor, __m128i bgcolor, unsigned int ifgcolor0, unsigned int ifgcolor1, uint32_t srcalpha, uint32_t destalpha)
{ {
using namespace DrawWall32TModes; using namespace DrawWall32TModes;

View file

@ -81,8 +81,6 @@ namespace swrenderer
mLight.SetColormap(lightsector, curline); mLight.SetColormap(lightsector, curline);
mLight.SetLightLeft(Thread, WallC); mLight.SetLightLeft(Thread, WallC);
Thread->PrepareTexture(pic, DefaultRenderStyle()); // Get correct render style? Shaded won't get here.
CameraLight* cameraLight = CameraLight::Instance(); CameraLight* cameraLight = CameraLight::Instance();
if (cameraLight->FixedColormap() || cameraLight->FixedLightLevel() >= 0 || !(lightsector->e && lightsector->e->XFloor.lightlist.Size())) if (cameraLight->FixedColormap() || cameraLight->FixedLightLevel() >= 0 || !(lightsector->e && lightsector->e->XFloor.lightlist.Size()))
{ {

View file

@ -59,8 +59,6 @@ CVAR(Bool, r_linearsky, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
EXTERN_CVAR(Int, r_skymode) EXTERN_CVAR(Int, r_skymode)
EXTERN_CVAR(Bool, cl_oldfreelooklimit) EXTERN_CVAR(Bool, cl_oldfreelooklimit)
std::pair<PalEntry, PalEntry>& R_GetSkyCapColor(FGameTexture* tex);
namespace swrenderer namespace swrenderer
{ {
static FSoftwareTexture *GetSWTex(FTextureID texid, bool allownull = true) static FSoftwareTexture *GetSWTex(FTextureID texid, bool allownull = true)
@ -216,9 +214,6 @@ namespace swrenderer
drawerargs.SetStyle(); drawerargs.SetStyle();
Thread->PrepareTexture(frontskytex, DefaultRenderStyle());
Thread->PrepareTexture(backskytex, DefaultRenderStyle());
DrawSky(pl); DrawSky(pl);
} }
@ -255,6 +250,8 @@ namespace swrenderer
angle1 = UMulScale16(ang, frontcyl) + frontpos; angle1 = UMulScale16(ang, frontcyl) + frontpos;
angle2 = UMulScale16(ang, backcyl) + backpos; angle2 = UMulScale16(ang, backcyl) + backpos;
auto skycapcolors = Thread->GetSkyCapColor(frontskytex);
drawerargs.SetFrontTexture(Thread, frontskytex, angle1); drawerargs.SetFrontTexture(Thread, frontskytex, angle1);
drawerargs.SetBackTexture(Thread, backskytex, angle2); drawerargs.SetBackTexture(Thread, backskytex, angle2);
drawerargs.SetTextureVStep(uv_step); drawerargs.SetTextureVStep(uv_step);
@ -262,9 +259,8 @@ namespace swrenderer
drawerargs.SetDest(viewport, start_x, y1); drawerargs.SetDest(viewport, start_x, y1);
drawerargs.SetCount(y2 - y1); drawerargs.SetCount(y2 - y1);
drawerargs.SetFadeSky(r_skymode == 2 && !(Level->flags & LEVEL_FORCETILEDSKY)); drawerargs.SetFadeSky(r_skymode == 2 && !(Level->flags & LEVEL_FORCETILEDSKY));
auto& col = R_GetSkyCapColor(frontskytex->GetTexture()); drawerargs.SetSolidTop(skycapcolors.first);
drawerargs.SetSolidTop(col.first); drawerargs.SetSolidBottom(skycapcolors.second);
drawerargs.SetSolidBottom(col.second);
if (!backskytex) if (!backskytex)
drawerargs.DrawSingleSkyColumn(Thread); drawerargs.DrawSingleSkyColumn(Thread);

View file

@ -53,6 +53,9 @@
#include "swrenderer/drawers/r_draw_pal.h" #include "swrenderer/drawers/r_draw_pal.h"
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "r_memory.h" #include "r_memory.h"
#include "common/rendering/polyrenderer/drawers/poly_thread.h"
std::pair<PalEntry, PalEntry>& R_GetSkyCapColor(FGameTexture* tex);
namespace swrenderer namespace swrenderer
{ {
@ -63,7 +66,6 @@ namespace swrenderer
FrameMemory.reset(new RenderMemory()); FrameMemory.reset(new RenderMemory());
Viewport.reset(new RenderViewport()); Viewport.reset(new RenderViewport());
Light.reset(new LightVisibility()); Light.reset(new LightVisibility());
DrawQueue.reset(new DrawerCommandQueue(FrameMemory.get()));
OpaquePass.reset(new RenderOpaquePass(this)); OpaquePass.reset(new RenderOpaquePass(this));
TranslucentPass.reset(new RenderTranslucentPass(this)); TranslucentPass.reset(new RenderTranslucentPass(this));
SpriteList.reset(new VisibleSpriteList()); SpriteList.reset(new VisibleSpriteList());
@ -73,8 +75,9 @@ namespace swrenderer
PlaneList.reset(new VisiblePlaneList(this)); PlaneList.reset(new VisiblePlaneList(this));
DrawSegments.reset(new DrawSegmentList(this)); DrawSegments.reset(new DrawSegmentList(this));
ClipSegments.reset(new RenderClipSegment()); ClipSegments.reset(new RenderClipSegment());
tc_drawers.reset(new SWTruecolorDrawers(DrawQueue)); Poly.reset(new PolyTriangleThreadData(0, 1, 0, 1, 0, screen->GetHeight()));
pal_drawers.reset(new SWPalDrawers(DrawQueue)); tc_drawers.reset(new SWTruecolorDrawers(this));
pal_drawers.reset(new SWPalDrawers(this));
} }
RenderThread::~RenderThread() RenderThread::~RenderThread()
@ -89,33 +92,13 @@ namespace swrenderer
return pal_drawers.get(); return pal_drawers.get();
} }
static std::mutex loadmutex; std::mutex loadmutex;
void RenderThread::PrepareTexture(FSoftwareTexture *texture, FRenderStyle style) {
if (texture == nullptr)
return;
// Textures may not have loaded/refreshed yet. The shared code doing
// this is not thread safe. By calling GetPixels in a mutex lock we
// make sure that only one thread is loading a texture at any given
// time.
//
// It is critical that this function is called before any direct
// calls to GetPixels for this to work.
std::pair<PalEntry, PalEntry> RenderThread::GetSkyCapColor(FSoftwareTexture* tex)
{
std::unique_lock<std::mutex> lock(loadmutex); std::unique_lock<std::mutex> lock(loadmutex);
std::pair<PalEntry, PalEntry> colors = R_GetSkyCapColor(tex->GetTexture());
const FSoftwareTextureSpan *spans; return colors;
if (Viewport->RenderTarget->IsBgra())
{
texture->GetPixelsBgra();
texture->GetColumnBgra(0, &spans);
}
else
{
bool alpha = !!(style.Flags & STYLEF_RedIsAlpha);
texture->GetPixels(alpha);
texture->GetColumn(alpha, 0, &spans);
}
} }
static std::mutex polyobjmutex; static std::mutex polyobjmutex;

View file

@ -25,9 +25,8 @@
#include <memory> #include <memory>
#include <thread> #include <thread>
class DrawerCommandQueue;
typedef std::shared_ptr<DrawerCommandQueue> DrawerCommandQueuePtr;
class RenderMemory; class RenderMemory;
class PolyTriangleThreadData;
struct FDynamicLight; struct FDynamicLight;
EXTERN_CVAR(Bool, r_models); EXTERN_CVAR(Bool, r_models);
@ -51,6 +50,7 @@ namespace swrenderer
class SWPixelFormatDrawers; class SWPixelFormatDrawers;
class SWTruecolorDrawers; class SWTruecolorDrawers;
class SWPalDrawers; class SWPalDrawers;
class WallColumnDrawerArgs;
class RenderThread class RenderThread
{ {
@ -75,7 +75,7 @@ namespace swrenderer
std::unique_ptr<RenderClipSegment> ClipSegments; std::unique_ptr<RenderClipSegment> ClipSegments;
std::unique_ptr<RenderViewport> Viewport; std::unique_ptr<RenderViewport> Viewport;
std::unique_ptr<LightVisibility> Light; std::unique_ptr<LightVisibility> Light;
DrawerCommandQueuePtr DrawQueue; std::unique_ptr<PolyTriangleThreadData> Poly;
TArray<FDynamicLight*> AddedLightsArray; TArray<FDynamicLight*> AddedLightsArray;
@ -87,11 +87,11 @@ namespace swrenderer
SWPixelFormatDrawers *Drawers(RenderViewport *viewport); SWPixelFormatDrawers *Drawers(RenderViewport *viewport);
// Make sure texture can accessed safely
void PrepareTexture(FSoftwareTexture *texture, FRenderStyle style);
// Setup poly object in a threadsafe manner // Setup poly object in a threadsafe manner
void PreparePolyObject(subsector_t *sub); void PreparePolyObject(subsector_t *sub);
// Retrieve skycap color in a threadsafe way
std::pair<PalEntry, PalEntry> GetSkyCapColor(FSoftwareTexture* tex);
private: private:
std::unique_ptr<SWTruecolorDrawers> tc_drawers; std::unique_ptr<SWTruecolorDrawers> tc_drawers;

View file

@ -66,14 +66,14 @@ void PeekThreadedErrorPane();
EXTERN_CVAR(Int, r_clearbuffer) EXTERN_CVAR(Int, r_clearbuffer)
EXTERN_CVAR(Int, r_debug_draw) EXTERN_CVAR(Int, r_debug_draw)
CVAR(Int, r_scene_multithreaded, 0, 0); CVAR(Int, r_scene_multithreaded, 1, 0);
CVAR(Bool, r_models, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR(Bool, r_models, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
bool r_modelscene = false; bool r_modelscene = false;
namespace swrenderer namespace swrenderer
{ {
cycle_t WallCycles, PlaneCycles, MaskedCycles, DrawerWaitCycles; cycle_t WallCycles, PlaneCycles, MaskedCycles;
RenderScene::RenderScene() RenderScene::RenderScene()
{ {
@ -131,7 +131,6 @@ namespace swrenderer
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
dest[i] = bgracolor.d; dest[i] = bgracolor.d;
} }
DrawerThreads::ResetDebugDrawPos();
} }
RenderActorView(player->mo, true, false); RenderActorView(player->mo, true, false);
@ -141,11 +140,8 @@ namespace swrenderer
auto copyqueue = std::make_shared<DrawerCommandQueue>(MainThread()->FrameMemory.get()); auto copyqueue = std::make_shared<DrawerCommandQueue>(MainThread()->FrameMemory.get());
copyqueue->Push<MemcpyCommand>(videobuffer, bufferpitch, target->GetPixels(), target->GetWidth(), target->GetHeight(), target->GetPitch(), target->IsBgra() ? 4 : 1); copyqueue->Push<MemcpyCommand>(videobuffer, bufferpitch, target->GetPixels(), target->GetWidth(), target->GetHeight(), target->GetPitch(), target->IsBgra() ? 4 : 1);
DrawerThreads::Execute(copyqueue); DrawerThreads::Execute(copyqueue);
DrawerThreads::WaitForWorkers();
} }
DrawerWaitCycles.Clock();
DrawerThreads::WaitForWorkers();
DrawerWaitCycles.Unclock();
} }
void RenderScene::RenderActorView(AActor *actor, bool renderPlayerSprites, bool dontmaplines) void RenderScene::RenderActorView(AActor *actor, bool renderPlayerSprites, bool dontmaplines)
@ -153,7 +149,6 @@ namespace swrenderer
WallCycles.Reset(); WallCycles.Reset();
PlaneCycles.Reset(); PlaneCycles.Reset();
MaskedCycles.Reset(); MaskedCycles.Reset();
DrawerWaitCycles.Reset();
R_SetupFrame(MainThread()->Viewport->viewpoint, MainThread()->Viewport->viewwindow, actor); R_SetupFrame(MainThread()->Viewport->viewpoint, MainThread()->Viewport->viewwindow, actor);
@ -194,14 +189,7 @@ namespace swrenderer
void RenderScene::RenderPSprites() void RenderScene::RenderPSprites()
{ {
// Player sprites needs to be rendered after all the slices because they may be hardware accelerated.
// If they are not hardware accelerated the drawers must run after all sliced drawers finished.
DrawerWaitCycles.Clock();
DrawerThreads::WaitForWorkers();
DrawerWaitCycles.Unclock();
MainThread()->DrawQueue->Clear();
MainThread()->PlayerSprites->Render(); MainThread()->PlayerSprites->Render();
DrawerThreads::Execute(MainThread()->DrawQueue);
} }
void RenderScene::RenderThreadSlices() void RenderScene::RenderThreadSlices()
@ -231,6 +219,7 @@ namespace swrenderer
Threads[i]->X2 = viewwidth * (i + 1) / numThreads; Threads[i]->X2 = viewwidth * (i + 1) / numThreads;
} }
run_id++; run_id++;
FSoftwareTexture::CurrentUpdate = run_id;
start_lock.unlock(); start_lock.unlock();
// Notify threads to run // Notify threads to run
@ -267,7 +256,6 @@ namespace swrenderer
void RenderScene::RenderThreadSlice(RenderThread *thread) void RenderScene::RenderThreadSlice(RenderThread *thread)
{ {
thread->DrawQueue->Clear();
thread->FrameMemory->Clear(); thread->FrameMemory->Clear();
thread->Clip3D->Cleanup(); thread->Clip3D->Cleanup();
thread->Clip3D->ResetClip(); // reset clips (floor/ceiling) thread->Clip3D->ResetClip(); // reset clips (floor/ceiling)
@ -306,7 +294,37 @@ namespace swrenderer
thread->TranslucentPass->Render(); thread->TranslucentPass->Render();
} }
DrawerThreads::Execute(thread->DrawQueue); #if 0 // shows the render slice edges
if (thread->Viewport->RenderTarget->IsBgra())
{
uint32_t* left = (uint32_t*)thread->Viewport->GetDest(thread->X1, 0);
uint32_t* right = (uint32_t*)thread->Viewport->GetDest(thread->X2 - 1, 0);
int pitch = thread->Viewport->RenderTarget->GetPitch();
uint32_t c = MAKEARGB(255, 0, 0, 0);
for (int i = 0; i < viewheight; i++)
{
*left = c;
*right = c;
left += pitch;
right += pitch;
}
}
else
{
uint8_t* left = (uint8_t*)thread->Viewport->GetDest(thread->X1, 0);
uint8_t* right = (uint8_t*)thread->Viewport->GetDest(thread->X2 - 1, 0);
int pitch = thread->Viewport->RenderTarget->GetPitch();
int r = 0, g = 0, b = 0;
uint8_t c = RGB32k.RGB[(r >> 3)][(g >> 3)][(b >> 3)];
for (int i = 0; i < viewheight; i++)
{
*left = c;
*right = c;
left += pitch;
right += pitch;
}
}
#endif
} }
void RenderScene::StartThreads(size_t numThreads) void RenderScene::StartThreads(size_t numThreads)
@ -390,9 +408,6 @@ namespace swrenderer
// Render: // Render:
RenderActorView(actor, false, dontmaplines); RenderActorView(actor, false, dontmaplines);
DrawerWaitCycles.Clock();
DrawerThreads::WaitForWorkers();
DrawerWaitCycles.Unclock();
viewport->RenderingToCanvas = false; viewport->RenderingToCanvas = false;
@ -418,12 +433,12 @@ namespace swrenderer
ADD_STAT(fps) ADD_STAT(fps)
{ {
FString out; FString out;
out.Format("frame=%04.1f ms walls=%04.1f ms planes=%04.1f ms masked=%04.1f ms drawers=%04.1f ms", out.Format("frame=%04.1f ms walls=%04.1f ms planes=%04.1f ms masked=%04.1f ms",
FrameCycles.TimeMS(), WallCycles.TimeMS(), PlaneCycles.TimeMS(), MaskedCycles.TimeMS(), DrawerWaitCycles.TimeMS()); FrameCycles.TimeMS(), WallCycles.TimeMS(), PlaneCycles.TimeMS(), MaskedCycles.TimeMS());
return out; return out;
} }
static double f_acc, w_acc, p_acc, m_acc, drawer_acc; static double f_acc, w_acc, p_acc, m_acc;
static int acc_c; static int acc_c;
ADD_STAT(fps_accumulated) ADD_STAT(fps_accumulated)
@ -432,11 +447,10 @@ namespace swrenderer
w_acc += WallCycles.TimeMS(); w_acc += WallCycles.TimeMS();
p_acc += PlaneCycles.TimeMS(); p_acc += PlaneCycles.TimeMS();
m_acc += MaskedCycles.TimeMS(); m_acc += MaskedCycles.TimeMS();
drawer_acc += DrawerWaitCycles.TimeMS();
acc_c++; acc_c++;
FString out; FString out;
out.Format("frame=%04.1f ms walls=%04.1f ms planes=%04.1f ms masked=%04.1f ms drawers=%04.1f ms %d counts", out.Format("frame=%04.1f ms walls=%04.1f ms planes=%04.1f ms masked=%04.1f ms %d counts",
f_acc / acc_c, w_acc / acc_c, p_acc / acc_c, m_acc / acc_c, drawer_acc / acc_c, acc_c); f_acc / acc_c, w_acc / acc_c, p_acc / acc_c, m_acc / acc_c, acc_c);
Printf(PRINT_LOG, "%s\n", out.GetChars()); Printf(PRINT_LOG, "%s\n", out.GetChars());
return out; return out;
} }

View file

@ -39,7 +39,7 @@
#include "m_alloc.h" #include "m_alloc.h"
#include "imagehelpers.h" #include "imagehelpers.h"
#include "texturemanager.h" #include "texturemanager.h"
#include <mutex>
inline EUpscaleFlags scaleFlagFromUseType(ETextureType useType) inline EUpscaleFlags scaleFlagFromUseType(ETextureType useType)
{ {
@ -119,7 +119,7 @@ void FSoftwareTexture::CalcBitSize ()
// //
//========================================================================== //==========================================================================
const uint8_t *FSoftwareTexture::GetPixels(int style) const uint8_t *FSoftwareTexture::GetPixelsLocked(int style)
{ {
if (Pixels.Size() == 0 || CheckModified(style)) if (Pixels.Size() == 0 || CheckModified(style))
{ {
@ -158,13 +158,7 @@ const uint8_t *FSoftwareTexture::GetPixels(int style)
return Pixels.Data(); return Pixels.Data();
} }
//========================================================================== const uint32_t *FSoftwareTexture::GetPixelsBgraLocked()
//
//
//
//==========================================================================
const uint32_t *FSoftwareTexture::GetPixelsBgra()
{ {
if (PixelsBgra.Size() == 0 || CheckModified(2)) if (PixelsBgra.Size() == 0 || CheckModified(2))
{ {
@ -197,60 +191,31 @@ const uint32_t *FSoftwareTexture::GetPixelsBgra()
// //
//========================================================================== //==========================================================================
const uint8_t *FSoftwareTexture::GetColumn(int index, unsigned int column, const FSoftwareTextureSpan **spans_out) int FSoftwareTexture::CurrentUpdate = 0;
namespace swrenderer { extern std::mutex loadmutex; }
void FSoftwareTexture::UpdatePixels(int index)
{ {
auto Pixeldata = GetPixels(index); std::unique_lock<std::mutex> lock(swrenderer::loadmutex);
if ((unsigned)column >= (unsigned)GetPhysicalWidth()) if (Unlockeddata[index].LastUpdate != CurrentUpdate)
{ {
if (WidthMask + 1 == GetPhysicalWidth()) if (index != 2)
{ {
column &= WidthMask; const uint8_t* Pixeldata = GetPixelsLocked(index);
if (Spandata[index] == nullptr)
Spandata[index] = CreateSpans(Pixeldata);
Unlockeddata[index].Pixels = Pixeldata;
Unlockeddata[index].LastUpdate = CurrentUpdate;
} }
else else
{ {
column %= GetPhysicalWidth(); const uint32_t* Pixeldata = GetPixelsBgraLocked();
if (Spandata[index] == nullptr)
Spandata[index] = CreateSpans(Pixeldata);
Unlockeddata[index].Pixels = Pixeldata;
Unlockeddata[index].LastUpdate = CurrentUpdate;
} }
} }
if (spans_out != nullptr)
{
if (Spandata[index] == nullptr)
{
Spandata[index] = CreateSpans(Pixeldata);
}
*spans_out = Spandata[index][column];
}
return Pixeldata + column * GetPhysicalHeight();
}
//==========================================================================
//
//
//
//==========================================================================
const uint32_t *FSoftwareTexture::GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out)
{
auto Pixeldata = GetPixelsBgra();
if ((unsigned)column >= (unsigned)GetPhysicalWidth())
{
if (WidthMask + 1 == GetPhysicalWidth())
{
column &= WidthMask;
}
else
{
column %= GetPhysicalWidth();
}
}
if (spans_out != nullptr)
{
if (Spandata[2] == nullptr)
{
Spandata[2] = CreateSpans(Pixeldata);
}
*spans_out = Spandata[2][column];
}
return Pixeldata + column * GetPhysicalHeight();
} }
//========================================================================== //==========================================================================
@ -562,15 +527,23 @@ void FSoftwareTexture::FreeAllSpans()
} }
} }
// Note: this function needs to be thread safe
FSoftwareTexture* GetSoftwareTexture(FGameTexture* tex) FSoftwareTexture* GetSoftwareTexture(FGameTexture* tex)
{ {
FSoftwareTexture* SoftwareTexture = static_cast<FSoftwareTexture*>(tex->GetSoftwareTexture()); FSoftwareTexture* SoftwareTexture = static_cast<FSoftwareTexture*>(tex->GetSoftwareTexture());
if (!SoftwareTexture) if (!SoftwareTexture)
{ {
if (tex->isSoftwareCanvas()) SoftwareTexture = new FSWCanvasTexture(tex); static std::mutex loadmutex;
else if (tex->isWarped()) SoftwareTexture = new FWarpTexture(tex, tex->isWarped()); std::unique_lock<std::mutex> lock(loadmutex);
else SoftwareTexture = new FSoftwareTexture(tex);
tex->SetSoftwareTexture(SoftwareTexture); SoftwareTexture = static_cast<FSoftwareTexture*>(tex->GetSoftwareTexture());
if (!SoftwareTexture)
{
if (tex->isSoftwareCanvas()) SoftwareTexture = new FSWCanvasTexture(tex);
else if (tex->isWarped()) SoftwareTexture = new FWarpTexture(tex, tex->isWarped());
else SoftwareTexture = new FSoftwareTexture(tex);
tex->SetSoftwareTexture(SoftwareTexture);
}
} }
return SoftwareTexture; return SoftwareTexture;
} }
@ -582,6 +555,7 @@ CUSTOM_CVAR(Bool, vid_nopalsubstitutions, false, CVAR_ARCHIVE | CVAR_NOINITCALL)
R_InitSkyMap(); R_InitSkyMap();
} }
// Note: this function needs to be thread safe
FSoftwareTexture* GetPalettedSWTexture(FTextureID texid, bool animate, bool checkcompat, bool allownull) FSoftwareTexture* GetPalettedSWTexture(FTextureID texid, bool animate, bool checkcompat, bool allownull)
{ {
bool needpal = !vid_nopalsubstitutions && !V_IsTrueColor(); bool needpal = !vid_nopalsubstitutions && !V_IsTrueColor();

View file

@ -20,6 +20,11 @@ protected:
FTexture *mSource; FTexture *mSource;
TArray<uint8_t> Pixels; TArray<uint8_t> Pixels;
TArray<uint32_t> PixelsBgra; TArray<uint32_t> PixelsBgra;
struct
{
const void* Pixels = nullptr;
int LastUpdate = -1;
} Unlockeddata[3];
FSoftwareTextureSpan **Spandata[3] = { }; FSoftwareTextureSpan **Spandata[3] = { };
DVector2 Scale; DVector2 Scale;
uint8_t WidthBits = 0, HeightBits = 0; uint8_t WidthBits = 0, HeightBits = 0;
@ -94,6 +99,7 @@ public:
{ {
Pixels.Reset(); Pixels.Reset();
PixelsBgra.Reset(); PixelsBgra.Reset();
for (auto& d : Unlockeddata) d = {};
} }
// Returns true if the next call to GetPixels() will return an image different from the // Returns true if the next call to GetPixels() will return an image different from the
@ -110,16 +116,69 @@ public:
virtual bool Mipmapped() { return true; } virtual bool Mipmapped() { return true; }
// Returns a single column of the texture // Returns a single column of the texture
virtual const uint8_t *GetColumn(int style, unsigned int column, const FSoftwareTextureSpan **spans_out); const uint8_t* GetColumn(int style, unsigned int column, const FSoftwareTextureSpan** spans_out)
{
column = WrapColumn(column);
const uint8_t* pixels = GetPixels(style);
if (spans_out)
*spans_out = Spandata[style][column];
return pixels + column * GetPhysicalHeight();
}
// Returns a single column of the texture, in BGRA8 format // Returns a single column of the texture, in BGRA8 format
virtual const uint32_t *GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out); const uint32_t* GetColumnBgra(unsigned int column, const FSoftwareTextureSpan** spans_out)
{
column = WrapColumn(column);
const uint32_t* pixels = GetPixelsBgra();
if (spans_out)
*spans_out = Spandata[2][column];
return pixels + column * GetPhysicalHeight();
}
unsigned int WrapColumn(unsigned int column)
{
if ((unsigned)column >= (unsigned)GetPhysicalWidth())
{
if (WidthMask + 1 == GetPhysicalWidth())
{
column &= WidthMask;
}
else
{
column %= GetPhysicalWidth();
}
}
return column;
}
// Returns the whole texture, stored in column-major order, in BGRA8 format // Returns the whole texture, stored in column-major order, in BGRA8 format
virtual const uint32_t *GetPixelsBgra(); const uint32_t* GetPixelsBgra()
{
int style = 2;
if (Unlockeddata[2].LastUpdate == CurrentUpdate)
{
return static_cast<const uint32_t*>(Unlockeddata[style].Pixels);
}
else
{
UpdatePixels(style);
return static_cast<const uint32_t*>(Unlockeddata[style].Pixels);
}
}
// Returns the whole texture, stored in column-major order // Returns the whole texture, stored in column-major order
virtual const uint8_t *GetPixels(int style); const uint8_t* GetPixels(int style)
{
if (Unlockeddata[style].LastUpdate == CurrentUpdate)
{
return static_cast<const uint8_t*>(Unlockeddata[style].Pixels);
}
else
{
UpdatePixels(style);
return static_cast<const uint8_t*>(Unlockeddata[style].Pixels);
}
}
const uint8_t *GetPixels(FRenderStyle style) const uint8_t *GetPixels(FRenderStyle style)
{ {
@ -139,6 +198,11 @@ public:
return GetColumn(alpha, column, spans_out); return GetColumn(alpha, column, spans_out);
} }
static int CurrentUpdate;
void UpdatePixels(int style);
virtual const uint32_t* GetPixelsBgraLocked();
virtual const uint8_t* GetPixelsLocked(int style);
}; };
// A texture that returns a wiggly version of another texture. // A texture that returns a wiggly version of another texture.
@ -154,8 +218,8 @@ class FWarpTexture : public FSoftwareTexture
public: public:
FWarpTexture (FGameTexture *source, int warptype); FWarpTexture (FGameTexture *source, int warptype);
const uint32_t *GetPixelsBgra() override; const uint32_t *GetPixelsBgraLocked() override;
const uint8_t *GetPixels(int style) override; const uint8_t *GetPixelsLocked(int style) override;
bool CheckModified (int which) override; bool CheckModified (int which) override;
void GenerateBgraMipmapsFast(); void GenerateBgraMipmapsFast();
@ -179,8 +243,8 @@ public:
~FSWCanvasTexture(); ~FSWCanvasTexture();
// Returns the whole texture, stored in column-major order // Returns the whole texture, stored in column-major order
const uint32_t *GetPixelsBgra() override; const uint32_t *GetPixelsBgraLocked() override;
const uint8_t *GetPixels(int style) override; const uint8_t *GetPixelsLocked(int style) override;
virtual void Unload() override; virtual void Unload() override;
void UpdatePixels(bool truecolor); void UpdatePixels(bool truecolor);

View file

@ -77,7 +77,7 @@ FSWCanvasTexture::~FSWCanvasTexture()
// //
//========================================================================== //==========================================================================
const uint8_t *FSWCanvasTexture::GetPixels(int style) const uint8_t *FSWCanvasTexture::GetPixelsLocked(int style)
{ {
static_cast<FCanvasTexture*>(mSource)->NeedUpdate(); static_cast<FCanvasTexture*>(mSource)->NeedUpdate();
if (Canvas == nullptr) if (Canvas == nullptr)
@ -94,7 +94,7 @@ const uint8_t *FSWCanvasTexture::GetPixels(int style)
// //
//========================================================================== //==========================================================================
const uint32_t *FSWCanvasTexture::GetPixelsBgra() const uint32_t *FSWCanvasTexture::GetPixelsBgraLocked()
{ {
static_cast<FCanvasTexture*>(mSource)->NeedUpdate(); static_cast<FCanvasTexture*>(mSource)->NeedUpdate();
if (CanvasBgra == nullptr) if (CanvasBgra == nullptr)

View file

@ -57,7 +57,7 @@ bool FWarpTexture::CheckModified (int style)
return screen->FrameTime != GenTime[style]; return screen->FrameTime != GenTime[style];
} }
const uint32_t *FWarpTexture::GetPixelsBgra() const uint32_t *FWarpTexture::GetPixelsBgraLocked()
{ {
uint64_t time = screen->FrameTime; uint64_t time = screen->FrameTime;
uint64_t resizeMult = gl_texture_hqresizemult; uint64_t resizeMult = gl_texture_hqresizemult;
@ -67,7 +67,7 @@ const uint32_t *FWarpTexture::GetPixelsBgra()
if (gl_texture_hqresizemode == 0 || gl_texture_hqresizemult < 1 || !(gl_texture_hqresize_targets & 1)) if (gl_texture_hqresizemode == 0 || gl_texture_hqresizemult < 1 || !(gl_texture_hqresize_targets & 1))
resizeMult = 1; resizeMult = 1;
auto otherpix = FSoftwareTexture::GetPixelsBgra(); auto otherpix = FSoftwareTexture::GetPixelsBgraLocked();
WarpedPixelsRgba.Resize(unsigned(GetWidth() * GetHeight() * resizeMult * resizeMult * 4 / 3 + 1)); WarpedPixelsRgba.Resize(unsigned(GetWidth() * GetHeight() * resizeMult * resizeMult * 4 / 3 + 1));
WarpBuffer(WarpedPixelsRgba.Data(), otherpix, int(GetWidth() * resizeMult), int(GetHeight() * resizeMult), WidthOffsetMultiplier, HeightOffsetMultiplier, time, mTexture->GetShaderSpeed(), bWarped); WarpBuffer(WarpedPixelsRgba.Data(), otherpix, int(GetWidth() * resizeMult), int(GetHeight() * resizeMult), WidthOffsetMultiplier, HeightOffsetMultiplier, time, mTexture->GetShaderSpeed(), bWarped);
GenerateBgraMipmapsFast(); GenerateBgraMipmapsFast();
@ -78,7 +78,7 @@ const uint32_t *FWarpTexture::GetPixelsBgra()
} }
const uint8_t *FWarpTexture::GetPixels(int index) const uint8_t *FWarpTexture::GetPixelsLocked(int index)
{ {
uint64_t time = screen->FrameTime; uint64_t time = screen->FrameTime;
uint64_t resizeMult = gl_texture_hqresizemult; uint64_t resizeMult = gl_texture_hqresizemult;
@ -88,7 +88,7 @@ const uint8_t *FWarpTexture::GetPixels(int index)
if (gl_texture_hqresizemode == 0 || gl_texture_hqresizemult < 1 || !(gl_texture_hqresize_targets & 1)) if (gl_texture_hqresizemode == 0 || gl_texture_hqresizemult < 1 || !(gl_texture_hqresize_targets & 1))
resizeMult = 1; resizeMult = 1;
const uint8_t *otherpix = FSoftwareTexture::GetPixels(index); const uint8_t *otherpix = FSoftwareTexture::GetPixelsLocked(index);
WarpedPixels[index].Resize(unsigned(GetWidth() * GetHeight() * resizeMult * resizeMult)); WarpedPixels[index].Resize(unsigned(GetWidth() * GetHeight() * resizeMult * resizeMult));
WarpBuffer(WarpedPixels[index].Data(), otherpix, int(GetWidth() * resizeMult), int(GetHeight() * resizeMult), WidthOffsetMultiplier, HeightOffsetMultiplier, time, mTexture->GetShaderSpeed(), bWarped); WarpBuffer(WarpedPixels[index].Data(), otherpix, int(GetWidth() * resizeMult), int(GetHeight() * resizeMult), WidthOffsetMultiplier, HeightOffsetMultiplier, time, mTexture->GetShaderSpeed(), bWarped);
FreeAllSpans(); FreeAllSpans();

View file

@ -240,7 +240,6 @@ namespace swrenderer
bool visible = drawerargs.SetStyle(thread->Viewport.get(), decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor, cmlight); bool visible = drawerargs.SetStyle(thread->Viewport.get(), decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor, cmlight);
if (visible) if (visible)
{ {
thread->PrepareTexture(WallSpriteTile, decal->RenderStyle);
drawerargs.DrawMasked(thread, zpos + WallSpriteTile->GetTopOffset(0) * decal->ScaleY, decal->ScaleY, decal->RenderFlags & RF_XFLIP, decal->RenderFlags & RF_YFLIP, WallC, clipper->x1, clipper->x2, light, WallSpriteTile, mfloorclip, mceilingclip, decal->RenderStyle); drawerargs.DrawMasked(thread, zpos + WallSpriteTile->GetTopOffset(0) * decal->ScaleY, decal->ScaleY, decal->RenderFlags & RF_XFLIP, decal->RenderFlags & RF_YFLIP, WallC, clipper->x1, clipper->x2, light, WallSpriteTile, mfloorclip, mceilingclip, decal->RenderStyle);
} }

View file

@ -231,7 +231,6 @@ namespace swrenderer
{ {
auto vis = this; auto vis = this;
int spacing;
uint8_t color = vis->Light.BaseColormap->Maps[vis->startfrac]; uint8_t color = vis->Light.BaseColormap->Maps[vis->startfrac];
int yl = vis->y1; int yl = vis->y1;
int ycount = vis->y2 - yl + 1; int ycount = vis->y2 - yl + 1;
@ -250,33 +249,18 @@ namespace swrenderer
uint32_t alpha = fglevel * 256 / FRACUNIT; uint32_t alpha = fglevel * 256 / FRACUNIT;
auto viewport = thread->Viewport.get(); auto viewport = thread->Viewport.get();
auto drawers = thread->Drawers(viewport);
spacing = viewport->RenderTarget->GetPitch();
uint32_t fracstepx = PARTICLE_TEXTURE_SIZE * FRACUNIT / countbase; uint32_t fracstepx = PARTICLE_TEXTURE_SIZE * FRACUNIT / countbase;
uint32_t fracposx = fracstepx / 2; uint32_t fracposx = fracstepx / 2;
RenderTranslucentPass *translucentPass = thread->TranslucentPass.get(); RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();
if (viewport->RenderTarget->IsBgra()) for (int x = x1; x < (x1 + countbase); x++, fracposx += fracstepx)
{ {
for (int x = x1; x < (x1 + countbase); x++, fracposx += fracstepx) if (translucentPass->ClipSpriteColumnWithPortals(x, vis))
{ continue;
if (translucentPass->ClipSpriteColumnWithPortals(x, vis)) drawers->DrawParticleColumn(x, yl, ycount, fg, alpha, fracposx);
continue;
uint32_t *dest = (uint32_t*)viewport->GetDest(x, yl);
thread->DrawQueue->Push<DrawParticleColumnRGBACommand>(dest, yl, spacing, ycount, fg, alpha, fracposx);
}
}
else
{
for (int x = x1; x < (x1 + countbase); x++, fracposx += fracstepx)
{
if (translucentPass->ClipSpriteColumnWithPortals(x, vis))
continue;
uint8_t *dest = viewport->GetDest(x, yl);
thread->DrawQueue->Push<DrawParticleColumnPalCommand>(dest, yl, spacing, ycount, fg, alpha, fracposx);
}
} }
} }

View file

@ -262,8 +262,7 @@ namespace swrenderer
{ {
RenderTranslucentPass *translucentPass = thread->TranslucentPass.get(); RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();
short portalfloorclip[MAXWIDTH]; short portalfloorclip[MAXWIDTH];
int x2 = wallc.sx2; for (int x = x1; x < x2; x++)
for (int x = wallc.sx1; x < x2; x++)
{ {
if (translucentPass->ClipSpriteColumnWithPortals(x, this)) if (translucentPass->ClipSpriteColumnWithPortals(x, this))
portalfloorclip[x] = mceilingclip[x]; portalfloorclip[x] = mceilingclip[x];
@ -271,8 +270,6 @@ namespace swrenderer
portalfloorclip[x] = mfloorclip[x]; portalfloorclip[x] = mfloorclip[x];
} }
thread->PrepareTexture(pic, RenderStyle);
ProjectedWallLight mlight; ProjectedWallLight mlight;
mlight.SetSpriteLight(); mlight.SetSpriteLight();

View file

@ -176,8 +176,6 @@ namespace swrenderer
// Draw it // Draw it
auto WallSpriteTile = spr->pic; auto WallSpriteTile = spr->pic;
thread->PrepareTexture(WallSpriteTile, spr->RenderStyle);
RenderTranslucentPass* translucentPass = thread->TranslucentPass.get(); RenderTranslucentPass* translucentPass = thread->TranslucentPass.get();
short floorclip[MAXWIDTH]; short floorclip[MAXWIDTH];
for (int x = x1; x < x2; x++) for (int x = x1; x < x2; x++)

View file

@ -32,8 +32,6 @@ namespace swrenderer
void SpanDrawerArgs::SetTexture(RenderThread *thread, FSoftwareTexture *tex) void SpanDrawerArgs::SetTexture(RenderThread *thread, FSoftwareTexture *tex)
{ {
thread->PrepareTexture(tex, DefaultRenderStyle());
ds_texwidth = tex->GetPhysicalWidth(); ds_texwidth = tex->GetPhysicalWidth();
ds_texheight = tex->GetPhysicalHeight(); ds_texheight = tex->GetPhysicalHeight();
ds_xbits = tex->GetWidthBits(); ds_xbits = tex->GetWidthBits();

View file

@ -111,7 +111,7 @@ namespace swrenderer
RenderViewport *dc_viewport = nullptr; RenderViewport *dc_viewport = nullptr;
friend class DrawVoxelBlocksRGBACommand; friend class SWTruecolorDrawers;
friend class DrawVoxelBlocksPalCommand; friend class SWPalDrawers;
}; };
} }