Revert "Merge dpJudas's renderslices branch (#1356)"

This reverts commit a5cba1aba5.
This commit is contained in:
Rachael Alexanderson 2021-03-26 07:08:31 -04:00
parent a5cba1aba5
commit 6e5dbbc8ec
29 changed files with 1997 additions and 1346 deletions

View file

@ -221,7 +221,238 @@ namespace swrenderer
/////////////////////////////////////////////////////////////////////////
void SWPixelFormatDrawers::DrawDepthColumn(const WallColumnDrawerArgs& args, float idepth)
DrawWallCommand::DrawWallCommand(const WallDrawerArgs& args) : wallargs(args)
{
}
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;
@ -246,11 +477,15 @@ namespace swrenderer
}
count = args.Count();
auto zbuffer = thread->Poly->depthstencil;
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++)
{
@ -259,7 +494,7 @@ namespace swrenderer
}
}
void SWPixelFormatDrawers::SetLights(WallColumnDrawerArgs& drawerargs, int x, int y1, const WallDrawerArgs& wallargs)
void DrawWallCommand::SetLights(WallColumnDrawerArgs& drawerargs, int x, int y1)
{
bool mirror = !!(wallargs.PortalMirrorFlags & RF_XFLIP);
int tx = x;
@ -325,74 +560,130 @@ 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)
{
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;
}
Queue->Push<DepthSkyColumnCommand>(args, idepth);
}
void SWPixelFormatDrawers::DrawDepthSpan(const SpanDrawerArgs &args, float idepth1, float 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;
}
}
Queue->Push<DepthSpanCommand>(args, idepth1, idepth2);
}
}

View file

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

File diff suppressed because it is too large Load diff

View file

@ -107,81 +107,289 @@ namespace swrenderer
int mShade = 0;
};
struct DrawWallModeNormal;
struct DrawWallModeMasked;
struct DrawWallModeAdd;
struct DrawWallModeAddClamp;
struct DrawWallModeSubClamp;
struct DrawWallModeRevSubClamp;
class DrawWallCommand : public DrawerCommand
{
public:
DrawWallCommand(const WallDrawerArgs& args);
void Execute(DrawerThread* thread) override;
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
{
public:
using SWPixelFormatDrawers::SWPixelFormatDrawers;
void DrawWall(const WallDrawerArgs &args) override { DrawWallColumns<DrawWallModeNormal>(args); }
void DrawWallMasked(const WallDrawerArgs &args) override { DrawWallColumns<DrawWallModeMasked>(args); }
void DrawWallAdd(const WallDrawerArgs &args) override { DrawWallColumns<DrawWallModeAdd>(args); }
void DrawWallAddClamp(const WallDrawerArgs &args) override { DrawWallColumns<DrawWallModeAddClamp>(args); }
void DrawWallSubClamp(const WallDrawerArgs &args) override { DrawWallColumns<DrawWallModeSubClamp>(args); }
void DrawWallRevSubClamp(const WallDrawerArgs &args) override { DrawWallColumns<DrawWallModeRevSubClamp>(args); }
void DrawSingleSkyColumn(const SkyDrawerArgs& args) override;
void DrawDoubleSkyColumn(const SkyDrawerArgs& args) override;
void DrawColumn(const SpriteDrawerArgs& args) override;
void FillColumn(const SpriteDrawerArgs& args) override;
void FillAddColumn(const SpriteDrawerArgs& args) override;
void FillAddClampColumn(const SpriteDrawerArgs& args) override;
void FillSubClampColumn(const SpriteDrawerArgs& args) override;
void FillRevSubClampColumn(const SpriteDrawerArgs& args) override;
void DrawWall(const WallDrawerArgs &args) override { Queue->Push<DrawWall1PalCommand>(args); }
void DrawWallMasked(const WallDrawerArgs &args) override { Queue->Push<DrawWallMasked1PalCommand>(args); }
void DrawWallAdd(const WallDrawerArgs &args) override { Queue->Push<DrawWallAdd1PalCommand>(args); }
void DrawWallAddClamp(const WallDrawerArgs &args) override { Queue->Push<DrawWallAddClamp1PalCommand>(args); }
void DrawWallSubClamp(const WallDrawerArgs &args) override { Queue->Push<DrawWallSubClamp1PalCommand>(args); }
void DrawWallRevSubClamp(const WallDrawerArgs &args) override { Queue->Push<DrawWallRevSubClamp1PalCommand>(args); }
void DrawSingleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push<DrawSingleSky1PalCommand>(args); }
void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push<DrawDoubleSky1PalCommand>(args); }
void DrawColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnPalCommand>(args); }
void FillColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnPalCommand>(args); }
void FillAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnAddPalCommand>(args); }
void FillAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnAddClampPalCommand>(args); }
void FillSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnSubClampPalCommand>(args); }
void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnRevSubClampPalCommand>(args); }
void DrawFuzzColumn(const SpriteDrawerArgs &args) override
{
if (r_fuzzscale)
DrawScaledFuzzColumn(args);
Queue->Push<DrawScaledFuzzColumnPalCommand>(args);
else
DrawUnscaledFuzzColumn(args);
Queue->Push<DrawFuzzColumnPalCommand>(args);
R_UpdateFuzzPos(args);
}
void DrawAddColumn(const SpriteDrawerArgs& args) override;
void DrawTranslatedColumn(const SpriteDrawerArgs& args) override;
void DrawTranslatedAddColumn(const SpriteDrawerArgs& args) override;
void DrawShadedColumn(const SpriteDrawerArgs& args) override;
void DrawAddClampShadedColumn(const SpriteDrawerArgs& args) override;
void DrawAddClampColumn(const SpriteDrawerArgs& args) override;
void DrawAddClampTranslatedColumn(const SpriteDrawerArgs& args) override;
void DrawSubClampColumn(const SpriteDrawerArgs& args) override;
void DrawSubClampTranslatedColumn(const SpriteDrawerArgs& args) override;
void DrawRevSubClampColumn(const SpriteDrawerArgs& args) override;
void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs& args) override;
void DrawVoxelBlocks(const SpriteDrawerArgs& args, const VoxelBlock* blocks, int blockcount) override;
void DrawSpan(const SpanDrawerArgs& args) override;
void DrawSpanMasked(const SpanDrawerArgs& args) override;
void DrawSpanTranslucent(const SpanDrawerArgs& args) override;
void DrawSpanMaskedTranslucent(const SpanDrawerArgs& args) override;
void DrawSpanAddClamp(const SpanDrawerArgs& args) override;
void DrawSpanMaskedAddClamp(const SpanDrawerArgs& args) override;
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 DrawAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddPalCommand>(args); }
void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnTranslatedPalCommand>(args); }
void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnTlatedAddPalCommand>(args); }
void DrawShadedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnShadedPalCommand>(args); }
void DrawAddClampShadedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddClampShadedPalCommand>(args); }
void DrawAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddClampPalCommand>(args); }
void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddClampTranslatedPalCommand>(args); }
void DrawSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnSubClampPalCommand>(args); }
void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnSubClampTranslatedPalCommand>(args); }
void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampPalCommand>(args); }
void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampTranslatedPalCommand>(args); }
void DrawVoxelBlocks(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount) override { Queue->Push<DrawVoxelBlocksPalCommand>(args, blocks, blockcount); }
void DrawSpan(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanPalCommand>(args); }
void DrawSpanMasked(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedPalCommand>(args); }
void DrawSpanTranslucent(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanTranslucentPalCommand>(args); }
void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedTranslucentPalCommand>(args); }
void DrawSpanAddClamp(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanAddClampPalCommand>(args); }
void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedAddClampPalCommand>(args); }
void FillSpan(const SpanDrawerArgs &args) override { Queue->Push<FillSpanPalCommand>(args); }
void 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
{
Queue->Push<DrawTiltedSpanPalCommand>(args, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy, basecolormap);
}
void DrawScaledFuzzColumn(const SpriteDrawerArgs& 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;
void DrawColoredSpan(const SpanDrawerArgs &args) override { Queue->Push<DrawColoredSpanPalCommand>(args); }
void DrawFogBoundaryLine(const SpanDrawerArgs &args) override { Queue->Push<DrawFogBoundaryLinePalCommand>(args); }
};
}

View file

@ -82,185 +82,193 @@ namespace swrenderer
{
void SWTruecolorDrawers::DrawWall(const WallDrawerArgs &args)
{
DrawWallColumns<DrawWall32Command>(args);
Queue->Push<DrawWall32Command>(args);
}
void SWTruecolorDrawers::DrawWallMasked(const WallDrawerArgs &args)
{
DrawWallColumns<DrawWallMasked32Command>(args);
Queue->Push<DrawWallMasked32Command>(args);
}
void SWTruecolorDrawers::DrawWallAdd(const WallDrawerArgs &args)
{
DrawWallColumns<DrawWallAddClamp32Command>(args);
Queue->Push<DrawWallAddClamp32Command>(args);
}
void SWTruecolorDrawers::DrawWallAddClamp(const WallDrawerArgs &args)
{
DrawWallColumns<DrawWallAddClamp32Command>(args);
Queue->Push<DrawWallAddClamp32Command>(args);
}
void SWTruecolorDrawers::DrawWallSubClamp(const WallDrawerArgs &args)
{
DrawWallColumns<DrawWallSubClamp32Command>(args);
Queue->Push<DrawWallSubClamp32Command>(args);
}
void SWTruecolorDrawers::DrawWallRevSubClamp(const WallDrawerArgs &args)
{
DrawWallColumns<DrawWallRevSubClamp32Command>(args);
Queue->Push<DrawWallRevSubClamp32Command>(args);
}
void SWTruecolorDrawers::DrawColumn(const SpriteDrawerArgs &args)
{
DrawSprite32Command::DrawColumn(args);
Queue->Push<DrawSprite32Command>(args);
}
void SWTruecolorDrawers::FillColumn(const SpriteDrawerArgs &args)
{
FillSprite32Command::DrawColumn(args);
Queue->Push<FillSprite32Command>(args);
}
void SWTruecolorDrawers::FillAddColumn(const SpriteDrawerArgs &args)
{
FillSpriteAddClamp32Command::DrawColumn(args);
Queue->Push<FillSpriteAddClamp32Command>(args);
}
void SWTruecolorDrawers::FillAddClampColumn(const SpriteDrawerArgs &args)
{
FillSpriteAddClamp32Command::DrawColumn(args);
Queue->Push<FillSpriteAddClamp32Command>(args);
}
void SWTruecolorDrawers::FillSubClampColumn(const SpriteDrawerArgs &args)
{
FillSpriteSubClamp32Command::DrawColumn(args);
Queue->Push<FillSpriteSubClamp32Command>(args);
}
void SWTruecolorDrawers::FillRevSubClampColumn(const SpriteDrawerArgs &args)
{
FillSpriteRevSubClamp32Command::DrawColumn(args);
Queue->Push<FillSpriteRevSubClamp32Command>(args);
}
void SWTruecolorDrawers::DrawFuzzColumn(const SpriteDrawerArgs &args)
{
if (r_fuzzscale)
DrawScaledFuzzColumn(args);
Queue->Push<DrawScaledFuzzColumnRGBACommand>(args);
else
DrawUnscaledFuzzColumn(args);
Queue->Push<DrawFuzzColumnRGBACommand>(args);
R_UpdateFuzzPos(args);
}
void SWTruecolorDrawers::DrawAddColumn(const SpriteDrawerArgs &args)
{
DrawSpriteAddClamp32Command::DrawColumn(args);
Queue->Push<DrawSpriteAddClamp32Command>(args);
}
void SWTruecolorDrawers::DrawTranslatedColumn(const SpriteDrawerArgs &args)
{
DrawSpriteTranslated32Command::DrawColumn(args);
Queue->Push<DrawSpriteTranslated32Command>(args);
}
void SWTruecolorDrawers::DrawTranslatedAddColumn(const SpriteDrawerArgs &args)
{
DrawSpriteTranslatedAddClamp32Command::DrawColumn(args);
Queue->Push<DrawSpriteTranslatedAddClamp32Command>(args);
}
void SWTruecolorDrawers::DrawShadedColumn(const SpriteDrawerArgs &args)
{
DrawSpriteShaded32Command::DrawColumn(args);
Queue->Push<DrawSpriteShaded32Command>(args);
}
void SWTruecolorDrawers::DrawAddClampShadedColumn(const SpriteDrawerArgs &args)
{
DrawSpriteAddClampShaded32Command::DrawColumn(args);
Queue->Push<DrawSpriteAddClampShaded32Command>(args);
}
void SWTruecolorDrawers::DrawAddClampColumn(const SpriteDrawerArgs &args)
{
DrawSpriteAddClamp32Command::DrawColumn(args);
Queue->Push<DrawSpriteAddClamp32Command>(args);
}
void SWTruecolorDrawers::DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args)
{
DrawSpriteTranslatedAddClamp32Command::DrawColumn(args);
Queue->Push<DrawSpriteTranslatedAddClamp32Command>(args);
}
void SWTruecolorDrawers::DrawSubClampColumn(const SpriteDrawerArgs &args)
{
DrawSpriteSubClamp32Command::DrawColumn(args);
Queue->Push<DrawSpriteSubClamp32Command>(args);
}
void SWTruecolorDrawers::DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args)
{
DrawSpriteTranslatedSubClamp32Command::DrawColumn(args);
Queue->Push<DrawSpriteTranslatedSubClamp32Command>(args);
}
void SWTruecolorDrawers::DrawRevSubClampColumn(const SpriteDrawerArgs &args)
{
DrawSpriteRevSubClamp32Command::DrawColumn(args);
Queue->Push<DrawSpriteRevSubClamp32Command>(args);
}
void SWTruecolorDrawers::DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args)
{
DrawSpriteTranslatedRevSubClamp32Command::DrawColumn(args);
Queue->Push<DrawSpriteTranslatedRevSubClamp32Command>(args);
}
void SWTruecolorDrawers::DrawVoxelBlocks(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount)
{
Queue->Push<DrawVoxelBlocksRGBACommand>(args, blocks, blockcount);
}
void SWTruecolorDrawers::DrawSpan(const SpanDrawerArgs &args)
{
DrawSpan32Command::DrawColumn(args);
Queue->Push<DrawSpan32Command>(args);
}
void SWTruecolorDrawers::DrawSpanMasked(const SpanDrawerArgs &args)
{
DrawSpanMasked32Command::DrawColumn(args);
Queue->Push<DrawSpanMasked32Command>(args);
}
void SWTruecolorDrawers::DrawSpanTranslucent(const SpanDrawerArgs &args)
{
DrawSpanTranslucent32Command::DrawColumn(args);
Queue->Push<DrawSpanTranslucent32Command>(args);
}
void SWTruecolorDrawers::DrawSpanMaskedTranslucent(const SpanDrawerArgs &args)
{
DrawSpanAddClamp32Command::DrawColumn(args);
Queue->Push<DrawSpanAddClamp32Command>(args);
}
void SWTruecolorDrawers::DrawSpanAddClamp(const SpanDrawerArgs &args)
{
DrawSpanTranslucent32Command::DrawColumn(args);
Queue->Push<DrawSpanTranslucent32Command>(args);
}
void SWTruecolorDrawers::DrawSpanMaskedAddClamp(const SpanDrawerArgs &args)
{
DrawSpanAddClamp32Command::DrawColumn(args);
Queue->Push<DrawSpanAddClamp32Command>(args);
}
void SWTruecolorDrawers::DrawSingleSkyColumn(const SkyDrawerArgs &args)
{
DrawSkySingle32Command::DrawColumn(args);
Queue->Push<DrawSkySingle32Command>(args);
}
void SWTruecolorDrawers::DrawDoubleSkyColumn(const SkyDrawerArgs &args)
{
DrawSkyDouble32Command::DrawColumn(args);
Queue->Push<DrawSkyDouble32Command>(args);
}
/////////////////////////////////////////////////////////////////////////////
void SWTruecolorDrawers::DrawScaledFuzzColumn(const SpriteDrawerArgs& drawerargs)
DrawScaledFuzzColumnRGBACommand::DrawScaledFuzzColumnRGBACommand(const SpriteDrawerArgs &drawerargs)
{
int _x = drawerargs.FuzzX();
int _yl = drawerargs.FuzzY1();
int _yh = drawerargs.FuzzY2();
uint8_t* RESTRICT _destorg = drawerargs.Viewport()->GetDest(0, 0);
int _pitch = drawerargs.Viewport()->RenderTarget->GetPitch();
int _fuzzpos = fuzzpos;
int _fuzzviewheight = fuzzviewheight;
_x = drawerargs.FuzzX();
_yl = drawerargs.FuzzY1();
_yh = drawerargs.FuzzY2();
_destorg = drawerargs.Viewport()->GetDest(0, 0);
_pitch = drawerargs.Viewport()->RenderTarget->GetPitch();
_fuzzpos = fuzzpos;
_fuzzviewheight = fuzzviewheight;
}
void DrawScaledFuzzColumnRGBACommand::Execute(DrawerThread *thread)
{
int x = _x;
int yl = MAX(_yl, 1);
int yh = MIN(_yh, _fuzzviewheight);
int count = yh - yl + 1;
int count = thread->count_for_thread(yl, yh - yl + 1);
if (count <= 0) return;
int pitch = _pitch;
@ -271,7 +279,14 @@ namespace swrenderer
fixed_t fuzzstep = (200 << FRACBITS) / _fuzzviewheight;
fixed_t fuzzcount = FUZZTABLE << FRACBITS;
fixed_t fuzz = ((fuzz_x << FRACBITS) + yl * fuzzstep) % fuzzcount;
fixed_t fuzz = (fuzz_x << FRACBITS) + yl * fuzzstep;
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)
{
@ -294,30 +309,33 @@ namespace swrenderer
/////////////////////////////////////////////////////////////////////////////
void SWTruecolorDrawers::DrawUnscaledFuzzColumn(const SpriteDrawerArgs& drawerargs)
DrawFuzzColumnRGBACommand::DrawFuzzColumnRGBACommand(const SpriteDrawerArgs &drawerargs)
{
int _x = drawerargs.FuzzX();
int _yl = drawerargs.FuzzY1();
int _yh = drawerargs.FuzzY2();
uint8_t* RESTRICT _destorg = drawerargs.Viewport()->GetDest(0, 0);
int _pitch = drawerargs.Viewport()->RenderTarget->GetPitch();
int _fuzzpos = fuzzpos;
int _fuzzviewheight = fuzzviewheight;
_x = drawerargs.FuzzX();
_yl = drawerargs.FuzzY1();
_yh = drawerargs.FuzzY2();
_destorg = drawerargs.Viewport()->GetDest(0, 0);
_pitch = drawerargs.Viewport()->RenderTarget->GetPitch();
_fuzzpos = fuzzpos;
_fuzzviewheight = fuzzviewheight;
}
void DrawFuzzColumnRGBACommand::Execute(DrawerThread *thread)
{
int yl = MAX(_yl, 1);
int yh = MIN(_yh, _fuzzviewheight);
int count = yh - yl + 1;
int count = thread->count_for_thread(yl, yh - yl + 1);
// Zero length.
if (count <= 0)
return;
uint32_t *dest = _pitch * yl + _x + (uint32_t*)_destorg;
int pitch = _pitch;
uint32_t *dest = thread->dest_for_thread(yl, _pitch, _pitch * yl + _x + (uint32_t*)_destorg);
int pitch = _pitch * thread->num_cores;
int fuzzstep = 1;
int fuzz = _fuzzpos % FUZZTABLE;
int fuzzstep = thread->num_cores;
int fuzz = (_fuzzpos + thread->skipped_by_thread(yl)) % FUZZTABLE;
#ifndef ORIGINAL_FUZZ
@ -349,6 +367,8 @@ namespace swrenderer
#else
yl += thread->skipped_by_thread(yl);
// Handle the case where we would go out of bounds at the top:
if (yl < fuzzstep)
{
@ -423,14 +443,20 @@ namespace swrenderer
/////////////////////////////////////////////////////////////////////////////
void SWTruecolorDrawers::FillSpan(const SpanDrawerArgs& drawerargs)
FillSpanRGBACommand::FillSpanRGBACommand(const SpanDrawerArgs &drawerargs)
{
int _x1 = drawerargs.DestX1();
int _x2 = drawerargs.DestX2();
int _y = drawerargs.DestY();
uint8_t* RESTRICT _dest = drawerargs.Viewport()->GetDest(_x1, _y);
fixed_t _light = drawerargs.Light();
int _color = drawerargs.SolidColor();
_x1 = drawerargs.DestX1();
_x2 = drawerargs.DestX2();
_y = drawerargs.DestY();
_dest = drawerargs.Viewport()->GetDest(_x1, _y);
_light = drawerargs.Light();
_color = drawerargs.SolidColor();
}
void FillSpanRGBACommand::Execute(DrawerThread *thread)
{
if (thread->line_skipped_by_thread(_y))
return;
uint32_t *dest = (uint32_t*)_dest;
int count = (_x2 - _x1 + 1);
@ -442,14 +468,20 @@ namespace swrenderer
/////////////////////////////////////////////////////////////////////////////
void SWTruecolorDrawers::DrawFogBoundaryLine(const SpanDrawerArgs& drawerargs)
DrawFogBoundaryLineRGBACommand::DrawFogBoundaryLineRGBACommand(const SpanDrawerArgs &drawerargs)
{
int _y = drawerargs.DestY();
int _x = drawerargs.DestX1();
int _x2 = drawerargs.DestX2();
uint8_t* RESTRICT _line = drawerargs.Viewport()->GetDest(0, _y);
fixed_t _light = drawerargs.Light();
ShadeConstants constants = drawerargs.ColormapConstants();
_y = drawerargs.DestY();
_x = drawerargs.DestX1();
_x2 = drawerargs.DestX2();
_line = drawerargs.Viewport()->GetDest(0, _y);
_light = drawerargs.Light();
_shade_constants = drawerargs.ColormapConstants();
}
void DrawFogBoundaryLineRGBACommand::Execute(DrawerThread *thread)
{
if (thread->line_skipped_by_thread(_y))
return;
int y = _y;
int x = _x;
@ -458,6 +490,7 @@ namespace swrenderer
uint32_t *dest = (uint32_t*)_line;
uint32_t light = LightBgra::calc_light_multiplier(_light);
ShadeConstants constants = _shade_constants;
do
{
@ -497,18 +530,32 @@ namespace swrenderer
/////////////////////////////////////////////////////////////////////////////
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)
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)
{
int _x1 = drawerargs.DestX1();
int _x2 = drawerargs.DestX2();
int _y = drawerargs.DestY();
uint8_t* _dest = drawerargs.Viewport()->GetDest(_x1, _y);
fixed_t _light = drawerargs.Light();
ShadeConstants _shade_constants = drawerargs.ColormapConstants();
const uint32_t* _source = (const uint32_t*)drawerargs.TexturePixels();
int _xbits = drawerargs.TextureWidthBits();
int _ybits = drawerargs.TextureHeightBits();
RenderViewport* viewport = drawerargs.Viewport();
_x1 = drawerargs.DestX1();
_x2 = drawerargs.DestX2();
_y = drawerargs.DestY();
_dest = drawerargs.Viewport()->GetDest(_x1, _y);
_light = drawerargs.Light();
_shade_constants = drawerargs.ColormapConstants();
_plane_sz = plane_sz;
_plane_su = plane_su;
_plane_sv = plane_sv;
_plane_shade = plane_shade;
_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 INVSPAN 0.03125f
@ -613,14 +660,20 @@ namespace swrenderer
/////////////////////////////////////////////////////////////////////////////
void SWTruecolorDrawers::DrawColoredSpan(const SpanDrawerArgs& drawerargs)
DrawColoredSpanRGBACommand::DrawColoredSpanRGBACommand(const SpanDrawerArgs &drawerargs)
{
int _y = drawerargs.DestY();
int _x1 = drawerargs.DestX1();
int _x2 = drawerargs.DestX2();
uint8_t* RESTRICT _dest = drawerargs.Viewport()->GetDest(_x1, _y);
fixed_t _light = drawerargs.Light();
int _color = drawerargs.SolidColor();
_y = drawerargs.DestY();
_x1 = drawerargs.DestX1();
_x2 = drawerargs.DestX2();
_dest = drawerargs.Viewport()->GetDest(_x1, _y);
_light = drawerargs.Light();
_color = drawerargs.SolidColor();
}
void DrawColoredSpanRGBACommand::Execute(DrawerThread *thread)
{
if (thread->line_skipped_by_thread(_y))
return;
int y = _y;
int x1 = _x1;
@ -637,13 +690,12 @@ namespace swrenderer
/////////////////////////////////////////////////////////////////////////////
#if 0
#ifdef NO_SSE
void SWTruecolorDrawers::ApplySpecialColormap(FSpecialColormap* colormap, DFrameBuffer* screen)
ApplySpecialColormapRGBACommand::ApplySpecialColormapRGBACommand(FSpecialColormap *colormap, DFrameBuffer *screen)
{
uint8_t* buffer = screen->GetBuffer();
int pitch = screen->GetPitch();
int width = screen->GetWidth();
int height = screen->GetHeight();
buffer = screen->GetBuffer();
pitch = screen->GetPitch();
width = screen->GetWidth();
height = screen->GetHeight();
start_red = (int)(colormap->ColorizeStart[0] * 255);
start_green = (int)(colormap->ColorizeStart[1] * 255);
@ -651,9 +703,13 @@ namespace swrenderer
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;
#ifdef NO_SSE
void ApplySpecialColormapRGBACommand::Execute(DrawerThread *thread)
{
int y = thread->skipped_by_thread(0);
int count = thread->count_for_thread(0, height);
while (count > 0)
{
uint8_t *pixels = buffer + y * pitch * 4;
@ -678,27 +734,15 @@ namespace swrenderer
pixels += 4;
}
y++;
y += thread->num_cores;
count--;
}
}
#else
void SWTruecolorDrawers::ApplySpecialColormap(FSpecialColormap* colormap, DFrameBuffer* screen)
void ApplySpecialColormapRGBACommand::Execute(DrawerThread *thread)
{
uint8_t* buffer = screen->GetBuffer();
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;
int y = thread->skipped_by_thread(0);
int count = thread->count_for_thread(0, height);
__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);
while (count > 0)
@ -792,7 +836,7 @@ namespace swrenderer
pixels += 4;
}
y++;
y += thread->num_cores;
count--;
}
}
@ -801,21 +845,33 @@ namespace swrenderer
/////////////////////////////////////////////////////////////////////////////
void SWTruecolorDrawers::DrawParticleColumn(int x, int _dest_y, int _count, uint32_t _fg, uint32_t _alpha, uint32_t _fracposx)
DrawParticleColumnRGBACommand::DrawParticleColumnRGBACommand(uint32_t *dest, int dest_y, int pitch, int count, uint32_t fg, uint32_t alpha, uint32_t fracposx)
{
uint32_t* dest = (uint32_t*)thread->Viewport->GetDest(x, _dest_y);
int pitch = thread->Viewport->RenderTarget->GetPitch();
_dest = dest;
_pitch = pitch;
_count = count;
_fg = fg;
_alpha = alpha;
_fracposx = fracposx;
_dest_y = dest_y;
}
int count = _count;
void DrawParticleColumnRGBACommand::Execute(DrawerThread *thread)
{
int count = thread->count_for_thread(_dest_y, _count);
if (count <= 0)
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);
const uint32_t *source = &particle_texture[particle_texture_index][(_fracposx >> FRACBITS) * PARTICLE_TEXTURE_SIZE];
uint32_t particle_alpha = _alpha;
uint32_t fracstep = PARTICLE_TEXTURE_SIZE * FRACUNIT / _count;
uint32_t fracpos = fracstep / 2;
uint32_t fracpos = fracstep * thread->skipped_by_thread(_dest_y) + fracstep / 2;
fracstep *= thread->num_cores;
uint32_t fg_red = (_fg >> 16) & 0xff;
uint32_t fg_green = (_fg >> 8) & 0xff;
@ -842,208 +898,37 @@ namespace swrenderer
/////////////////////////////////////////////////////////////////////////////
void SWTruecolorDrawers::DrawVoxelBlocks(const SpriteDrawerArgs& args, const VoxelBlock* blocks, int blockcount)
DrawVoxelBlocksRGBACommand::DrawVoxelBlocksRGBACommand(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount) : args(args), blocks(blocks), blockcount(blockcount)
{
}
void DrawVoxelBlocksRGBACommand::Execute(DrawerThread *thread)
{
int pitch = args.Viewport()->RenderTarget->GetPitch();
uint8_t *destorig = args.Viewport()->RenderTarget->GetPixels();
SpriteDrawerArgs drawerargs = args;
drawerargs.dc_texturefracx = 0;
drawerargs.dc_source2 = 0;
DrawSprite32Command drawer(args);
drawer.args.dc_texturefracx = 0;
drawer.args.dc_source2 = 0;
for (int i = 0; i < blockcount; i++)
{
const VoxelBlock &block = blocks[i];
double v = block.vPos / (double)block.voxelsCount / FRACUNIT;
double vstep = block.vStep / (double)block.voxelsCount / FRACUNIT;
drawerargs.dc_texturefrac = (int)(v * (1 << 30));
drawerargs.dc_iscale = (int)(vstep * (1 << 30));
drawerargs.dc_source = block.voxels;
drawerargs.dc_textureheight = block.voxelsCount;
drawerargs.dc_count = block.height;
drawerargs.dc_dest_y = block.y;
drawerargs.dc_dest = destorig + (block.x + block.y * pitch) * 4;
drawer.args.dc_texturefrac = (int)(v * (1 << 30));
drawer.args.dc_iscale = (int)(vstep * (1 << 30));
drawer.args.dc_source = block.voxels;
drawer.args.dc_textureheight = block.voxelsCount;
drawer.args.dc_count = block.height;
drawer.args.dc_dest_y = block.y;
drawer.args.dc_dest = destorig + (block.x + block.y * pitch) * 4;
for (int j = 0; j < block.width; j++)
{
DrawSprite32Command::DrawColumn(drawerargs);
drawerargs.dc_dest += 4;
drawer.Execute(thread);
drawer.args.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,7 +25,6 @@
#include "r_draw.h"
#include "v_palette.h"
#include "r_thread.h"
#include "r_draw_pal.h"
#include "swrenderer/viewport/r_skydrawer.h"
#include "swrenderer/viewport/r_spandrawer.h"
#include "swrenderer/viewport/r_walldrawer.h"
@ -71,6 +70,125 @@ namespace swrenderer
#define VECTORCALL
#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>
class DrawerBlendCommand : public CommandType
{
@ -89,6 +207,38 @@ 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
{
public:
@ -127,19 +277,15 @@ namespace swrenderer
void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override;
void DrawSpanAddClamp(const SpanDrawerArgs &args) override;
void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override;
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 FillSpan(const SpanDrawerArgs &args) override { Queue->Push<FillSpanRGBACommand>(args); }
void DrawScaledFuzzColumn(const SpriteDrawerArgs& args);
void DrawUnscaledFuzzColumn(const SpriteDrawerArgs& args);
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
{
Queue->Push<DrawTiltedSpanRGBACommand>(args, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy);
}
template<typename DrawerT> void DrawWallColumns(const WallDrawerArgs& 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;
void DrawColoredSpan(const SpanDrawerArgs &args) override { Queue->Push<DrawColoredSpanRGBACommand>(args); }
void DrawFogBoundaryLine(const SpanDrawerArgs &args) override { Queue->Push<DrawFogBoundaryLineRGBACommand>(args); }
};
/////////////////////////////////////////////////////////////////////////////

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -54,10 +54,14 @@ namespace swrenderer
}
template<typename BlendT, typename SamplerT>
class DrawSprite32T
class DrawSprite32T : public DrawerCommand
{
public:
static void DrawColumn(const SpriteDrawerArgs& args)
SpriteDrawerArgs args;
DrawSprite32T(const SpriteDrawerArgs &drawerargs) : args(drawerargs) { }
void Execute(DrawerThread *thread) override
{
using namespace DrawSprite32TModes;
@ -70,33 +74,33 @@ namespace swrenderer
if (shade_constants.simple_shade)
{
if (is_nearest_filter)
Loop<SimpleShade, NearestFilter>(args, shade_constants);
Loop<SimpleShade, NearestFilter>(thread, shade_constants);
else
Loop<SimpleShade, LinearFilter>(args, shade_constants);
Loop<SimpleShade, LinearFilter>(thread, shade_constants);
}
else
{
if (is_nearest_filter)
Loop<AdvancedShade, NearestFilter>(args, shade_constants);
Loop<AdvancedShade, NearestFilter>(thread, shade_constants);
else
Loop<AdvancedShade, LinearFilter>(args, shade_constants);
Loop<AdvancedShade, LinearFilter>(thread, shade_constants);
}
}
else // no linear filtering for translated, shaded or fill
{
if (shade_constants.simple_shade)
{
Loop<SimpleShade, NearestFilter>(args, shade_constants);
Loop<SimpleShade, NearestFilter>(thread, shade_constants);
}
else
{
Loop<AdvancedShade, NearestFilter>(args, shade_constants);
Loop<AdvancedShade, NearestFilter>(thread, shade_constants);
}
}
}
template<typename ShadeModeT, typename FilterModeT>
FORCEINLINE static void VECTORCALL Loop(const SpriteDrawerArgs& args, ShadeConstants shade_constants)
FORCEINLINE void VECTORCALL Loop(DrawerThread *thread, ShadeConstants shade_constants)
{
using namespace DrawSprite32TModes;
@ -158,7 +162,6 @@ namespace swrenderer
}
int count = args.Count();
if (count <= 0) return;
int pitch = args.Viewport()->RenderTarget->GetPitch();
uint32_t fracstep = args.TextureVStep();
uint32_t frac = args.TextureVPos();
@ -166,6 +169,13 @@ namespace swrenderer
uint32_t *dest = (uint32_t*)args.Dest();
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)
{
frac -= one / 2;
@ -245,7 +255,7 @@ namespace swrenderer
}
template<typename FilterModeT>
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)
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)
{
using namespace DrawSprite32TModes;
@ -294,7 +304,7 @@ namespace swrenderer
}
}
FORCEINLINE static unsigned int VECTORCALL SampleShade(uint32_t frac, const uint32_t *source, const uint8_t *colormap)
FORCEINLINE unsigned int VECTORCALL SampleShade(uint32_t frac, const uint32_t *source, const uint8_t *colormap)
{
using namespace DrawSprite32TModes;
@ -311,7 +321,7 @@ namespace swrenderer
}
template<typename ShadeModeT>
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)
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)
{
using namespace DrawSprite32TModes;
@ -350,7 +360,7 @@ namespace swrenderer
}
}
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)
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)
{
using namespace DrawSprite32TModes;

View file

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

View file

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

View file

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

View file

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

View file

@ -53,9 +53,6 @@
#include "swrenderer/drawers/r_draw_pal.h"
#include "swrenderer/viewport/r_viewport.h"
#include "r_memory.h"
#include "common/rendering/polyrenderer/drawers/poly_thread.h"
std::pair<PalEntry, PalEntry>& R_GetSkyCapColor(FGameTexture* tex);
namespace swrenderer
{
@ -66,6 +63,7 @@ namespace swrenderer
FrameMemory.reset(new RenderMemory());
Viewport.reset(new RenderViewport());
Light.reset(new LightVisibility());
DrawQueue.reset(new DrawerCommandQueue(FrameMemory.get()));
OpaquePass.reset(new RenderOpaquePass(this));
TranslucentPass.reset(new RenderTranslucentPass(this));
SpriteList.reset(new VisibleSpriteList());
@ -75,9 +73,8 @@ namespace swrenderer
PlaneList.reset(new VisiblePlaneList(this));
DrawSegments.reset(new DrawSegmentList(this));
ClipSegments.reset(new RenderClipSegment());
Poly.reset(new PolyTriangleThreadData(0, 1, 0, 1, 0, screen->GetHeight()));
tc_drawers.reset(new SWTruecolorDrawers(this));
pal_drawers.reset(new SWPalDrawers(this));
tc_drawers.reset(new SWTruecolorDrawers(DrawQueue));
pal_drawers.reset(new SWPalDrawers(DrawQueue));
}
RenderThread::~RenderThread()
@ -92,13 +89,33 @@ namespace swrenderer
return pal_drawers.get();
}
std::mutex loadmutex;
static 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::pair<PalEntry, PalEntry> colors = R_GetSkyCapColor(tex->GetTexture());
return colors;
const FSoftwareTextureSpan *spans;
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;

View file

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

View file

@ -66,14 +66,14 @@ void PeekThreadedErrorPane();
EXTERN_CVAR(Int, r_clearbuffer)
EXTERN_CVAR(Int, r_debug_draw)
CVAR(Int, r_scene_multithreaded, 1, 0);
CVAR(Int, r_scene_multithreaded, 0, 0);
CVAR(Bool, r_models, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
bool r_modelscene = false;
namespace swrenderer
{
cycle_t WallCycles, PlaneCycles, MaskedCycles;
cycle_t WallCycles, PlaneCycles, MaskedCycles, DrawerWaitCycles;
RenderScene::RenderScene()
{
@ -131,6 +131,7 @@ namespace swrenderer
for (int i = 0; i < size; i++)
dest[i] = bgracolor.d;
}
DrawerThreads::ResetDebugDrawPos();
}
RenderActorView(player->mo, true, false);
@ -140,8 +141,11 @@ namespace swrenderer
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);
DrawerThreads::Execute(copyqueue);
DrawerThreads::WaitForWorkers();
}
DrawerWaitCycles.Clock();
DrawerThreads::WaitForWorkers();
DrawerWaitCycles.Unclock();
}
void RenderScene::RenderActorView(AActor *actor, bool renderPlayerSprites, bool dontmaplines)
@ -149,6 +153,7 @@ namespace swrenderer
WallCycles.Reset();
PlaneCycles.Reset();
MaskedCycles.Reset();
DrawerWaitCycles.Reset();
R_SetupFrame(MainThread()->Viewport->viewpoint, MainThread()->Viewport->viewwindow, actor);
@ -189,7 +194,14 @@ namespace swrenderer
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();
DrawerThreads::Execute(MainThread()->DrawQueue);
}
void RenderScene::RenderThreadSlices()
@ -219,7 +231,6 @@ namespace swrenderer
Threads[i]->X2 = viewwidth * (i + 1) / numThreads;
}
run_id++;
FSoftwareTexture::CurrentUpdate = run_id;
start_lock.unlock();
// Notify threads to run
@ -256,6 +267,7 @@ namespace swrenderer
void RenderScene::RenderThreadSlice(RenderThread *thread)
{
thread->DrawQueue->Clear();
thread->FrameMemory->Clear();
thread->Clip3D->Cleanup();
thread->Clip3D->ResetClip(); // reset clips (floor/ceiling)
@ -294,37 +306,7 @@ namespace swrenderer
thread->TranslucentPass->Render();
}
#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
DrawerThreads::Execute(thread->DrawQueue);
}
void RenderScene::StartThreads(size_t numThreads)
@ -408,6 +390,9 @@ namespace swrenderer
// Render:
RenderActorView(actor, false, dontmaplines);
DrawerWaitCycles.Clock();
DrawerThreads::WaitForWorkers();
DrawerWaitCycles.Unclock();
viewport->RenderingToCanvas = false;
@ -433,12 +418,12 @@ namespace swrenderer
ADD_STAT(fps)
{
FString out;
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());
out.Format("frame=%04.1f ms walls=%04.1f ms planes=%04.1f ms masked=%04.1f ms drawers=%04.1f ms",
FrameCycles.TimeMS(), WallCycles.TimeMS(), PlaneCycles.TimeMS(), MaskedCycles.TimeMS(), DrawerWaitCycles.TimeMS());
return out;
}
static double f_acc, w_acc, p_acc, m_acc;
static double f_acc, w_acc, p_acc, m_acc, drawer_acc;
static int acc_c;
ADD_STAT(fps_accumulated)
@ -447,10 +432,11 @@ namespace swrenderer
w_acc += WallCycles.TimeMS();
p_acc += PlaneCycles.TimeMS();
m_acc += MaskedCycles.TimeMS();
drawer_acc += DrawerWaitCycles.TimeMS();
acc_c++;
FString out;
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, acc_c);
out.Format("frame=%04.1f ms walls=%04.1f ms planes=%04.1f ms masked=%04.1f ms drawers=%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);
Printf(PRINT_LOG, "%s\n", out.GetChars());
return out;
}

View file

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

View file

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

View file

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

View file

@ -57,7 +57,7 @@ bool FWarpTexture::CheckModified (int style)
return screen->FrameTime != GenTime[style];
}
const uint32_t *FWarpTexture::GetPixelsBgraLocked()
const uint32_t *FWarpTexture::GetPixelsBgra()
{
uint64_t time = screen->FrameTime;
uint64_t resizeMult = gl_texture_hqresizemult;
@ -67,7 +67,7 @@ const uint32_t *FWarpTexture::GetPixelsBgraLocked()
if (gl_texture_hqresizemode == 0 || gl_texture_hqresizemult < 1 || !(gl_texture_hqresize_targets & 1))
resizeMult = 1;
auto otherpix = FSoftwareTexture::GetPixelsBgraLocked();
auto otherpix = FSoftwareTexture::GetPixelsBgra();
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);
GenerateBgraMipmapsFast();
@ -78,7 +78,7 @@ const uint32_t *FWarpTexture::GetPixelsBgraLocked()
}
const uint8_t *FWarpTexture::GetPixelsLocked(int index)
const uint8_t *FWarpTexture::GetPixels(int index)
{
uint64_t time = screen->FrameTime;
uint64_t resizeMult = gl_texture_hqresizemult;
@ -88,7 +88,7 @@ const uint8_t *FWarpTexture::GetPixelsLocked(int index)
if (gl_texture_hqresizemode == 0 || gl_texture_hqresizemult < 1 || !(gl_texture_hqresize_targets & 1))
resizeMult = 1;
const uint8_t *otherpix = FSoftwareTexture::GetPixelsLocked(index);
const uint8_t *otherpix = FSoftwareTexture::GetPixels(index);
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);
FreeAllSpans();

View file

@ -240,6 +240,7 @@ namespace swrenderer
bool visible = drawerargs.SetStyle(thread->Viewport.get(), decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor, cmlight);
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);
}

View file

@ -231,6 +231,7 @@ namespace swrenderer
{
auto vis = this;
int spacing;
uint8_t color = vis->Light.BaseColormap->Maps[vis->startfrac];
int yl = vis->y1;
int ycount = vis->y2 - yl + 1;
@ -249,18 +250,33 @@ namespace swrenderer
uint32_t alpha = fglevel * 256 / FRACUNIT;
auto viewport = thread->Viewport.get();
auto drawers = thread->Drawers(viewport);
spacing = viewport->RenderTarget->GetPitch();
uint32_t fracstepx = PARTICLE_TEXTURE_SIZE * FRACUNIT / countbase;
uint32_t fracposx = fracstepx / 2;
RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();
for (int x = x1; x < (x1 + countbase); x++, fracposx += fracstepx)
if (viewport->RenderTarget->IsBgra())
{
if (translucentPass->ClipSpriteColumnWithPortals(x, vis))
continue;
drawers->DrawParticleColumn(x, yl, ycount, fg, alpha, fracposx);
for (int x = x1; x < (x1 + countbase); x++, fracposx += fracstepx)
{
if (translucentPass->ClipSpriteColumnWithPortals(x, vis))
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,7 +262,8 @@ namespace swrenderer
{
RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();
short portalfloorclip[MAXWIDTH];
for (int x = x1; x < x2; x++)
int x2 = wallc.sx2;
for (int x = wallc.sx1; x < x2; x++)
{
if (translucentPass->ClipSpriteColumnWithPortals(x, this))
portalfloorclip[x] = mceilingclip[x];
@ -270,6 +271,8 @@ namespace swrenderer
portalfloorclip[x] = mfloorclip[x];
}
thread->PrepareTexture(pic, RenderStyle);
ProjectedWallLight mlight;
mlight.SetSpriteLight();

View file

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

View file

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

View file

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