From a5cba1aba5f5d449a1590a2a1ce7f55a593628d2 Mon Sep 17 00:00:00 2001 From: Xaser Acheron Date: Thu, 25 Mar 2021 19:58:08 -0500 Subject: [PATCH] Merge dpJudas's renderslices branch (#1356) * Remove threading from the drawers * Fix some r_scene_multithreaded related bugs * Fix some r_scene_multithreaded crashes * Fix fullbright shade bug * Fix truecolor drawer crash * Add debug code for showing the render slices * Fix texture loading race condition and improve performance by only locking the load mutex if data hasn't already been updated for this frame Co-authored-by: Magnus Norddahl --- src/rendering/swrenderer/drawers/r_draw.cpp | 401 +----- src/rendering/swrenderer/drawers/r_draw.h | 16 +- .../swrenderer/drawers/r_draw_pal.cpp | 1168 ++++++++--------- src/rendering/swrenderer/drawers/r_draw_pal.h | 336 +---- .../swrenderer/drawers/r_draw_rgba.cpp | 499 ++++--- .../swrenderer/drawers/r_draw_rgba.h | 170 +-- .../swrenderer/drawers/r_draw_sky32.h | 65 +- .../swrenderer/drawers/r_draw_sky32_sse2.h | 88 +- .../swrenderer/drawers/r_draw_span32.h | 37 +- .../swrenderer/drawers/r_draw_span32_sse2.h | 37 +- .../swrenderer/drawers/r_draw_sprite32.h | 39 +- .../swrenderer/drawers/r_draw_sprite32_sse2.h | 38 +- .../swrenderer/drawers/r_draw_wall32.h | 39 +- .../swrenderer/drawers/r_draw_wall32_sse2.h | 37 +- src/rendering/swrenderer/line/r_walldraw.cpp | 2 - src/rendering/swrenderer/plane/r_skyplane.cpp | 12 +- src/rendering/swrenderer/r_renderthread.cpp | 39 +- src/rendering/swrenderer/r_renderthread.h | 12 +- src/rendering/swrenderer/scene/r_scene.cpp | 66 +- .../swrenderer/textures/r_swtexture.cpp | 90 +- .../swrenderer/textures/r_swtexture.h | 80 +- .../swrenderer/textures/swcanvastexture.cpp | 4 +- .../swrenderer/textures/warptexture.cpp | 8 +- src/rendering/swrenderer/things/r_decal.cpp | 1 - .../swrenderer/things/r_particle.cpp | 26 +- src/rendering/swrenderer/things/r_sprite.cpp | 5 +- .../swrenderer/things/r_wallsprite.cpp | 2 - .../swrenderer/viewport/r_spandrawer.cpp | 2 - .../swrenderer/viewport/r_spritedrawer.h | 4 +- 29 files changed, 1336 insertions(+), 1987 deletions(-) diff --git a/src/rendering/swrenderer/drawers/r_draw.cpp b/src/rendering/swrenderer/drawers/r_draw.cpp index 2d191b32852..797f6562620 100644 --- a/src/rendering/swrenderer/drawers/r_draw.cpp +++ b/src/rendering/swrenderer/drawers/r_draw.cpp @@ -221,238 +221,7 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////// - DrawWallCommand::DrawWallCommand(const WallDrawerArgs& args) : wallargs(args) - { - } - - void DrawWallCommand::Execute(DrawerThread* thread) - { - if (!thread->columndrawer) - thread->columndrawer = std::make_shared(); - - 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(texelStepX)* (1.0 / 0x1'0000'0000LL)); - double ymagnitude = fabs(static_cast(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(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(wallargs.texpixels) + (((texelX >> 16)* texwidth) >> 16)* texheight; - - texelY = (static_cast(texelY)* texheight) >> (32 - fracbits); - texelStepY = (static_cast(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) + void SWPixelFormatDrawers::DrawDepthColumn(const WallColumnDrawerArgs& args, float idepth) { int x, y, count; @@ -477,15 +246,11 @@ namespace swrenderer } count = args.Count(); - auto zbuffer = PolyTriangleThreadData::Get(thread)->depthstencil; + auto zbuffer = thread->Poly->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++) { @@ -494,7 +259,7 @@ namespace swrenderer } } - void DrawWallCommand::SetLights(WallColumnDrawerArgs& drawerargs, int x, int y1) + void SWPixelFormatDrawers::SetLights(WallColumnDrawerArgs& drawerargs, int x, int y1, const WallDrawerArgs& wallargs) { bool mirror = !!(wallargs.PortalMirrorFlags & RF_XFLIP); int tx = x; @@ -560,130 +325,74 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////// - class DepthSkyColumnCommand : public DrawerCommand + void SWPixelFormatDrawers::DrawDepthSkyColumn(const SkyDrawerArgs &args, float idepth) { - public: - DepthSkyColumnCommand(const SkyDrawerArgs &args, float idepth) : idepth(idepth) + int x, y, count; + auto rendertarget = args.Viewport()->RenderTarget; + if (rendertarget->IsBgra()) { - 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(); + 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(); } - - void Execute(DrawerThread *thread) override + else { - 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; - } + 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(); - private: - int x, y, count; - float idepth; - }; - - // #define DEPTH_DEBUG + auto zbuffer = thread->Poly->depthstencil; + int pitch = zbuffer->Width(); + float* values = zbuffer->DepthValues() + y * pitch + x; + int cnt = count; - class DepthSpanCommand : public DrawerCommand - { - public: - DepthSpanCommand(const SpanDrawerArgs &args, float idepth1, float idepth2) : idepth1(idepth1), idepth2(idepth2) + float depth = idepth; + for (int i = 0; i < cnt; i++) { - y = args.DestY(); - x1 = args.DestX1(); - x2 = args.DestX2(); - #ifdef DEPTH_DEBUG - dest = (uint32_t*)args.Viewport()->GetDest(0, args.DestY()); - #endif + *values = depth; + values += pitch; } + } - void Execute(DrawerThread *thread) override - { - if (thread->skipped_by_thread(y)) - return; + 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; - auto zbuffer = PolyTriangleThreadData::Get(thread)->depthstencil; - int pitch = zbuffer->Width(); - float *values = zbuffer->DepthValues() + y * pitch; - int end = x2; + int count = x2 - x1 + 1; - if (idepth1 == idepth2) + if (idepth1 == idepth2) + { + float depth = idepth1; + for (int i = 0; i < count; i++) { - float depth = idepth1; - #ifdef DEPTH_DEBUG - uint32_t gray = clamp((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 - } + *values = depth; + values++; } - else + } + else + { + float depth = idepth1; + float step = (idepth2 - idepth1) / (x2 - x1 + 1); + for (int i = 0; i < count; i++) { - 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)(1.0f / depth / 4.0f), 0, 255); - uint32_t color = MAKEARGB(255, gray, gray, gray); - dest[x] = color; - #endif - - values[x] = depth; - depth += step; - } + *values = depth; + values++; + 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) - { - Queue->Push(args, idepth); - } - - void SWPixelFormatDrawers::DrawDepthSpan(const SpanDrawerArgs &args, float idepth1, float idepth2) - { - Queue->Push(args, idepth1, idepth2); } } diff --git a/src/rendering/swrenderer/drawers/r_draw.h b/src/rendering/swrenderer/drawers/r_draw.h index 32eba2db07e..be261959554 100644 --- a/src/rendering/swrenderer/drawers/r_draw.h +++ b/src/rendering/swrenderer/drawers/r_draw.h @@ -19,14 +19,12 @@ EXTERN_CVAR(Float, transsouls); EXTERN_CVAR(Bool, r_dynlights); EXTERN_CVAR(Bool, r_fuzzscale); -class DrawerCommandQueue; -typedef std::shared_ptr DrawerCommandQueuePtr; - namespace swrenderer { class DrawerArgs; class SkyDrawerArgs; class WallDrawerArgs; + class WallColumnDrawerArgs; class SpanDrawerArgs; class SpriteDrawerArgs; class VoxelBlock; @@ -55,8 +53,8 @@ namespace swrenderer class SWPixelFormatDrawers { public: - SWPixelFormatDrawers(DrawerCommandQueuePtr queue) : Queue(queue) { } - virtual ~SWPixelFormatDrawers() { } + SWPixelFormatDrawers(RenderThread* thread) : thread(thread) { } + virtual ~SWPixelFormatDrawers() = default; virtual void DrawWall(const WallDrawerArgs &args) = 0; virtual void DrawWallMasked(const WallDrawerArgs &args) = 0; virtual void DrawWallAdd(const WallDrawerArgs &args) = 0; @@ -94,11 +92,15 @@ namespace swrenderer virtual void DrawTiltedSpan(const SpanDrawerArgs &args, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap) = 0; virtual void 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); - - DrawerCommandQueuePtr Queue; + + void SetLights(WallColumnDrawerArgs& drawerargs, int x, int y1, const WallDrawerArgs& wallargs); + + RenderThread* thread = nullptr; }; void R_InitShadeMaps(); diff --git a/src/rendering/swrenderer/drawers/r_draw_pal.cpp b/src/rendering/swrenderer/drawers/r_draw_pal.cpp index af42a7f352e..8cc7a0fc8a8 100644 --- a/src/rendering/swrenderer/drawers/r_draw_pal.cpp +++ b/src/rendering/swrenderer/drawers/r_draw_pal.cpp @@ -93,7 +93,7 @@ EXTERN_CVAR(Int, gl_particles_style) namespace swrenderer { - uint8_t PalWall1Command::AddLights(const DrawerLight *lights, int num_lights, float viewpos_z, uint8_t fg, uint8_t material) + uint8_t SWPalDrawers::AddLightsColumn(const DrawerLight *lights, int num_lights, float viewpos_z, uint8_t fg, uint8_t material) { uint32_t lit_r = 0; uint32_t lit_g = 0; @@ -146,12 +146,16 @@ namespace swrenderer return RGB256k.All[((lit_r >> 2) << 12) | ((lit_g >> 2) << 6) | (lit_b >> 2)]; } - void DrawWall1PalCommand::DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) + template<> + void SWPalDrawers::DrawWallColumn(const WallColumnDrawerArgs& args) { + int count = args.Count(); + if (count <= 0) + return; + uint32_t fracstep = args.TextureVStep(); uint32_t frac = args.TextureVPos(); uint8_t *colormap = args.Colormap(args.Viewport()); - int count = args.Count(); const uint8_t *source = args.TexturePixels(); uint8_t *dest = args.Dest(); int bits = args.TextureFracBits(); @@ -161,15 +165,6 @@ namespace swrenderer float viewpos_z = args.dc_viewpos.Z; float step_viewpos_z = args.dc_viewpos_step.Z; - count = thread->count_for_thread(args.DestY(), count); - if (count <= 0) - return; - - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; - if (num_dynlights == 0) { do @@ -184,12 +179,9 @@ namespace swrenderer float viewpos_z = args.dc_viewpos.Z; float step_viewpos_z = args.dc_viewpos_step.Z; - viewpos_z += step_viewpos_z * thread->skipped_by_thread(args.DestY()); - step_viewpos_z *= thread->num_cores; - do { - *dest = AddLights(dynlights, num_dynlights, viewpos_z, colormap[source[frac >> bits]], source[frac >> bits]); + *dest = AddLightsColumn(dynlights, num_dynlights, viewpos_z, colormap[source[frac >> bits]], source[frac >> bits]); viewpos_z += step_viewpos_z; frac += fracstep; dest += pitch; @@ -197,12 +189,16 @@ namespace swrenderer } } - void DrawWallMasked1PalCommand::DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) + template<> + void SWPalDrawers::DrawWallColumn(const WallColumnDrawerArgs& args) { + int count = args.Count(); + if (count <= 0) + return; + uint32_t fracstep = args.TextureVStep(); uint32_t frac = args.TextureVPos(); uint8_t *colormap = args.Colormap(args.Viewport()); - int count = args.Count(); const uint8_t *source = args.TexturePixels(); uint8_t *dest = args.Dest(); int bits = args.TextureFracBits(); @@ -212,15 +208,6 @@ namespace swrenderer float viewpos_z = args.dc_viewpos.Z; float step_viewpos_z = args.dc_viewpos_step.Z; - count = thread->count_for_thread(args.DestY(), count); - if (count <= 0) - return; - - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; - if (num_dynlights == 0) { do @@ -239,15 +226,12 @@ namespace swrenderer float viewpos_z = args.dc_viewpos.Z; float step_viewpos_z = args.dc_viewpos_step.Z; - viewpos_z += step_viewpos_z * thread->skipped_by_thread(args.DestY()); - step_viewpos_z *= thread->num_cores; - do { uint8_t pix = source[frac >> bits]; if (pix != 0) { - *dest = AddLights(dynlights, num_dynlights, viewpos_z, colormap[pix], pix); + *dest = AddLightsColumn(dynlights, num_dynlights, viewpos_z, colormap[pix], pix); } viewpos_z += step_viewpos_z; frac += fracstep; @@ -256,12 +240,16 @@ namespace swrenderer } } - void DrawWallAdd1PalCommand::DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) + template<> + void SWPalDrawers::DrawWallColumn(const WallColumnDrawerArgs& args) { + int count = args.Count(); + if (count <= 0) + return; + uint32_t fracstep = args.TextureVStep(); uint32_t frac = args.TextureVPos(); uint8_t *colormap = args.Colormap(args.Viewport()); - int count = args.Count(); const uint8_t *source = args.TexturePixels(); uint8_t *dest = args.Dest(); int bits = args.TextureFracBits(); @@ -270,15 +258,6 @@ namespace swrenderer uint32_t *fg2rgb = args.SrcBlend(); uint32_t *bg2rgb = args.DestBlend(); - count = thread->count_for_thread(args.DestY(), count); - if (count <= 0) - return; - - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; - if (!r_blendmethod) { do @@ -318,12 +297,16 @@ namespace swrenderer } } - void DrawWallAddClamp1PalCommand::DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) + template<> + void SWPalDrawers::DrawWallColumn(const WallColumnDrawerArgs& args) { + int count = args.Count(); + if (count <= 0) + return; + uint32_t fracstep = args.TextureVStep(); uint32_t frac = args.TextureVPos(); uint8_t *colormap = args.Colormap(args.Viewport()); - int count = args.Count(); const uint8_t *source = args.TexturePixels(); uint8_t *dest = args.Dest(); int bits = args.TextureFracBits(); @@ -336,17 +319,6 @@ namespace swrenderer uint32_t *fg2rgb = args.SrcBlend(); uint32_t *bg2rgb = args.DestBlend(); - count = thread->count_for_thread(args.DestY(), count); - if (count <= 0) - return; - - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; - viewpos_z += step_viewpos_z * thread->skipped_by_thread(args.DestY()); - step_viewpos_z *= thread->num_cores; - if (!r_blendmethod) { do @@ -354,7 +326,7 @@ namespace swrenderer uint8_t pix = source[frac >> bits]; if (pix != 0) { - uint8_t lit = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_z, colormap[pix], pix) : colormap[pix]; + uint8_t lit = num_dynlights != 0 ? AddLightsColumn(dynlights, num_dynlights, viewpos_z, colormap[pix], pix) : colormap[pix]; uint32_t a = fg2rgb[lit] + bg2rgb[*dest]; uint32_t b = a; @@ -378,7 +350,7 @@ namespace swrenderer uint8_t pix = source[frac >> bits]; if (pix != 0) { - uint8_t lit = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_z, colormap[pix], pix) : colormap[pix]; + uint8_t lit = num_dynlights != 0 ? AddLightsColumn(dynlights, num_dynlights, viewpos_z, colormap[pix], pix) : colormap[pix]; uint32_t r = MIN(GPalette.BaseColors[lit].r + GPalette.BaseColors[*dest].r, 255); uint32_t g = MIN(GPalette.BaseColors[lit].g + GPalette.BaseColors[*dest].g, 255); @@ -392,12 +364,16 @@ namespace swrenderer } } - void DrawWallSubClamp1PalCommand::DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) + template<> + void SWPalDrawers::DrawWallColumn(const WallColumnDrawerArgs& args) { + int count = args.Count(); + if (count <= 0) + return; + uint32_t fracstep = args.TextureVStep(); uint32_t frac = args.TextureVPos(); uint8_t *colormap = args.Colormap(args.Viewport()); - int count = args.Count(); const uint8_t *source = args.TexturePixels(); uint8_t *dest = args.Dest(); int bits = args.TextureFracBits(); @@ -410,17 +386,6 @@ namespace swrenderer uint32_t *fg2rgb = args.SrcBlend(); uint32_t *bg2rgb = args.DestBlend(); - count = thread->count_for_thread(args.DestY(), count); - if (count <= 0) - return; - - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; - viewpos_z += step_viewpos_z * thread->skipped_by_thread(args.DestY()); - step_viewpos_z *= thread->num_cores; - if (!r_blendmethod) { do @@ -428,7 +393,7 @@ namespace swrenderer uint8_t pix = source[frac >> bits]; if (pix != 0) { - uint8_t lit = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_z, colormap[pix], pix) : colormap[pix]; + uint8_t lit = num_dynlights != 0 ? AddLightsColumn(dynlights, num_dynlights, viewpos_z, colormap[pix], pix) : colormap[pix]; uint32_t a = (fg2rgb[lit] | 0x40100400) - bg2rgb[*dest]; uint32_t b = a; @@ -451,7 +416,7 @@ namespace swrenderer uint8_t pix = source[frac >> bits]; if (pix != 0) { - uint8_t lit = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_z, colormap[pix], pix) : colormap[pix]; + uint8_t lit = num_dynlights != 0 ? AddLightsColumn(dynlights, num_dynlights, viewpos_z, colormap[pix], pix) : colormap[pix]; int r = clamp(-GPalette.BaseColors[lit].r + GPalette.BaseColors[*dest].r, 0, 255); int g = clamp(-GPalette.BaseColors[lit].g + GPalette.BaseColors[*dest].g, 0, 255); @@ -465,12 +430,16 @@ namespace swrenderer } } - void DrawWallRevSubClamp1PalCommand::DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) + template<> + void SWPalDrawers::DrawWallColumn(const WallColumnDrawerArgs& args) { + int count = args.Count(); + if (count <= 0) + return; + uint32_t fracstep = args.TextureVStep(); uint32_t frac = args.TextureVPos(); uint8_t *colormap = args.Colormap(args.Viewport()); - int count = args.Count(); const uint8_t *source = args.TexturePixels(); uint8_t *dest = args.Dest(); int bits = args.TextureFracBits(); @@ -483,17 +452,6 @@ namespace swrenderer uint32_t *fg2rgb = args.SrcBlend(); uint32_t *bg2rgb = args.DestBlend(); - count = thread->count_for_thread(args.DestY(), count); - if (count <= 0) - return; - - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; - viewpos_z += step_viewpos_z * thread->skipped_by_thread(args.DestY()); - step_viewpos_z *= thread->num_cores; - if (!r_blendmethod) { do @@ -501,7 +459,7 @@ namespace swrenderer uint8_t pix = source[frac >> bits]; if (pix != 0) { - uint8_t lit = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_z, colormap[pix], pix) : colormap[pix]; + uint8_t lit = num_dynlights != 0 ? AddLightsColumn(dynlights, num_dynlights, viewpos_z, colormap[pix], pix) : colormap[pix]; uint32_t a = (bg2rgb[*dest] | 0x40100400) - fg2rgb[lit]; uint32_t b = a; @@ -524,7 +482,7 @@ namespace swrenderer uint8_t pix = source[frac >> bits]; if (pix != 0) { - uint8_t lit = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_z, colormap[pix], pix) : colormap[pix]; + uint8_t lit = num_dynlights != 0 ? AddLightsColumn(dynlights, num_dynlights, viewpos_z, colormap[pix], pix) : colormap[pix]; int r = clamp(GPalette.BaseColors[lit].r - GPalette.BaseColors[*dest].r, 0, 255); int g = clamp(GPalette.BaseColors[lit].g - GPalette.BaseColors[*dest].g, 0, 255); @@ -540,11 +498,7 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////// - PalSkyCommand::PalSkyCommand(const SkyDrawerArgs &args) : args(args) - { - } - - void DrawSingleSky1PalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawSingleSkyColumn(const SkyDrawerArgs& args) { uint8_t *dest = args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); @@ -554,31 +508,10 @@ namespace swrenderer int32_t frac = args.TextureVPos(); int32_t fracstep = args.TextureVStep(); - 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 - 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; + int count = args.Count(); if (!args.FadeSky()) { - 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; @@ -590,6 +523,18 @@ 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); + uint32_t solid_top = args.SolidTopColor(); uint32_t solid_bottom = args.SolidBottomColor(); @@ -604,7 +549,7 @@ namespace swrenderer const uint32_t *palette = (const uint32_t *)GPalette.BaseColors; - int index = skipped; + int index = 0; // Top solid color: while (index < start_fadetop_y) @@ -612,7 +557,7 @@ namespace swrenderer *dest = solid_top_fill; dest += pitch; frac += fracstep; - index += num_cores; + index++; } // Top fade: @@ -634,7 +579,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Textured center: @@ -645,7 +590,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Fade bottom: @@ -667,7 +612,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Bottom solid color: @@ -675,11 +620,11 @@ namespace swrenderer { *dest = solid_bottom_fill; dest += pitch; - index += num_cores; + index++; } } - void DrawDoubleSky1PalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawDoubleSkyColumn(const SkyDrawerArgs& args) { uint8_t *dest = args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); @@ -691,31 +636,9 @@ namespace swrenderer int32_t frac = args.TextureVPos(); int32_t fracstep = args.TextureVStep(); - 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 - 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; - + int count = args.Count(); if (!args.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; @@ -734,6 +657,18 @@ 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); + uint32_t solid_top = args.SolidTopColor(); uint32_t solid_bottom = args.SolidBottomColor(); @@ -748,7 +683,7 @@ namespace swrenderer const uint32_t *palette = (const uint32_t *)GPalette.BaseColors; - int index = skipped; + int index = 0; // Top solid color: while (index < start_fadetop_y) @@ -756,7 +691,7 @@ namespace swrenderer *dest = solid_top_fill; dest += pitch; frac += fracstep; - index += num_cores; + index++; } // Top fade: @@ -783,7 +718,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Textured center: @@ -800,7 +735,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Fade bottom: @@ -827,7 +762,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Bottom solid color: @@ -835,17 +770,13 @@ namespace swrenderer { *dest = solid_bottom_fill; dest += pitch; - index += num_cores; + index++; } } ///////////////////////////////////////////////////////////////////////// - PalColumnCommand::PalColumnCommand(const SpriteDrawerArgs &args) : args(args) - { - } - - uint8_t PalColumnCommand::AddLights(uint8_t fg, uint8_t material, uint32_t lit_r, uint32_t lit_g, uint32_t lit_b) + uint8_t SWPalDrawers::AddLights(uint8_t fg, uint8_t material, uint32_t lit_r, uint32_t lit_g, uint32_t lit_b) { if (lit_r == 0 && lit_g == 0 && lit_b == 0) return fg; @@ -861,7 +792,7 @@ namespace swrenderer return RGB256k.All[((lit_r >> 2) << 12) | ((lit_g >> 2) << 6) | (lit_b >> 2)]; } - void DrawColumnPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawColumn(const SpriteDrawerArgs& args) { int count; uint8_t *dest; @@ -869,6 +800,8 @@ namespace swrenderer fixed_t fracstep; count = args.Count(); + if (count <= 0) + return; // Framebuffer destination address. dest = args.Dest(); @@ -878,15 +811,7 @@ namespace swrenderer fracstep = args.TextureVStep(); frac = args.TextureVPos(); - count = thread->count_for_thread(args.DestY(), count); - if (count <= 0) - return; - int pitch = args.Viewport()->RenderTarget->GetPitch(); - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; // [RH] Get local copies of these variables so that the compiler // has a better chance of optimizing this well. @@ -931,21 +856,15 @@ namespace swrenderer } } - void FillColumnPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::FillColumn(const SpriteDrawerArgs& args) { - int count; - uint8_t *dest; - - count = args.Count(); - dest = args.Dest(); - - count = thread->count_for_thread(args.DestY(), count); + int count = args.Count(); if (count <= 0) return; + uint8_t* dest = args.Dest(); + int pitch = args.Viewport()->RenderTarget->GetPitch(); - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - pitch *= thread->num_cores; uint8_t color = args.SolidColor(); do @@ -955,26 +874,17 @@ namespace swrenderer } while (--count); } - void FillColumnAddPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::FillAddColumn(const SpriteDrawerArgs& args) { - int count; - uint8_t *dest; - - count = args.Count(); - dest = args.Dest(); - uint32_t *bg2rgb; - uint32_t fg; - - bg2rgb = args.DestBlend(); - fg = args.SrcColorIndex(); - int pitch = args.Viewport()->RenderTarget->GetPitch(); - - count = thread->count_for_thread(args.DestY(), count); + int count = args.Count(); if (count <= 0) return; - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - pitch *= thread->num_cores; + uint8_t* dest = args.Dest(); + int pitch = args.Viewport()->RenderTarget->GetPitch(); + + uint32_t *bg2rgb = args.DestBlend(); + uint32_t fg = args.SrcColorIndex(); const PalEntry* pal = GPalette.BaseColors; @@ -1007,12 +917,14 @@ namespace swrenderer } } - void FillColumnAddClampPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::FillAddClampColumn(const SpriteDrawerArgs& args) { int count; uint8_t *dest; count = args.Count(); + if (count <= 0) + return; dest = args.Dest(); uint32_t *bg2rgb; @@ -1022,13 +934,6 @@ namespace swrenderer fg = args.SrcColorIndex(); int pitch = args.Viewport()->RenderTarget->GetPitch(); - count = thread->count_for_thread(args.DestY(), count); - if (count <= 0) - return; - - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - pitch *= thread->num_cores; - const PalEntry* pal = GPalette.BaseColors; if (!r_blendmethod) @@ -1066,26 +971,18 @@ namespace swrenderer } } - void FillColumnSubClampPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::FillSubClampColumn(const SpriteDrawerArgs& args) { - int count; - uint8_t *dest; + int count = args.Count(); + if (count <= 0) + return; - count = args.Count(); + uint8_t* dest = args.Dest(); + int pitch = args.Viewport()->RenderTarget->GetPitch(); - dest = args.Dest(); uint32_t *bg2rgb = args.DestBlend(); uint32_t fg = args.SrcColorIndex(); - int pitch = args.Viewport()->RenderTarget->GetPitch(); - - count = thread->count_for_thread(args.DestY(), count); - if (count <= 0) - return; - - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - pitch *= thread->num_cores; - const PalEntry* palette = GPalette.BaseColors; if (!r_blendmethod) @@ -1124,27 +1021,17 @@ namespace swrenderer } } - void FillColumnRevSubClampPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::FillRevSubClampColumn(const SpriteDrawerArgs& args) { - int count; - uint8_t *dest; - - count = args.Count(); + int count = args.Count(); if (count <= 0) return; - dest = args.Dest(); - uint32_t *bg2rgb = args.DestBlend(); - uint32_t fg = args.SrcColorIndex(); - + uint8_t* dest = args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); - count = thread->count_for_thread(args.DestY(), count); - if (count <= 0) - return; - - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - pitch *= thread->num_cores; + uint32_t *bg2rgb = args.DestBlend(); + uint32_t fg = args.SrcColorIndex(); const PalEntry *palette = GPalette.BaseColors; @@ -1184,28 +1071,17 @@ namespace swrenderer } } - void DrawColumnAddPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawAddColumn(const SpriteDrawerArgs& args) { - int count; - uint8_t *dest; - fixed_t frac; - fixed_t fracstep; - - count = args.Count(); - dest = args.Dest(); - - fracstep = args.TextureVStep(); - frac = args.TextureVPos(); - - count = thread->count_for_thread(args.DestY(), count); + int count = args.Count(); if (count <= 0) return; + uint8_t* dest = args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; + + fixed_t fracstep = args.TextureVStep(); + fixed_t frac = args.TextureVPos(); uint32_t *fg2rgb = args.SrcBlend(); uint32_t *bg2rgb = args.DestBlend(); @@ -1247,29 +1123,17 @@ namespace swrenderer } } - void DrawColumnTranslatedPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawTranslatedColumn(const SpriteDrawerArgs& args) { - int count; - uint8_t* dest; - fixed_t frac; - fixed_t fracstep; - - count = args.Count(); - - dest = args.Dest(); - - fracstep = args.TextureVStep(); - frac = args.TextureVPos(); - - count = thread->count_for_thread(args.DestY(), count); + int count = args.Count(); if (count <= 0) return; + uint8_t* dest = args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; + + fixed_t fracstep = args.TextureVStep(); + fixed_t frac = args.TextureVPos(); // [RH] Local copies of global vars to improve compiler optimizations const uint8_t *colormap = args.Colormap(args.Viewport()); @@ -1285,28 +1149,17 @@ namespace swrenderer } while (--count); } - void DrawColumnTlatedAddPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawTranslatedAddColumn(const SpriteDrawerArgs& args) { - int count; - uint8_t *dest; - fixed_t frac; - fixed_t fracstep; - - count = args.Count(); - dest = args.Dest(); - - fracstep = args.TextureVStep(); - frac = args.TextureVPos(); - - count = thread->count_for_thread(args.DestY(), count); + int count = args.Count(); if (count <= 0) return; + uint8_t* dest = args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; + + fixed_t fracstep = args.TextureVStep(); + fixed_t frac = args.TextureVPos(); uint32_t *fg2rgb = args.SrcBlend(); uint32_t *bg2rgb = args.DestBlend(); @@ -1349,27 +1202,17 @@ namespace swrenderer } } - void DrawColumnShadedPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawShadedColumn(const SpriteDrawerArgs& args) { - int count; - uint8_t *dest; - fixed_t frac, fracstep; - - count = args.Count(); - dest = args.Dest(); - - fracstep = args.TextureVStep(); - frac = args.TextureVPos(); - - count = thread->count_for_thread(args.DestY(), count); + int count = args.Count(); if (count <= 0) return; + uint8_t* dest = args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; + + fixed_t fracstep = args.TextureVStep(); + fixed_t frac = args.TextureVPos(); const uint8_t *source = args.TexturePixels(); const uint8_t *colormap = args.Colormap(args.Viewport()); @@ -1413,27 +1256,17 @@ namespace swrenderer } } - void DrawColumnAddClampShadedPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawAddClampShadedColumn(const SpriteDrawerArgs& args) { - int count; - uint8_t *dest; - fixed_t frac, fracstep; - - count = args.Count(); - dest = args.Dest(); - - fracstep = args.TextureVStep(); - frac = args.TextureVPos(); - - count = thread->count_for_thread(args.DestY(), count); + int count = args.Count(); if (count <= 0) return; + uint8_t* dest = args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; + + fixed_t fracstep = args.TextureVStep(); + fixed_t frac = args.TextureVPos(); const uint8_t *source = args.TexturePixels(); const uint8_t *colormap = args.Colormap(args.Viewport()); @@ -1455,28 +1288,17 @@ namespace swrenderer } while (--count); } - void DrawColumnAddClampPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawAddClampColumn(const SpriteDrawerArgs& args) { - int count; - uint8_t *dest; - fixed_t frac; - fixed_t fracstep; - - count = args.Count(); - dest = args.Dest(); - - fracstep = args.TextureVStep(); - frac = args.TextureVPos(); - - count = thread->count_for_thread(args.DestY(), count); + int count = args.Count(); if (count <= 0) return; + uint8_t* dest = args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; + + fixed_t fracstep = args.TextureVStep(); + fixed_t frac = args.TextureVPos(); const uint8_t *colormap = args.Colormap(args.Viewport()); const uint8_t *source = args.TexturePixels(); @@ -1519,28 +1341,17 @@ namespace swrenderer } } - void DrawColumnAddClampTranslatedPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawAddClampTranslatedColumn(const SpriteDrawerArgs& args) { - int count; - uint8_t *dest; - fixed_t frac; - fixed_t fracstep; - - count = args.Count(); - dest = args.Dest(); - - fracstep = args.TextureVStep(); - frac = args.TextureVPos(); - - count = thread->count_for_thread(args.DestY(), count); + int count = args.Count(); if (count <= 0) return; + uint8_t* dest = args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; + + fixed_t fracstep = args.TextureVStep(); + fixed_t frac = args.TextureVPos(); const uint8_t *translation = args.TranslationMap(); const uint8_t *colormap = args.Colormap(args.Viewport()); @@ -1584,28 +1395,17 @@ namespace swrenderer } } - void DrawColumnSubClampPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawSubClampColumn(const SpriteDrawerArgs& args) { - int count; - uint8_t *dest; - fixed_t frac; - fixed_t fracstep; - - count = args.Count(); - dest = args.Dest(); - - fracstep = args.TextureVStep(); - frac = args.TextureVPos(); - - count = thread->count_for_thread(args.DestY(), count); + int count = args.Count(); if (count <= 0) return; + uint8_t* dest = args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; + + fixed_t fracstep = args.TextureVStep(); + fixed_t frac = args.TextureVPos(); const uint8_t *colormap = args.Colormap(args.Viewport()); const uint8_t *source = args.TexturePixels(); @@ -1647,28 +1447,17 @@ namespace swrenderer } } - void DrawColumnSubClampTranslatedPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawSubClampTranslatedColumn(const SpriteDrawerArgs& args) { - int count; - uint8_t *dest; - fixed_t frac; - fixed_t fracstep; - - count = args.Count(); - dest = args.Dest(); - - fracstep = args.TextureVStep(); - frac = args.TextureVPos(); - - count = thread->count_for_thread(args.DestY(), count); + int count = args.Count(); if (count <= 0) return; + uint8_t* dest = args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; + + fixed_t fracstep = args.TextureVStep(); + fixed_t frac = args.TextureVPos(); const uint8_t *translation = args.TranslationMap(); const uint8_t *colormap = args.Colormap(args.Viewport()); @@ -1711,28 +1500,17 @@ namespace swrenderer } } - void DrawColumnRevSubClampPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawRevSubClampColumn(const SpriteDrawerArgs& args) { - int count; - uint8_t *dest; - fixed_t frac; - fixed_t fracstep; - - count = args.Count(); - dest = args.Dest(); - - fracstep = args.TextureVStep(); - frac = args.TextureVPos(); - - count = thread->count_for_thread(args.DestY(), count); + int count = args.Count(); if (count <= 0) return; + uint8_t* dest = args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; + + fixed_t fracstep = args.TextureVStep(); + fixed_t frac = args.TextureVPos(); const uint8_t *colormap = args.Colormap(args.Viewport()); const uint8_t *source = args.TexturePixels(); @@ -1774,28 +1552,17 @@ namespace swrenderer } } - void DrawColumnRevSubClampTranslatedPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs& args) { - int count; - uint8_t *dest; - fixed_t frac; - fixed_t fracstep; - - count = args.Count(); - dest = args.Dest(); - - fracstep = args.TextureVStep(); - frac = args.TextureVPos(); - - count = thread->count_for_thread(args.DestY(), count); + int count = args.Count(); if (count <= 0) return; + uint8_t* dest = args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); - dest = thread->dest_for_thread(args.DestY(), pitch, dest); - frac += fracstep * thread->skipped_by_thread(args.DestY()); - fracstep *= thread->num_cores; - pitch *= thread->num_cores; + + fixed_t fracstep = args.TextureVStep(); + fixed_t frac = args.TextureVPos(); const uint8_t *translation = args.TranslationMap(); const uint8_t *colormap = args.Colormap(args.Viewport()); @@ -1840,24 +1607,21 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////////// - DrawScaledFuzzColumnPalCommand::DrawScaledFuzzColumnPalCommand(const SpriteDrawerArgs &drawerargs) + void SWPalDrawers::DrawScaledFuzzColumn(const SpriteDrawerArgs& args) { - _x = drawerargs.FuzzX(); - _yl = drawerargs.FuzzY1(); - _yh = drawerargs.FuzzY2(); - _destorg = drawerargs.Viewport()->GetDest(0, 0); - _pitch = drawerargs.Viewport()->RenderTarget->GetPitch(); - _fuzzpos = fuzzpos; - _fuzzviewheight = fuzzviewheight; - } + int _yl = args.FuzzY1(); + int _yh = args.FuzzY2(); + int _x = args.FuzzX(); + uint8_t* _destorg = args.Viewport()->GetDest(0, 0); + int _pitch = args.Viewport()->RenderTarget->GetPitch(); + int _fuzzpos = fuzzpos; + int _fuzzviewheight = fuzzviewheight; - void DrawScaledFuzzColumnPalCommand::Execute(DrawerThread *thread) - { int x = _x; int yl = MAX(_yl, 1); int yh = MIN(_yh, _fuzzviewheight); - int count = thread->count_for_thread(yl, yh - yl + 1); + int count = yh - yl + 1; if (count <= 0) return; int pitch = _pitch; @@ -1868,14 +1632,7 @@ namespace swrenderer fixed_t fuzzstep = (200 << FRACBITS) / _fuzzviewheight; fixed_t fuzzcount = FUZZTABLE << FRACBITS; - 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; + fixed_t fuzz = ((fuzz_x << FRACBITS) + yl * fuzzstep) % fuzzcount; uint8_t *map = NormalLight.Maps; @@ -1894,34 +1651,30 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////// - DrawFuzzColumnPalCommand::DrawFuzzColumnPalCommand(const SpriteDrawerArgs &args) + void SWPalDrawers::DrawUnscaledFuzzColumn(const SpriteDrawerArgs& args) { - _yl = args.FuzzY1(); - _yh = args.FuzzY2(); - _x = args.FuzzX(); - _destorg = args.Viewport()->GetDest(0, 0); - _pitch = args.Viewport()->RenderTarget->GetPitch(); - _fuzzpos = fuzzpos; - _fuzzviewheight = fuzzviewheight; - } + int _yl = args.FuzzY1(); + int _yh = args.FuzzY2(); + int _x = args.FuzzX(); + uint8_t* _destorg = args.Viewport()->GetDest(0, 0); + int _pitch = args.Viewport()->RenderTarget->GetPitch(); + int _fuzzpos = fuzzpos; + int _fuzzviewheight = fuzzviewheight; - void DrawFuzzColumnPalCommand::Execute(DrawerThread *thread) - { int yl = MAX(_yl, 1); int yh = MIN(_yh, _fuzzviewheight); - int count = thread->count_for_thread(yl, yh - yl + 1); + int count = yh - yl + 1; // Zero length. if (count <= 0) return; int pitch = _pitch; - uint8_t *dest = thread->dest_for_thread(yl, pitch, yl * pitch + _x + _destorg); + uint8_t *dest = yl * pitch + _x + _destorg; - pitch = pitch * thread->num_cores; - int fuzzstep = thread->num_cores; - int fuzz = (_fuzzpos + thread->skipped_by_thread(yl)) % FUZZTABLE; + int fuzzstep = 1; + int fuzz = _fuzzpos % FUZZTABLE; #ifndef ORIGINAL_FUZZ @@ -1952,8 +1705,6 @@ namespace swrenderer uint8_t *map = &NormalLight.Maps[6 * 256]; - yl += thread->skipped_by_thread(yl); - // Handle the case where we would go out of bounds at the top: if (yl < fuzzstep) { @@ -2010,32 +1761,7 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////// - PalSpanCommand::PalSpanCommand(const SpanDrawerArgs &args) - { - _source = args.TexturePixels(); - _colormap = args.Colormap(args.Viewport()); - _xfrac = args.TextureUPos(); - _yfrac = args.TextureVPos(); - _y = args.DestY(); - _x1 = args.DestX1(); - _x2 = args.DestX2(); - _dest = args.Viewport()->GetDest(_x1, _y); - _xstep = args.TextureUStep(); - _ystep = args.TextureVStep(); - _srcwidth = args.TextureWidth(); - _srcheight = args.TextureHeight(); - _srcblend = args.SrcBlend(); - _destblend = args.DestBlend(); - _color = args.SolidColor(); - _srcalpha = args.SrcAlpha(); - _destalpha = args.DestAlpha(); - _dynlights = args.dc_lights; - _num_dynlights = args.dc_num_lights; - _viewpos_x = args.dc_viewpos.X; - _step_viewpos_x = args.dc_viewpos_step.X; - } - - uint8_t PalSpanCommand::AddLights(const DrawerLight *lights, int num_lights, float viewpos_x, uint8_t fg, uint8_t material) + uint8_t SWPalDrawers::AddLightsSpan(const DrawerLight *lights, int num_lights, float viewpos_x, uint8_t fg, uint8_t material) { uint32_t lit_r = 0; uint32_t lit_g = 0; @@ -2088,10 +1814,29 @@ namespace swrenderer return RGB256k.All[((lit_r >> 2) << 12) | ((lit_g >> 2) << 6) | (lit_b >> 2)]; } - void DrawSpanPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawSpan(const SpanDrawerArgs& args) { - if (thread->line_skipped_by_thread(_y)) - return; + const uint8_t* _source = args.TexturePixels(); + const uint8_t* _colormap = args.Colormap(args.Viewport()); + uint32_t _xfrac = args.TextureUPos(); + uint32_t _yfrac = args.TextureVPos(); + int _y = args.DestY(); + int _x1 = args.DestX1(); + int _x2 = args.DestX2(); + uint8_t* _dest = args.Viewport()->GetDest(_x1, _y); + uint32_t _xstep = args.TextureUStep(); + uint32_t _ystep = args.TextureVStep(); + int _srcwidth = args.TextureWidth(); + int _srcheight = args.TextureHeight(); + uint32_t* _srcblend = args.SrcBlend(); + uint32_t* _destblend = args.DestBlend(); + int _color = args.SolidColor(); + fixed_t _srcalpha = args.SrcAlpha(); + fixed_t _destalpha = args.DestAlpha(); + DrawerLight* _dynlights = args.dc_lights; + int _num_dynlights = args.dc_num_lights; + float _viewpos_x = args.dc_viewpos.X; + float _step_viewpos_x = args.dc_viewpos_step.X; uint32_t xfrac; uint32_t yfrac; @@ -2145,7 +1890,7 @@ namespace swrenderer // Lookup pixel from flat texture tile, // re-index using light/colormap. - *dest++ = AddLights(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]); + *dest++ = AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]); // Next step in u,v. xfrac += xstep; @@ -2165,7 +1910,7 @@ namespace swrenderer // Lookup pixel from flat texture tile, // re-index using light/colormap. - *dest++ = AddLights(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]); + *dest++ = AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]); // Next step in u,v. xfrac += xstep; @@ -2175,10 +1920,29 @@ namespace swrenderer } } - void DrawSpanMaskedPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawSpanMasked(const SpanDrawerArgs& args) { - if (thread->line_skipped_by_thread(_y)) - return; + const uint8_t* _source = args.TexturePixels(); + const uint8_t* _colormap = args.Colormap(args.Viewport()); + uint32_t _xfrac = args.TextureUPos(); + uint32_t _yfrac = args.TextureVPos(); + int _y = args.DestY(); + int _x1 = args.DestX1(); + int _x2 = args.DestX2(); + uint8_t* _dest = args.Viewport()->GetDest(_x1, _y); + uint32_t _xstep = args.TextureUStep(); + uint32_t _ystep = args.TextureVStep(); + int _srcwidth = args.TextureWidth(); + int _srcheight = args.TextureHeight(); + uint32_t* _srcblend = args.SrcBlend(); + uint32_t* _destblend = args.DestBlend(); + int _color = args.SolidColor(); + fixed_t _srcalpha = args.SrcAlpha(); + fixed_t _destalpha = args.DestAlpha(); + DrawerLight* _dynlights = args.dc_lights; + int _num_dynlights = args.dc_num_lights; + float _viewpos_x = args.dc_viewpos.X; + float _step_viewpos_x = args.dc_viewpos_step.X; uint32_t xfrac; uint32_t yfrac; @@ -2216,7 +1980,7 @@ namespace swrenderer texdata = source[spot]; if (texdata != 0) { - *dest = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; + *dest = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; } dest++; xfrac += xstep; @@ -2237,7 +2001,7 @@ namespace swrenderer texdata = source[spot]; if (texdata != 0) { - *dest = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; + *dest = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; } dest++; xfrac += xstep; @@ -2247,10 +2011,29 @@ namespace swrenderer } } - void DrawSpanTranslucentPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawSpanTranslucent(const SpanDrawerArgs& args) { - if (thread->line_skipped_by_thread(_y)) - return; + const uint8_t* _source = args.TexturePixels(); + const uint8_t* _colormap = args.Colormap(args.Viewport()); + uint32_t _xfrac = args.TextureUPos(); + uint32_t _yfrac = args.TextureVPos(); + int _y = args.DestY(); + int _x1 = args.DestX1(); + int _x2 = args.DestX2(); + uint8_t* _dest = args.Viewport()->GetDest(_x1, _y); + uint32_t _xstep = args.TextureUStep(); + uint32_t _ystep = args.TextureVStep(); + int _srcwidth = args.TextureWidth(); + int _srcheight = args.TextureHeight(); + uint32_t* _srcblend = args.SrcBlend(); + uint32_t* _destblend = args.DestBlend(); + int _color = args.SolidColor(); + fixed_t _srcalpha = args.SrcAlpha(); + fixed_t _destalpha = args.DestAlpha(); + DrawerLight* _dynlights = args.dc_lights; + int _num_dynlights = args.dc_num_lights; + float _viewpos_x = args.dc_viewpos.X; + float _step_viewpos_x = args.dc_viewpos_step.X; uint32_t xfrac; uint32_t yfrac; @@ -2289,7 +2072,7 @@ namespace swrenderer do { spot = ((xfrac >> (32 - 6 - 6))&(63 * 64)) + (yfrac >> (32 - 6)); - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; uint32_t bg = *dest; fg = fg2rgb[fg]; bg = bg2rgb[bg]; @@ -2308,7 +2091,7 @@ namespace swrenderer do { spot = (((xfrac >> 16) * srcwidth) >> 16) * srcheight + (((yfrac >> 16) * srcheight) >> 16); - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; uint32_t bg = *dest; fg = fg2rgb[fg]; bg = bg2rgb[bg]; @@ -2328,7 +2111,7 @@ namespace swrenderer do { spot = ((xfrac >> (32 - 6 - 6))&(63 * 64)) + (yfrac >> (32 - 6)); - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; uint32_t bg = *dest; int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); @@ -2348,7 +2131,7 @@ namespace swrenderer do { spot = (((xfrac >> 16) * srcwidth) >> 16) * srcheight + (((yfrac >> 16) * srcheight) >> 16); - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; uint32_t bg = *dest; int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); @@ -2363,10 +2146,29 @@ namespace swrenderer } } - void DrawSpanMaskedTranslucentPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawSpanMaskedTranslucent(const SpanDrawerArgs& args) { - if (thread->line_skipped_by_thread(_y)) - return; + const uint8_t* _source = args.TexturePixels(); + const uint8_t* _colormap = args.Colormap(args.Viewport()); + uint32_t _xfrac = args.TextureUPos(); + uint32_t _yfrac = args.TextureVPos(); + int _y = args.DestY(); + int _x1 = args.DestX1(); + int _x2 = args.DestX2(); + uint8_t* _dest = args.Viewport()->GetDest(_x1, _y); + uint32_t _xstep = args.TextureUStep(); + uint32_t _ystep = args.TextureVStep(); + int _srcwidth = args.TextureWidth(); + int _srcheight = args.TextureHeight(); + uint32_t* _srcblend = args.SrcBlend(); + uint32_t* _destblend = args.DestBlend(); + int _color = args.SolidColor(); + fixed_t _srcalpha = args.SrcAlpha(); + fixed_t _destalpha = args.DestAlpha(); + DrawerLight* _dynlights = args.dc_lights; + int _num_dynlights = args.dc_num_lights; + float _viewpos_x = args.dc_viewpos.X; + float _step_viewpos_x = args.dc_viewpos_step.X; uint32_t xfrac; uint32_t yfrac; @@ -2410,7 +2212,7 @@ namespace swrenderer texdata = source[spot]; if (texdata != 0) { - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; uint32_t bg = *dest; fg = fg2rgb[fg]; bg = bg2rgb[bg]; @@ -2436,7 +2238,7 @@ namespace swrenderer texdata = source[spot]; if (texdata != 0) { - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; uint32_t bg = *dest; fg = fg2rgb[fg]; bg = bg2rgb[bg]; @@ -2463,7 +2265,7 @@ namespace swrenderer texdata = source[spot]; if (texdata != 0) { - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; uint32_t bg = *dest; int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); @@ -2489,7 +2291,7 @@ namespace swrenderer texdata = source[spot]; if (texdata != 0) { - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; uint32_t bg = *dest; int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); @@ -2505,10 +2307,29 @@ namespace swrenderer } } - void DrawSpanAddClampPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawSpanAddClamp(const SpanDrawerArgs& args) { - if (thread->line_skipped_by_thread(_y)) - return; + const uint8_t* _source = args.TexturePixels(); + const uint8_t* _colormap = args.Colormap(args.Viewport()); + uint32_t _xfrac = args.TextureUPos(); + uint32_t _yfrac = args.TextureVPos(); + int _y = args.DestY(); + int _x1 = args.DestX1(); + int _x2 = args.DestX2(); + uint8_t* _dest = args.Viewport()->GetDest(_x1, _y); + uint32_t _xstep = args.TextureUStep(); + uint32_t _ystep = args.TextureVStep(); + int _srcwidth = args.TextureWidth(); + int _srcheight = args.TextureHeight(); + uint32_t* _srcblend = args.SrcBlend(); + uint32_t* _destblend = args.DestBlend(); + int _color = args.SolidColor(); + fixed_t _srcalpha = args.SrcAlpha(); + fixed_t _destalpha = args.DestAlpha(); + DrawerLight* _dynlights = args.dc_lights; + int _num_dynlights = args.dc_num_lights; + float _viewpos_x = args.dc_viewpos.X; + float _step_viewpos_x = args.dc_viewpos_step.X; uint32_t xfrac; uint32_t yfrac; @@ -2546,7 +2367,7 @@ namespace swrenderer do { spot = ((xfrac >> (32 - 6 - 6))&(63 * 64)) + (yfrac >> (32 - 6)); - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; uint32_t a = fg2rgb[fg] + bg2rgb[*dest]; uint32_t b = a; @@ -2569,7 +2390,7 @@ namespace swrenderer do { spot = (((xfrac >> 16) * srcwidth) >> 16) * srcheight + (((yfrac >> 16) * srcheight) >> 16); - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; uint32_t a = fg2rgb[fg] + bg2rgb[*dest]; uint32_t b = a; @@ -2593,7 +2414,7 @@ namespace swrenderer do { spot = ((xfrac >> (32 - 6 - 6))&(63 * 64)) + (yfrac >> (32 - 6)); - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; uint32_t bg = *dest; int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); @@ -2613,7 +2434,7 @@ namespace swrenderer do { spot = (((xfrac >> 16) * srcwidth) >> 16) * srcheight + (((yfrac >> 16) * srcheight) >> 16); - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; uint32_t bg = *dest; int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); @@ -2628,10 +2449,29 @@ namespace swrenderer } } - void DrawSpanMaskedAddClampPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawSpanMaskedAddClamp(const SpanDrawerArgs& args) { - if (thread->line_skipped_by_thread(_y)) - return; + const uint8_t* _source = args.TexturePixels(); + const uint8_t* _colormap = args.Colormap(args.Viewport()); + uint32_t _xfrac = args.TextureUPos(); + uint32_t _yfrac = args.TextureVPos(); + int _y = args.DestY(); + int _x1 = args.DestX1(); + int _x2 = args.DestX2(); + uint8_t* _dest = args.Viewport()->GetDest(_x1, _y); + uint32_t _xstep = args.TextureUStep(); + uint32_t _ystep = args.TextureVStep(); + int _srcwidth = args.TextureWidth(); + int _srcheight = args.TextureHeight(); + uint32_t* _srcblend = args.SrcBlend(); + uint32_t* _destblend = args.DestBlend(); + int _color = args.SolidColor(); + fixed_t _srcalpha = args.SrcAlpha(); + fixed_t _destalpha = args.DestAlpha(); + DrawerLight* _dynlights = args.dc_lights; + int _num_dynlights = args.dc_num_lights; + float _viewpos_x = args.dc_viewpos.X; + float _step_viewpos_x = args.dc_viewpos_step.X; uint32_t xfrac; uint32_t yfrac; @@ -2674,7 +2514,7 @@ namespace swrenderer texdata = source[spot]; if (texdata != 0) { - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; uint32_t a = fg2rgb[fg] + bg2rgb[*dest]; uint32_t b = a; @@ -2704,7 +2544,7 @@ namespace swrenderer texdata = source[spot]; if (texdata != 0) { - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; uint32_t a = fg2rgb[fg] + bg2rgb[*dest]; uint32_t b = a; @@ -2735,7 +2575,7 @@ namespace swrenderer texdata = source[spot]; if (texdata != 0) { - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; uint32_t bg = *dest; int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); @@ -2761,7 +2601,7 @@ namespace swrenderer texdata = source[spot]; if (texdata != 0) { - uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; + uint32_t fg = num_dynlights != 0 ? AddLightsSpan(dynlights, num_dynlights, viewpos_x, colormap[texdata], texdata) : colormap[texdata]; uint32_t bg = *dest; int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); @@ -2777,37 +2617,49 @@ namespace swrenderer } } - void FillSpanPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::FillSpan(const SpanDrawerArgs& args) { - if (thread->line_skipped_by_thread(_y)) - return; + const uint8_t* _source = args.TexturePixels(); + const uint8_t* _colormap = args.Colormap(args.Viewport()); + uint32_t _xfrac = args.TextureUPos(); + uint32_t _yfrac = args.TextureVPos(); + int _y = args.DestY(); + int _x1 = args.DestX1(); + int _x2 = args.DestX2(); + uint8_t* _dest = args.Viewport()->GetDest(_x1, _y); + uint32_t _xstep = args.TextureUStep(); + uint32_t _ystep = args.TextureVStep(); + int _srcwidth = args.TextureWidth(); + int _srcheight = args.TextureHeight(); + uint32_t* _srcblend = args.SrcBlend(); + uint32_t* _destblend = args.DestBlend(); + int _color = args.SolidColor(); + fixed_t _srcalpha = args.SrcAlpha(); + fixed_t _destalpha = args.DestAlpha(); + DrawerLight* _dynlights = args.dc_lights; + int _num_dynlights = args.dc_num_lights; + float _viewpos_x = args.dc_viewpos.X; + float _step_viewpos_x = args.dc_viewpos_step.X; memset(_dest, _color, _x2 - _x1 + 1); } ///////////////////////////////////////////////////////////////////////// - DrawTiltedSpanPalCommand::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) - : plane_sz(plane_sz), plane_su(plane_su), plane_sv(plane_sv), plane_shade(plane_shade), planeshade(planeshade), planelightfloat(planelightfloat), pviewx(pviewx), pviewy(pviewy) + void SWPalDrawers::DrawTiltedSpan(const SpanDrawerArgs& args, const FVector3& plane_sz, const FVector3& plane_su, const FVector3& plane_sv, bool is_planeshaded, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap* basecolormap) { - y = args.DestY(); - x1 = args.DestX1(); - x2 = args.DestX2(); - viewport = args.Viewport(); - _colormap = args.Colormap(args.Viewport()); - _dest = args.Viewport()->GetDest(x1, y); - _ybits = args.TextureHeightBits(); - _xbits = args.TextureWidthBits(); - _source = args.TexturePixels(); - basecolormapdata = basecolormap->Maps; - } - - void DrawTiltedSpanPalCommand::Execute(DrawerThread *thread) - { - if (thread->line_skipped_by_thread(y)) - return; - - const uint8_t **tiltlighting = thread->tiltlighting; + int y = args.DestY(); + int x1 = args.DestX1(); + int x2 = args.DestX2(); + RenderViewport* viewport = args.Viewport(); + const uint8_t* _colormap = args.Colormap(args.Viewport()); + uint8_t* _dest = args.Viewport()->GetDest(x1, y); + int _ybits = args.TextureHeightBits(); + int _xbits = args.TextureWidthBits(); + const uint8_t* _source = args.TexturePixels(); + uint8_t* basecolormapdata = basecolormap->Maps; + + const uint8_t **tiltlighting = this->tiltlighting; int width = x2 - x1; double iz, uz, vz; @@ -2818,11 +2670,11 @@ namespace swrenderer iz = plane_sz[2] + plane_sz[1] * (viewport->viewwindow.centery - y) + plane_sz[0] * (x1 - viewport->viewwindow.centerx); // Lighting is simple. It's just linear interpolation from start to end - if (plane_shade) + if (is_planeshaded) { uz = (iz + plane_sz[0] * width) * planelightfloat; vz = iz * planelightfloat; - CalcTiltedLighting(vz, uz, width, thread); + CalcTiltedLighting(vz, uz, width, planeshade, basecolormapdata); } else { @@ -2939,9 +2791,9 @@ namespace swrenderer // Calculates the lighting for one row of a tilted plane. If the definition // of GETPALOOKUP changes, this needs to change, too. - void DrawTiltedSpanPalCommand::CalcTiltedLighting(double lstart, double lend, int width, DrawerThread *thread) + void SWPalDrawers::CalcTiltedLighting(double lstart, double lend, int width, int planeshade, uint8_t* basecolormapdata) { - const uint8_t **tiltlighting = thread->tiltlighting; + const uint8_t **tiltlighting = this->tiltlighting; uint8_t *lightstart = basecolormapdata + (GETPALOOKUP(lstart, planeshade) << COLORMAPSHIFT); uint8_t *lightend = basecolormapdata + (GETPALOOKUP(lend, planeshade) << COLORMAPSHIFT); @@ -2967,38 +2819,25 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////// - DrawColoredSpanPalCommand::DrawColoredSpanPalCommand(const SpanDrawerArgs &args) : PalSpanCommand(args) + void SWPalDrawers::DrawColoredSpan(const SpanDrawerArgs& args) { - y = args.DestY(); - x1 = args.DestX1(); - x2 = args.DestX2(); - color = args.SolidColor(); - dest = args.Viewport()->GetDest(x1, y); - } - - void DrawColoredSpanPalCommand::Execute(DrawerThread *thread) - { - if (thread->line_skipped_by_thread(y)) - return; - + int y = args.DestY(); + int x1 = args.DestX1(); + int x2 = args.DestX2(); + int color = args.SolidColor(); + uint8_t* _dest = args.Viewport()->GetDest(0, y); memset(_dest, color, x2 - x1 + 1); } ///////////////////////////////////////////////////////////////////////// - DrawFogBoundaryLinePalCommand::DrawFogBoundaryLinePalCommand(const SpanDrawerArgs &args) : PalSpanCommand(args) - { - y = args.DestY(); - x1 = args.DestX1(); - x2 = args.DestX2(); - _colormap = args.Colormap(args.Viewport()); - _dest = args.Viewport()->GetDest(0, y); - } - - void DrawFogBoundaryLinePalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawFogBoundaryLine(const SpanDrawerArgs& args) { - if (thread->line_skipped_by_thread(y)) - return; + int y = args.DestY(); + int x1 = args.DestX1(); + int x2 = args.DestX2(); + const uint8_t* _colormap = args.Colormap(args.Viewport()); + uint8_t* _dest = args.Viewport()->GetDest(0, y); const uint8_t *colormap = _colormap; uint8_t *dest = _dest; @@ -3011,34 +2850,21 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////////// - DrawParticleColumnPalCommand::DrawParticleColumnPalCommand(uint8_t *dest, int dest_y, int pitch, int count, uint32_t fg, uint32_t alpha, uint32_t fracposx) + void SWPalDrawers::DrawParticleColumn(int x, int _dest_y, int _count, uint32_t _fg, uint32_t _alpha, uint32_t _fracposx) { - _dest = dest; - _pitch = pitch; - _count = count; - _fg = fg; - _alpha = alpha; - _fracposx = fracposx; - _dest_y = dest_y; - } + uint8_t* dest = thread->Viewport->GetDest(x, _dest_y); + int pitch = thread->Viewport->RenderTarget->GetPitch(); - void DrawParticleColumnPalCommand::Execute(DrawerThread *thread) - { - int count = thread->count_for_thread(_dest_y, _count); + int count = _count; if (count <= 0) return; - int pitch = _pitch; - uint8_t *dest = thread->dest_for_thread(_dest_y, pitch, _dest); - pitch = pitch * thread->num_cores; - int particle_texture_index = MIN(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 * thread->skipped_by_thread(_dest_y) + fracstep / 2; - fracstep *= thread->num_cores; + uint32_t fracpos = fracstep / 2; uint32_t fg_red = (_fg >> 16) & 0xff; uint32_t fg_green = (_fg >> 8) & 0xff; @@ -3066,11 +2892,7 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////////// - DrawVoxelBlocksPalCommand::DrawVoxelBlocksPalCommand(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount) : args(args), blocks(blocks), blockcount(blockcount) - { - } - - void DrawVoxelBlocksPalCommand::Execute(DrawerThread *thread) + void SWPalDrawers::DrawVoxelBlocks(const SpriteDrawerArgs& args, const VoxelBlock* blocks, int blockcount) { int destpitch = args.Viewport()->RenderTarget->GetPitch(); uint8_t *destorig = args.Viewport()->RenderTarget->GetPixels(); @@ -3089,12 +2911,6 @@ namespace swrenderer int pitch = destpitch; uint8_t *dest = destorig + (block.x + block.y * pitch); - count = thread->count_for_thread(block.y, count); - dest = thread->dest_for_thread(block.y, pitch, dest); - fracpos += iscale * thread->skipped_by_thread(block.y); - iscale *= thread->num_cores; - pitch *= thread->num_cores; - if (width == 1) { while (count > 0) @@ -3161,4 +2977,164 @@ namespace swrenderer } } } + + template + void SWPalDrawers::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); + + DrawWallColumn8(wallcolargs, x, y1, y2, texelX, texelY, 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 + void SWPalDrawers::DrawWallColumn8(WallColumnDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepY) + { + auto& wallargs = *drawerargs.wallargs; + int texwidth = wallargs.texwidth; + int texheight = wallargs.texheight; + int fracbits = wallargs.fracbits; + uint32_t uv_max = texheight << fracbits; + + const uint8_t* pixels = static_cast(wallargs.texpixels) + (((texelX >> 16) * texwidth) >> 16) * texheight; + + texelY = (static_cast(texelY) * texheight) >> (32 - fracbits); + texelStepY = (static_cast(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); + DrawWallColumn(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); + DrawWallColumn(drawerargs); + + y += count; + left -= count; + texelY += texelStepY * count; + if (texelY >= uv_max) + texelY -= uv_max; + } + } + } } diff --git a/src/rendering/swrenderer/drawers/r_draw_pal.h b/src/rendering/swrenderer/drawers/r_draw_pal.h index 14b1e3bc204..9777560e60c 100644 --- a/src/rendering/swrenderer/drawers/r_draw_pal.h +++ b/src/rendering/swrenderer/drawers/r_draw_pal.h @@ -107,289 +107,81 @@ namespace swrenderer int mShade = 0; }; - 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; - }; + struct DrawWallModeNormal; + struct DrawWallModeMasked; + struct DrawWallModeAdd; + struct DrawWallModeAddClamp; + struct DrawWallModeSubClamp; + struct DrawWallModeRevSubClamp; class SWPalDrawers : public SWPixelFormatDrawers { public: using SWPixelFormatDrawers::SWPixelFormatDrawers; - void DrawWall(const WallDrawerArgs &args) override { Queue->Push(args); } - void DrawWallMasked(const WallDrawerArgs &args) override { Queue->Push(args); } - void DrawWallAdd(const WallDrawerArgs &args) override { Queue->Push(args); } - void DrawWallAddClamp(const WallDrawerArgs &args) override { Queue->Push(args); } - void DrawWallSubClamp(const WallDrawerArgs &args) override { Queue->Push(args); } - void DrawWallRevSubClamp(const WallDrawerArgs &args) override { Queue->Push(args); } - void DrawSingleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push(args); } - void DrawDoubleSkyColumn(const SkyDrawerArgs &args) override { Queue->Push(args); } - void DrawColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void FillColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void FillAddColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void FillAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void FillSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawWall(const WallDrawerArgs &args) override { DrawWallColumns(args); } + void DrawWallMasked(const WallDrawerArgs &args) override { DrawWallColumns(args); } + void DrawWallAdd(const WallDrawerArgs &args) override { DrawWallColumns(args); } + void DrawWallAddClamp(const WallDrawerArgs &args) override { DrawWallColumns(args); } + void DrawWallSubClamp(const WallDrawerArgs &args) override { DrawWallColumns(args); } + void DrawWallRevSubClamp(const WallDrawerArgs &args) override { DrawWallColumns(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 DrawFuzzColumn(const SpriteDrawerArgs &args) override { if (r_fuzzscale) - Queue->Push(args); + DrawScaledFuzzColumn(args); else - Queue->Push(args); + DrawUnscaledFuzzColumn(args); R_UpdateFuzzPos(args); } - void DrawAddColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void DrawShadedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void DrawAddClampShadedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void DrawAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void DrawSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } - void DrawVoxelBlocks(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount) override { Queue->Push(args, blocks, blockcount); } - void DrawSpan(const SpanDrawerArgs &args) override { Queue->Push(args); } - void DrawSpanMasked(const SpanDrawerArgs &args) override { Queue->Push(args); } - void DrawSpanTranslucent(const SpanDrawerArgs &args) override { Queue->Push(args); } - void DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) override { Queue->Push(args); } - void DrawSpanAddClamp(const SpanDrawerArgs &args) override { Queue->Push(args); } - void DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) override { Queue->Push(args); } - void FillSpan(const SpanDrawerArgs &args) override { Queue->Push(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(args, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy, basecolormap); - } - - void DrawColoredSpan(const SpanDrawerArgs &args) override { Queue->Push(args); } - void DrawFogBoundaryLine(const SpanDrawerArgs &args) override { Queue->Push(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 DrawParticleColumn(int x, int yl, int ycount, uint32_t fg, uint32_t alpha, uint32_t fracposx) override; + + 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 void DrawWallColumns(const WallDrawerArgs& args); + template void DrawWallColumn8(WallColumnDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepY); + template void DrawWallColumn(const WallColumnDrawerArgs& args); + + // Working buffer used by the tilted (sloped) span drawer + const uint8_t* tiltlighting[MAXWIDTH]; + + WallColumnDrawerArgs wallcolargs; }; } diff --git a/src/rendering/swrenderer/drawers/r_draw_rgba.cpp b/src/rendering/swrenderer/drawers/r_draw_rgba.cpp index 10bb6be634c..b6360981cd0 100644 --- a/src/rendering/swrenderer/drawers/r_draw_rgba.cpp +++ b/src/rendering/swrenderer/drawers/r_draw_rgba.cpp @@ -82,193 +82,185 @@ namespace swrenderer { void SWTruecolorDrawers::DrawWall(const WallDrawerArgs &args) { - Queue->Push(args); + DrawWallColumns(args); } void SWTruecolorDrawers::DrawWallMasked(const WallDrawerArgs &args) { - Queue->Push(args); + DrawWallColumns(args); } void SWTruecolorDrawers::DrawWallAdd(const WallDrawerArgs &args) { - Queue->Push(args); + DrawWallColumns(args); } void SWTruecolorDrawers::DrawWallAddClamp(const WallDrawerArgs &args) { - Queue->Push(args); + DrawWallColumns(args); } void SWTruecolorDrawers::DrawWallSubClamp(const WallDrawerArgs &args) { - Queue->Push(args); + DrawWallColumns(args); } void SWTruecolorDrawers::DrawWallRevSubClamp(const WallDrawerArgs &args) { - Queue->Push(args); + DrawWallColumns(args); } void SWTruecolorDrawers::DrawColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + DrawSprite32Command::DrawColumn(args); } void SWTruecolorDrawers::FillColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + FillSprite32Command::DrawColumn(args); } void SWTruecolorDrawers::FillAddColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + FillSpriteAddClamp32Command::DrawColumn(args); } void SWTruecolorDrawers::FillAddClampColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + FillSpriteAddClamp32Command::DrawColumn(args); } void SWTruecolorDrawers::FillSubClampColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + FillSpriteSubClamp32Command::DrawColumn(args); } void SWTruecolorDrawers::FillRevSubClampColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + FillSpriteRevSubClamp32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawFuzzColumn(const SpriteDrawerArgs &args) { if (r_fuzzscale) - Queue->Push(args); + DrawScaledFuzzColumn(args); else - Queue->Push(args); + DrawUnscaledFuzzColumn(args); R_UpdateFuzzPos(args); } void SWTruecolorDrawers::DrawAddColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + DrawSpriteAddClamp32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawTranslatedColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + DrawSpriteTranslated32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawTranslatedAddColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + DrawSpriteTranslatedAddClamp32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawShadedColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + DrawSpriteShaded32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawAddClampShadedColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + DrawSpriteAddClampShaded32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawAddClampColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + DrawSpriteAddClamp32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + DrawSpriteTranslatedAddClamp32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawSubClampColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + DrawSpriteSubClamp32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + DrawSpriteTranslatedSubClamp32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawRevSubClampColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); + DrawSpriteRevSubClamp32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) { - Queue->Push(args); - } - - void SWTruecolorDrawers::DrawVoxelBlocks(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount) - { - Queue->Push(args, blocks, blockcount); + DrawSpriteTranslatedRevSubClamp32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawSpan(const SpanDrawerArgs &args) { - Queue->Push(args); + DrawSpan32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawSpanMasked(const SpanDrawerArgs &args) { - Queue->Push(args); + DrawSpanMasked32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawSpanTranslucent(const SpanDrawerArgs &args) { - Queue->Push(args); + DrawSpanTranslucent32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawSpanMaskedTranslucent(const SpanDrawerArgs &args) { - Queue->Push(args); + DrawSpanAddClamp32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawSpanAddClamp(const SpanDrawerArgs &args) { - Queue->Push(args); + DrawSpanTranslucent32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawSpanMaskedAddClamp(const SpanDrawerArgs &args) { - Queue->Push(args); + DrawSpanAddClamp32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawSingleSkyColumn(const SkyDrawerArgs &args) { - Queue->Push(args); + DrawSkySingle32Command::DrawColumn(args); } void SWTruecolorDrawers::DrawDoubleSkyColumn(const SkyDrawerArgs &args) { - Queue->Push(args); + DrawSkyDouble32Command::DrawColumn(args); } ///////////////////////////////////////////////////////////////////////////// - DrawScaledFuzzColumnRGBACommand::DrawScaledFuzzColumnRGBACommand(const SpriteDrawerArgs &drawerargs) + void SWTruecolorDrawers::DrawScaledFuzzColumn(const SpriteDrawerArgs& drawerargs) { - _x = drawerargs.FuzzX(); - _yl = drawerargs.FuzzY1(); - _yh = drawerargs.FuzzY2(); - _destorg = drawerargs.Viewport()->GetDest(0, 0); - _pitch = drawerargs.Viewport()->RenderTarget->GetPitch(); - _fuzzpos = fuzzpos; - _fuzzviewheight = fuzzviewheight; - } + 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; - void DrawScaledFuzzColumnRGBACommand::Execute(DrawerThread *thread) - { int x = _x; int yl = MAX(_yl, 1); int yh = MIN(_yh, _fuzzviewheight); - int count = thread->count_for_thread(yl, yh - yl + 1); + int count = yh - yl + 1; if (count <= 0) return; int pitch = _pitch; @@ -279,14 +271,7 @@ namespace swrenderer fixed_t fuzzstep = (200 << FRACBITS) / _fuzzviewheight; fixed_t fuzzcount = FUZZTABLE << FRACBITS; - 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; + fixed_t fuzz = ((fuzz_x << FRACBITS) + yl * fuzzstep) % fuzzcount; while (count > 0) { @@ -309,33 +294,30 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////////// - DrawFuzzColumnRGBACommand::DrawFuzzColumnRGBACommand(const SpriteDrawerArgs &drawerargs) + void SWTruecolorDrawers::DrawUnscaledFuzzColumn(const SpriteDrawerArgs& drawerargs) { - _x = drawerargs.FuzzX(); - _yl = drawerargs.FuzzY1(); - _yh = drawerargs.FuzzY2(); - _destorg = drawerargs.Viewport()->GetDest(0, 0); - _pitch = drawerargs.Viewport()->RenderTarget->GetPitch(); - _fuzzpos = fuzzpos; - _fuzzviewheight = fuzzviewheight; - } + 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; - void DrawFuzzColumnRGBACommand::Execute(DrawerThread *thread) - { int yl = MAX(_yl, 1); int yh = MIN(_yh, _fuzzviewheight); - int count = thread->count_for_thread(yl, yh - yl + 1); + int count = yh - yl + 1; // Zero length. if (count <= 0) return; - uint32_t *dest = thread->dest_for_thread(yl, _pitch, _pitch * yl + _x + (uint32_t*)_destorg); - int pitch = _pitch * thread->num_cores; + uint32_t *dest = _pitch * yl + _x + (uint32_t*)_destorg; + int pitch = _pitch; - int fuzzstep = thread->num_cores; - int fuzz = (_fuzzpos + thread->skipped_by_thread(yl)) % FUZZTABLE; + int fuzzstep = 1; + int fuzz = _fuzzpos % FUZZTABLE; #ifndef ORIGINAL_FUZZ @@ -367,8 +349,6 @@ 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) { @@ -443,20 +423,14 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////////// - FillSpanRGBACommand::FillSpanRGBACommand(const SpanDrawerArgs &drawerargs) + void SWTruecolorDrawers::FillSpan(const SpanDrawerArgs& drawerargs) { - _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; + 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(); uint32_t *dest = (uint32_t*)_dest; int count = (_x2 - _x1 + 1); @@ -468,20 +442,14 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////////// - DrawFogBoundaryLineRGBACommand::DrawFogBoundaryLineRGBACommand(const SpanDrawerArgs &drawerargs) + void SWTruecolorDrawers::DrawFogBoundaryLine(const SpanDrawerArgs& drawerargs) { - _y = drawerargs.DestY(); - _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 = 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(); int y = _y; int x = _x; @@ -490,7 +458,6 @@ namespace swrenderer uint32_t *dest = (uint32_t*)_line; uint32_t light = LightBgra::calc_light_multiplier(_light); - ShadeConstants constants = _shade_constants; do { @@ -530,32 +497,18 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////////// - DrawTiltedSpanRGBACommand::DrawTiltedSpanRGBACommand(const SpanDrawerArgs &drawerargs, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy) - { - _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; + 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) + { + 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(); //#define SPANSIZE 32 //#define INVSPAN 0.03125f @@ -660,20 +613,14 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////////// - DrawColoredSpanRGBACommand::DrawColoredSpanRGBACommand(const SpanDrawerArgs &drawerargs) - { - _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) + void SWTruecolorDrawers::DrawColoredSpan(const SpanDrawerArgs& drawerargs) { - if (thread->line_skipped_by_thread(_y)) - return; + 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(); int y = _y; int x1 = _x1; @@ -690,12 +637,13 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////////// #if 0 - ApplySpecialColormapRGBACommand::ApplySpecialColormapRGBACommand(FSpecialColormap *colormap, DFrameBuffer *screen) +#ifdef NO_SSE + void SWTruecolorDrawers::ApplySpecialColormap(FSpecialColormap* colormap, DFrameBuffer* screen) { - buffer = screen->GetBuffer(); - pitch = screen->GetPitch(); - width = screen->GetWidth(); - height = screen->GetHeight(); + 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); @@ -703,13 +651,9 @@ namespace swrenderer end_red = (int)(colormap->ColorizeEnd[0] * 255); end_green = (int)(colormap->ColorizeEnd[1] * 255); end_blue = (int)(colormap->ColorizeEnd[2] * 255); - } -#ifdef NO_SSE - void ApplySpecialColormapRGBACommand::Execute(DrawerThread *thread) - { - int y = thread->skipped_by_thread(0); - int count = thread->count_for_thread(0, height); + int y = 0; + int count = height; while (count > 0) { uint8_t *pixels = buffer + y * pitch * 4; @@ -734,15 +678,27 @@ namespace swrenderer pixels += 4; } - y += thread->num_cores; + y++; count--; } } #else - void ApplySpecialColormapRGBACommand::Execute(DrawerThread *thread) + void SWTruecolorDrawers::ApplySpecialColormap(FSpecialColormap* colormap, DFrameBuffer* screen) { - int y = thread->skipped_by_thread(0); - int count = thread->count_for_thread(0, height); + 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; __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) @@ -836,7 +792,7 @@ namespace swrenderer pixels += 4; } - y += thread->num_cores; + y++; count--; } } @@ -845,33 +801,21 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////////// - DrawParticleColumnRGBACommand::DrawParticleColumnRGBACommand(uint32_t *dest, int dest_y, int pitch, int count, uint32_t fg, uint32_t alpha, uint32_t fracposx) + void SWTruecolorDrawers::DrawParticleColumn(int x, int _dest_y, int _count, uint32_t _fg, uint32_t _alpha, uint32_t _fracposx) { - _dest = dest; - _pitch = pitch; - _count = count; - _fg = fg; - _alpha = alpha; - _fracposx = fracposx; - _dest_y = dest_y; - } + uint32_t* dest = (uint32_t*)thread->Viewport->GetDest(x, _dest_y); + int pitch = thread->Viewport->RenderTarget->GetPitch(); - void DrawParticleColumnRGBACommand::Execute(DrawerThread *thread) - { - int count = thread->count_for_thread(_dest_y, _count); + int count = _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(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 * thread->skipped_by_thread(_dest_y) + fracstep / 2; - fracstep *= thread->num_cores; + uint32_t fracpos = fracstep / 2; uint32_t fg_red = (_fg >> 16) & 0xff; uint32_t fg_green = (_fg >> 8) & 0xff; @@ -898,37 +842,208 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////////// - DrawVoxelBlocksRGBACommand::DrawVoxelBlocksRGBACommand(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount) : args(args), blocks(blocks), blockcount(blockcount) - { - } - - void DrawVoxelBlocksRGBACommand::Execute(DrawerThread *thread) + void SWTruecolorDrawers::DrawVoxelBlocks(const SpriteDrawerArgs& args, const VoxelBlock* blocks, int blockcount) { int pitch = args.Viewport()->RenderTarget->GetPitch(); uint8_t *destorig = args.Viewport()->RenderTarget->GetPixels(); - DrawSprite32Command drawer(args); - drawer.args.dc_texturefracx = 0; - drawer.args.dc_source2 = 0; + SpriteDrawerArgs drawerargs = args; + drawerargs.dc_texturefracx = 0; + drawerargs.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; - 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; + 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; for (int j = 0; j < block.width; j++) { - drawer.Execute(thread); - drawer.args.dc_dest += 4; + DrawSprite32Command::DrawColumn(drawerargs); + drawerargs.dc_dest += 4; } } } + + ///////////////////////////////////////////////////////////////////////////// + + template + 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(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 + 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(texelStepX) * (1.0 / 0x1'0000'0000LL)); + double ymagnitude = fabs(static_cast(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(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); + } } diff --git a/src/rendering/swrenderer/drawers/r_draw_rgba.h b/src/rendering/swrenderer/drawers/r_draw_rgba.h index 2182909eed9..0babc563b9d 100644 --- a/src/rendering/swrenderer/drawers/r_draw_rgba.h +++ b/src/rendering/swrenderer/drawers/r_draw_rgba.h @@ -25,6 +25,7 @@ #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" @@ -70,125 +71,6 @@ 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 class DrawerBlendCommand : public CommandType { @@ -207,38 +89,6 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////////// - class DrawParticleColumnRGBACommand : public DrawerCommand - { - public: - DrawParticleColumnRGBACommand(uint32_t *dest, int dest_y, int pitch, int count, uint32_t fg, uint32_t alpha, uint32_t fracposx); - void Execute(DrawerThread *thread) override; - - private: - uint32_t *_dest; - int _dest_y; - int _pitch; - int _count; - uint32_t _fg; - uint32_t _alpha; - uint32_t _fracposx; - }; - - ///////////////////////////////////////////////////////////////////////////// - - class DrawVoxelBlocksRGBACommand : public DrawerCommand - { - public: - DrawVoxelBlocksRGBACommand(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount); - void Execute(DrawerThread *thread) override; - - private: - SpriteDrawerArgs args; - const VoxelBlock *blocks; - int blockcount; - }; - - ///////////////////////////////////////////////////////////////////////////// - class SWTruecolorDrawers : public SWPixelFormatDrawers { public: @@ -277,15 +127,19 @@ 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 { Queue->Push(args); } + void FillSpan(const SpanDrawerArgs& args) override; + void DrawTiltedSpan(const SpanDrawerArgs& args, const FVector3& plane_sz, const FVector3& plane_su, const FVector3& plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap* basecolormap) override; + void DrawColoredSpan(const SpanDrawerArgs& args) override; + void DrawFogBoundaryLine(const SpanDrawerArgs& args) override; + void DrawParticleColumn(int x, int yl, int ycount, uint32_t fg, uint32_t alpha, uint32_t fracposx) override; - void DrawTiltedSpan(const SpanDrawerArgs &args, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap) override - { - Queue->Push(args, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy); - } + void DrawScaledFuzzColumn(const SpriteDrawerArgs& args); + void DrawUnscaledFuzzColumn(const SpriteDrawerArgs& args); + + template void DrawWallColumns(const WallDrawerArgs& args); + template void DrawWallColumn32(WallColumnDrawerArgs& drawerargs, int x, int y1, int y2, uint32_t texelX, uint32_t texelY, uint32_t texelStepX, uint32_t texelStepY); - void DrawColoredSpan(const SpanDrawerArgs &args) override { Queue->Push(args); } - void DrawFogBoundaryLine(const SpanDrawerArgs &args) override { Queue->Push(args); } + WallColumnDrawerArgs wallcolargs; }; ///////////////////////////////////////////////////////////////////////////// diff --git a/src/rendering/swrenderer/drawers/r_draw_sky32.h b/src/rendering/swrenderer/drawers/r_draw_sky32.h index bc65e41e270..df208afabf9 100644 --- a/src/rendering/swrenderer/drawers/r_draw_sky32.h +++ b/src/rendering/swrenderer/drawers/r_draw_sky32.h @@ -27,16 +27,10 @@ namespace swrenderer { - - class DrawSkySingle32Command : public DrawerCommand + class DrawSkySingle32Command { - protected: - SkyDrawerArgs args; - public: - DrawSkySingle32Command(const SkyDrawerArgs &args) : args(args) { } - - void Execute(DrawerThread *thread) override + static void DrawColumn(const SkyDrawerArgs& args) { uint32_t *dest = (uint32_t *)args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); @@ -50,9 +44,7 @@ namespace swrenderer uint32_t solid_bottom = args.SolidBottomColor(); bool fadeSky = args.FadeSky(); - 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; + int count = args.Count(); // 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 @@ -66,15 +58,8 @@ 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; @@ -89,7 +74,7 @@ namespace swrenderer BgraColor solid_top_fill = solid_top; BgraColor solid_bottom_fill = solid_bottom; - int index = skipped; + int index = 0; // Top solid color: while (index < start_fadetop_y) @@ -97,7 +82,7 @@ namespace swrenderer *dest = solid_top; dest += pitch; frac += fracstep; - index += num_cores; + index++; } // Top fade: @@ -117,7 +102,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Textured center: @@ -128,7 +113,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Fade bottom: @@ -148,7 +133,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Bottom solid color: @@ -156,20 +141,15 @@ namespace swrenderer { *dest = solid_bottom; dest += pitch; - index += num_cores; + index++; } } }; - class DrawSkyDouble32Command : public DrawerCommand + class DrawSkyDouble32Command { - protected: - SkyDrawerArgs args; - public: - DrawSkyDouble32Command(const SkyDrawerArgs &args) : args(args) { } - - void Execute(DrawerThread *thread) override + static void DrawColumn(const SkyDrawerArgs& args) { uint32_t *dest = (uint32_t *)args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); @@ -181,9 +161,7 @@ namespace swrenderer int32_t frac = args.TextureVPos(); int32_t fracstep = args.TextureVStep(); - 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; + int count = args.Count(); uint32_t solid_top = args.SolidTopColor(); uint32_t solid_bottom = args.SolidBottomColor(); @@ -201,15 +179,8 @@ 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; @@ -231,7 +202,7 @@ namespace swrenderer BgraColor solid_top_fill = solid_top; BgraColor solid_bottom_fill = solid_bottom; - int index = skipped; + int index = 0; // Top solid color: while (index < start_fadetop_y) @@ -239,7 +210,7 @@ namespace swrenderer *dest = solid_top; dest += pitch; frac += fracstep; - index += num_cores; + index++; } // Top fade: @@ -262,7 +233,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Textured center: @@ -279,7 +250,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Fade bottom: @@ -302,7 +273,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Bottom solid color: @@ -310,7 +281,7 @@ namespace swrenderer { *dest = solid_bottom; dest += pitch; - index += num_cores; + index++; } } }; diff --git a/src/rendering/swrenderer/drawers/r_draw_sky32_sse2.h b/src/rendering/swrenderer/drawers/r_draw_sky32_sse2.h index 64afca87ac6..998833416c1 100644 --- a/src/rendering/swrenderer/drawers/r_draw_sky32_sse2.h +++ b/src/rendering/swrenderer/drawers/r_draw_sky32_sse2.h @@ -27,15 +27,10 @@ namespace swrenderer { - class DrawSkySingle32Command : public DrawerCommand + class DrawSkySingle32Command { - protected: - SkyDrawerArgs args; - public: - DrawSkySingle32Command(const SkyDrawerArgs &args) : args(args) { } - - void Execute(DrawerThread *thread) override + static void DrawColumn(const SkyDrawerArgs& args) { uint32_t *dest = (uint32_t *)args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); @@ -49,9 +44,7 @@ namespace swrenderer uint32_t solid_bottom = args.SolidBottomColor(); bool fadeSky = args.FadeSky(); - 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; + int count = args.Count(); // 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 @@ -65,15 +58,8 @@ 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; @@ -88,7 +74,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 = skipped; + int index = 0; // Top solid color: while (index < start_fadetop_y) @@ -96,7 +82,7 @@ namespace swrenderer *dest = solid_top; dest += pitch; frac += fracstep; - index += num_cores; + index++; } // Top fade: @@ -114,7 +100,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Textured center: @@ -125,7 +111,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Fade bottom: @@ -143,7 +129,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Bottom solid color: @@ -151,20 +137,15 @@ namespace swrenderer { *dest = solid_bottom; dest += pitch; - index += num_cores; + index++; } } }; - class DrawSkyDouble32Command : public DrawerCommand + class DrawSkyDouble32Command { - protected: - SkyDrawerArgs args; - public: - DrawSkyDouble32Command(const SkyDrawerArgs &args) : args(args) { } - - void Execute(DrawerThread *thread) override + static void DrawColumn(const SkyDrawerArgs& args) { uint32_t *dest = (uint32_t *)args.Dest(); int pitch = args.Viewport()->RenderTarget->GetPitch(); @@ -176,35 +157,14 @@ namespace swrenderer int32_t frac = args.TextureVPos(); int32_t fracstep = args.TextureVStep(); - 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; + int count = args.Count(); 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; @@ -223,10 +183,22 @@ 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 = skipped; + int index = 0; // Top solid color: while (index < start_fadetop_y) @@ -234,7 +206,7 @@ namespace swrenderer *dest = solid_top; dest += pitch; frac += fracstep; - index += num_cores; + index++; } // Top fade: @@ -257,7 +229,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Textured center: @@ -274,7 +246,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Fade bottom: @@ -297,7 +269,7 @@ namespace swrenderer frac += fracstep; dest += pitch; - index += num_cores; + index++; } // Bottom solid color: @@ -305,7 +277,7 @@ namespace swrenderer { *dest = solid_bottom; dest += pitch; - index += num_cores; + index++; } } }; diff --git a/src/rendering/swrenderer/drawers/r_draw_span32.h b/src/rendering/swrenderer/drawers/r_draw_span32.h index f0b83c79670..9534c496b02 100644 --- a/src/rendering/swrenderer/drawers/r_draw_span32.h +++ b/src/rendering/swrenderer/drawers/r_draw_span32.h @@ -51,14 +51,9 @@ namespace swrenderer } template - class DrawSpan32T : public DrawerCommand + class DrawSpan32T { - protected: - SpanDrawerArgs args; - public: - DrawSpan32T(const SpanDrawerArgs &drawerargs) : args(drawerargs) { } - struct TextureData { uint32_t width; @@ -72,12 +67,10 @@ namespace swrenderer const uint32_t *source; }; - void Execute(DrawerThread *thread) override + static void DrawColumn(const SpanDrawerArgs& args) { using namespace DrawSpan32TModes; - if (thread->line_skipped_by_thread(args.DestY())) return; - TextureData texdata; texdata.width = args.TextureWidth(); texdata.height = args.TextureHeight(); @@ -119,16 +112,16 @@ namespace swrenderer if (is_nearest_filter) { if (is_64x64) - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); else - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); } else { if (is_64x64) - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); else - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); } } else @@ -136,22 +129,22 @@ namespace swrenderer if (is_nearest_filter) { if (is_64x64) - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); else - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); } else { if (is_64x64) - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); else - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); } } } template - FORCEINLINE void Loop(DrawerThread *thread, TextureData texdata, ShadeConstants shade_constants) + FORCEINLINE static void Loop(const SpanDrawerArgs& args, TextureData texdata, ShadeConstants shade_constants) { using namespace DrawSpan32TModes; @@ -229,7 +222,7 @@ namespace swrenderer } template - FORCEINLINE uint32_t Sample(uint32_t width, uint32_t height, uint32_t xone, uint32_t yone, uint32_t xstep, uint32_t ystep, uint32_t xfrac, uint32_t yfrac, const uint32_t *source) + FORCEINLINE static uint32_t Sample(uint32_t width, uint32_t height, uint32_t xone, uint32_t yone, uint32_t xstep, uint32_t ystep, uint32_t xfrac, uint32_t yfrac, const uint32_t *source) { using namespace DrawSpan32TModes; @@ -291,7 +284,7 @@ namespace swrenderer } template - FORCEINLINE BgraColor Shade(BgraColor fgcolor, uint32_t light, uint32_t desaturate, uint32_t inv_desaturate, BgraColor shade_fade, BgraColor shade_light, const DrawerLight *lights, int num_lights, float viewpos_x) + FORCEINLINE static BgraColor Shade(BgraColor fgcolor, uint32_t light, uint32_t desaturate, uint32_t inv_desaturate, BgraColor shade_fade, BgraColor shade_light, const DrawerLight *lights, int num_lights, float viewpos_x) { using namespace DrawSpan32TModes; @@ -313,7 +306,7 @@ namespace swrenderer return AddLights(material, fgcolor, lights, num_lights, viewpos_x); } - FORCEINLINE BgraColor AddLights(BgraColor material, BgraColor fgcolor, const DrawerLight *lights, int num_lights, float viewpos_x) + FORCEINLINE static BgraColor AddLights(BgraColor material, BgraColor fgcolor, const DrawerLight *lights, int num_lights, float viewpos_x) { using namespace DrawSpan32TModes; @@ -365,7 +358,7 @@ namespace swrenderer return fgcolor; } - FORCEINLINE BgraColor Blend(BgraColor fgcolor, BgraColor bgcolor, uint32_t srcalpha, uint32_t destalpha, unsigned int ifgcolor) + FORCEINLINE static BgraColor Blend(BgraColor fgcolor, BgraColor bgcolor, uint32_t srcalpha, uint32_t destalpha, unsigned int ifgcolor) { using namespace DrawSpan32TModes; diff --git a/src/rendering/swrenderer/drawers/r_draw_span32_sse2.h b/src/rendering/swrenderer/drawers/r_draw_span32_sse2.h index f5823a3eb7f..527545a9d61 100644 --- a/src/rendering/swrenderer/drawers/r_draw_span32_sse2.h +++ b/src/rendering/swrenderer/drawers/r_draw_span32_sse2.h @@ -51,14 +51,9 @@ namespace swrenderer } template - class DrawSpan32T : public DrawerCommand + class DrawSpan32T { - protected: - SpanDrawerArgs args; - public: - DrawSpan32T(const SpanDrawerArgs &drawerargs) : args(drawerargs) { } - struct TextureData { uint32_t width; @@ -72,12 +67,10 @@ namespace swrenderer const uint32_t *source; }; - void Execute(DrawerThread *thread) override + static void DrawColumn(const SpanDrawerArgs& args) { using namespace DrawSpan32TModes; - if (thread->line_skipped_by_thread(args.DestY())) return; - TextureData texdata; texdata.width = args.TextureWidth(); texdata.height = args.TextureHeight(); @@ -119,16 +112,16 @@ namespace swrenderer if (is_nearest_filter) { if (is_64x64) - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); else - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); } else { if (is_64x64) - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); else - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); } } else @@ -136,22 +129,22 @@ namespace swrenderer if (is_nearest_filter) { if (is_64x64) - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); else - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); } else { if (is_64x64) - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); else - Loop(thread, texdata, shade_constants); + Loop(args, texdata, shade_constants); } } } template - FORCEINLINE void VECTORCALL Loop(DrawerThread *thread, TextureData texdata, ShadeConstants shade_constants) + FORCEINLINE static void VECTORCALL Loop(const SpanDrawerArgs& args, TextureData texdata, ShadeConstants shade_constants) { using namespace DrawSpan32TModes; @@ -263,7 +256,7 @@ namespace swrenderer } template - FORCEINLINE unsigned int VECTORCALL Sample(uint32_t width, uint32_t height, uint32_t xone, uint32_t yone, uint32_t xstep, uint32_t ystep, uint32_t xfrac, uint32_t yfrac, const uint32_t *source) + FORCEINLINE static unsigned int VECTORCALL Sample(uint32_t width, uint32_t height, uint32_t xone, uint32_t yone, uint32_t xstep, uint32_t ystep, uint32_t xfrac, uint32_t yfrac, const uint32_t *source) { using namespace DrawSpan32TModes; @@ -325,7 +318,7 @@ namespace swrenderer } template - FORCEINLINE __m128i VECTORCALL Shade(__m128i fgcolor, __m128i mlight, unsigned int ifgcolor0, unsigned int ifgcolor1, int desaturate, __m128i inv_desaturate, __m128i shade_fade, __m128i shade_light, const DrawerLight *lights, int num_lights, __m128 viewpos_x) + FORCEINLINE static __m128i VECTORCALL Shade(__m128i fgcolor, __m128i mlight, unsigned int ifgcolor0, unsigned int ifgcolor1, int desaturate, __m128i inv_desaturate, __m128i shade_fade, __m128i shade_light, const DrawerLight *lights, int num_lights, __m128 viewpos_x) { using namespace DrawSpan32TModes; @@ -357,7 +350,7 @@ namespace swrenderer return AddLights(material, fgcolor, lights, num_lights, viewpos_x); } - FORCEINLINE __m128i VECTORCALL AddLights(__m128i material, __m128i fgcolor, const DrawerLight *lights, int num_lights, __m128 viewpos_x) + FORCEINLINE static __m128i VECTORCALL AddLights(__m128i material, __m128i fgcolor, const DrawerLight *lights, int num_lights, __m128 viewpos_x) { using namespace DrawSpan32TModes; @@ -406,7 +399,7 @@ namespace swrenderer return fgcolor; } - FORCEINLINE __m128i VECTORCALL Blend(__m128i fgcolor, __m128i bgcolor, uint32_t srcalpha, uint32_t destalpha, unsigned int ifgcolor0, unsigned int ifgcolor1) + FORCEINLINE static __m128i VECTORCALL Blend(__m128i fgcolor, __m128i bgcolor, uint32_t srcalpha, uint32_t destalpha, unsigned int ifgcolor0, unsigned int ifgcolor1) { using namespace DrawSpan32TModes; diff --git a/src/rendering/swrenderer/drawers/r_draw_sprite32.h b/src/rendering/swrenderer/drawers/r_draw_sprite32.h index e4026468978..7fa300f8202 100644 --- a/src/rendering/swrenderer/drawers/r_draw_sprite32.h +++ b/src/rendering/swrenderer/drawers/r_draw_sprite32.h @@ -54,14 +54,10 @@ namespace swrenderer } template - class DrawSprite32T : public DrawerCommand + class DrawSprite32T { public: - SpriteDrawerArgs args; - - DrawSprite32T(const SpriteDrawerArgs &drawerargs) : args(drawerargs) { } - - void Execute(DrawerThread *thread) override + static void DrawColumn(const SpriteDrawerArgs& args) { using namespace DrawSprite32TModes; @@ -74,33 +70,33 @@ namespace swrenderer if (shade_constants.simple_shade) { if (is_nearest_filter) - Loop(thread, shade_constants); + Loop(args, shade_constants); else - Loop(thread, shade_constants); + Loop(args, shade_constants); } else { if (is_nearest_filter) - Loop(thread, shade_constants); + Loop(args, shade_constants); else - Loop(thread, shade_constants); + Loop(args, shade_constants); } } else // no linear filtering for translated, shaded or fill { if (shade_constants.simple_shade) { - Loop(thread, shade_constants); + Loop(args, shade_constants); } else { - Loop(thread, shade_constants); + Loop(args, shade_constants); } } } template - FORCEINLINE void Loop(DrawerThread *thread, ShadeConstants shade_constants) + FORCEINLINE static void Loop(const SpriteDrawerArgs& args, ShadeConstants shade_constants) { using namespace DrawSprite32TModes; @@ -171,6 +167,8 @@ 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(); @@ -178,13 +176,6 @@ 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; @@ -220,7 +211,7 @@ namespace swrenderer } template - FORCEINLINE BgraColor Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, const uint32_t *translation, int textureheight, uint32_t one, uint32_t texturefracx, uint32_t color, uint32_t srccolor) + FORCEINLINE static BgraColor Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, const uint32_t *translation, int textureheight, uint32_t one, uint32_t texturefracx, uint32_t color, uint32_t srccolor) { using namespace DrawSprite32TModes; @@ -269,7 +260,7 @@ namespace swrenderer } } - FORCEINLINE uint32_t SampleShade(uint32_t frac, const uint32_t *source, const uint8_t *colormap) + FORCEINLINE static uint32_t SampleShade(uint32_t frac, const uint32_t *source, const uint8_t *colormap) { using namespace DrawSprite32TModes; @@ -286,7 +277,7 @@ namespace swrenderer } template - FORCEINLINE BgraColor Shade(BgraColor fgcolor, BgraColor mlight, uint32_t desaturate, uint32_t inv_desaturate, BgraColor shade_fade, BgraColor shade_light, BgraColor lightcontrib) + FORCEINLINE static BgraColor Shade(BgraColor fgcolor, BgraColor mlight, uint32_t desaturate, uint32_t inv_desaturate, BgraColor shade_fade, BgraColor shade_light, BgraColor lightcontrib) { using namespace DrawSprite32TModes; @@ -316,7 +307,7 @@ namespace swrenderer } } - FORCEINLINE BgraColor Blend(BgraColor fgcolor, BgraColor bgcolor, uint32_t ifgcolor, uint32_t ifgshade, uint32_t srcalpha, uint32_t destalpha) + FORCEINLINE static BgraColor Blend(BgraColor fgcolor, BgraColor bgcolor, uint32_t ifgcolor, uint32_t ifgshade, uint32_t srcalpha, uint32_t destalpha) { using namespace DrawSprite32TModes; diff --git a/src/rendering/swrenderer/drawers/r_draw_sprite32_sse2.h b/src/rendering/swrenderer/drawers/r_draw_sprite32_sse2.h index d07dbc5859e..d59f1d204d3 100644 --- a/src/rendering/swrenderer/drawers/r_draw_sprite32_sse2.h +++ b/src/rendering/swrenderer/drawers/r_draw_sprite32_sse2.h @@ -54,14 +54,10 @@ namespace swrenderer } template - class DrawSprite32T : public DrawerCommand + class DrawSprite32T { public: - SpriteDrawerArgs args; - - DrawSprite32T(const SpriteDrawerArgs &drawerargs) : args(drawerargs) { } - - void Execute(DrawerThread *thread) override + static void DrawColumn(const SpriteDrawerArgs& args) { using namespace DrawSprite32TModes; @@ -74,33 +70,33 @@ namespace swrenderer if (shade_constants.simple_shade) { if (is_nearest_filter) - Loop(thread, shade_constants); + Loop(args, shade_constants); else - Loop(thread, shade_constants); + Loop(args, shade_constants); } else { if (is_nearest_filter) - Loop(thread, shade_constants); + Loop(args, shade_constants); else - Loop(thread, shade_constants); + Loop(args, shade_constants); } } else // no linear filtering for translated, shaded or fill { if (shade_constants.simple_shade) { - Loop(thread, shade_constants); + Loop(args, shade_constants); } else { - Loop(thread, shade_constants); + Loop(args, shade_constants); } } } template - FORCEINLINE void VECTORCALL Loop(DrawerThread *thread, ShadeConstants shade_constants) + FORCEINLINE static void VECTORCALL Loop(const SpriteDrawerArgs& args, ShadeConstants shade_constants) { using namespace DrawSprite32TModes; @@ -162,6 +158,7 @@ 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(); @@ -169,13 +166,6 @@ 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; @@ -255,7 +245,7 @@ namespace swrenderer } template - FORCEINLINE unsigned int VECTORCALL Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, const uint32_t *translation, int textureheight, uint32_t one, uint32_t texturefracx, uint32_t color, uint32_t srccolor) + FORCEINLINE static unsigned int VECTORCALL Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, const uint32_t *translation, int textureheight, uint32_t one, uint32_t texturefracx, uint32_t color, uint32_t srccolor) { using namespace DrawSprite32TModes; @@ -304,7 +294,7 @@ namespace swrenderer } } - FORCEINLINE unsigned int VECTORCALL SampleShade(uint32_t frac, const uint32_t *source, const uint8_t *colormap) + FORCEINLINE static unsigned int VECTORCALL SampleShade(uint32_t frac, const uint32_t *source, const uint8_t *colormap) { using namespace DrawSprite32TModes; @@ -321,7 +311,7 @@ namespace swrenderer } template - FORCEINLINE __m128i VECTORCALL Shade(__m128i fgcolor, __m128i mlight, unsigned int ifgcolor0, unsigned int ifgcolor1, int desaturate, __m128i inv_desaturate, __m128i shade_fade, __m128i shade_light, __m128i lightcontrib) + FORCEINLINE static __m128i VECTORCALL Shade(__m128i fgcolor, __m128i mlight, unsigned int ifgcolor0, unsigned int ifgcolor1, int desaturate, __m128i inv_desaturate, __m128i shade_fade, __m128i shade_light, __m128i lightcontrib) { using namespace DrawSprite32TModes; @@ -360,7 +350,7 @@ namespace swrenderer } } - FORCEINLINE __m128i VECTORCALL Blend(__m128i fgcolor, __m128i bgcolor, unsigned int ifgcolor0, unsigned int ifgcolor1, unsigned int ifgshade0, unsigned int ifgshade1, uint32_t srcalpha, uint32_t destalpha) + FORCEINLINE static __m128i VECTORCALL Blend(__m128i fgcolor, __m128i bgcolor, unsigned int ifgcolor0, unsigned int ifgcolor1, unsigned int ifgshade0, unsigned int ifgshade1, uint32_t srcalpha, uint32_t destalpha) { using namespace DrawSprite32TModes; diff --git a/src/rendering/swrenderer/drawers/r_draw_wall32.h b/src/rendering/swrenderer/drawers/r_draw_wall32.h index 2f40129017b..65f7025b2dc 100644 --- a/src/rendering/swrenderer/drawers/r_draw_wall32.h +++ b/src/rendering/swrenderer/drawers/r_draw_wall32.h @@ -47,12 +47,10 @@ namespace swrenderer } template - class DrawWall32T : public DrawWallCommand + class DrawWall32T { public: - DrawWall32T(const WallDrawerArgs &drawerargs) : DrawWallCommand(drawerargs) { } - - void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override + static void DrawColumn(const WallColumnDrawerArgs& args) { using namespace DrawWall32TModes; @@ -62,24 +60,27 @@ namespace swrenderer if (shade_constants.simple_shade) { if (is_nearest_filter) - Loop(thread, args, shade_constants); + Loop(args, shade_constants); else - Loop(thread, args, shade_constants); + Loop(args, shade_constants); } else { if (is_nearest_filter) - Loop(thread, args, shade_constants); + Loop(args, shade_constants); else - Loop(thread, args, shade_constants); + Loop(args, shade_constants); } } template - FORCEINLINE void Loop(DrawerThread *thread, const WallColumnDrawerArgs& args, ShadeConstants shade_constants) + FORCEINLINE static void Loop(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(); @@ -115,7 +116,6 @@ 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,15 +125,8 @@ namespace swrenderer auto lights = args.dc_lights; auto num_lights = args.dc_num_lights; - float viewpos_z = args.dc_viewpos.Z + args.dc_viewpos_step.Z * thread->skipped_by_thread(dest_y); - float 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; + float viewpos_z = args.dc_viewpos.Z; + float step_viewpos_z = args.dc_viewpos_step.Z; if (FilterModeT::Mode == (int)FilterModes::Linear) { @@ -167,7 +160,7 @@ namespace swrenderer } template - FORCEINLINE BgraColor Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, int textureheight, uint32_t one, uint32_t texturefracx) + FORCEINLINE static BgraColor Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, int textureheight, uint32_t one, uint32_t texturefracx) { using namespace DrawWall32TModes; @@ -203,7 +196,7 @@ namespace swrenderer } template - FORCEINLINE BgraColor Shade(BgraColor fgcolor, uint32_t light, uint32_t desaturate, uint32_t inv_desaturate, BgraColor shade_fade, BgraColor shade_light, const DrawerLight *lights, int num_lights, float viewpos_z) + FORCEINLINE static BgraColor Shade(BgraColor fgcolor, uint32_t light, uint32_t desaturate, uint32_t inv_desaturate, BgraColor shade_fade, BgraColor shade_light, const DrawerLight *lights, int num_lights, float viewpos_z) { using namespace DrawWall32TModes; @@ -225,7 +218,7 @@ namespace swrenderer return AddLights(material, fgcolor, lights, num_lights, viewpos_z); } - FORCEINLINE BgraColor AddLights(BgraColor material, BgraColor fgcolor, const DrawerLight *lights, int num_lights, float viewpos_z) + FORCEINLINE static BgraColor AddLights(BgraColor material, BgraColor fgcolor, const DrawerLight *lights, int num_lights, float viewpos_z) { using namespace DrawWall32TModes; @@ -277,7 +270,7 @@ namespace swrenderer return fgcolor; } - FORCEINLINE BgraColor Blend(BgraColor fgcolor, BgraColor bgcolor, unsigned int ifgcolor, uint32_t srcalpha, uint32_t destalpha) + FORCEINLINE static BgraColor Blend(BgraColor fgcolor, BgraColor bgcolor, unsigned int ifgcolor, uint32_t srcalpha, uint32_t destalpha) { using namespace DrawWall32TModes; diff --git a/src/rendering/swrenderer/drawers/r_draw_wall32_sse2.h b/src/rendering/swrenderer/drawers/r_draw_wall32_sse2.h index 5316a9e0308..4ea8d4d7590 100644 --- a/src/rendering/swrenderer/drawers/r_draw_wall32_sse2.h +++ b/src/rendering/swrenderer/drawers/r_draw_wall32_sse2.h @@ -47,12 +47,10 @@ namespace swrenderer } template - class DrawWall32T : public DrawWallCommand + class DrawWall32T { public: - DrawWall32T(const WallDrawerArgs &drawerargs) : DrawWallCommand(drawerargs) { } - - void DrawColumn(DrawerThread *thread, const WallColumnDrawerArgs& args) override + static void DrawColumn(const WallColumnDrawerArgs& args) { using namespace DrawWall32TModes; @@ -62,21 +60,21 @@ namespace swrenderer if (shade_constants.simple_shade) { if (is_nearest_filter) - Loop(thread, args, shade_constants); + Loop(args, shade_constants); else - Loop(thread, args, shade_constants); + Loop(args, shade_constants); } else { if (is_nearest_filter) - Loop(thread, args, shade_constants); + Loop(args, shade_constants); else - Loop(thread, args, shade_constants); + Loop(args, shade_constants); } } template - FORCEINLINE void VECTORCALL Loop(DrawerThread *thread, const WallColumnDrawerArgs& args, ShadeConstants shade_constants) + FORCEINLINE static void VECTORCALL Loop(const WallColumnDrawerArgs& args, ShadeConstants shade_constants) { using namespace DrawWall32TModes; @@ -110,6 +108,8 @@ 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,18 +119,11 @@ namespace swrenderer auto lights = args.dc_lights; auto num_lights = args.dc_num_lights; - float vpz = args.dc_viewpos.Z + args.dc_viewpos_step.Z * thread->skipped_by_thread(dest_y); - float stepvpz = args.dc_viewpos_step.Z * thread->num_cores; + float vpz = args.dc_viewpos.Z; + float stepvpz = args.dc_viewpos_step.Z; __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; @@ -203,7 +196,7 @@ namespace swrenderer } template - FORCEINLINE unsigned int VECTORCALL Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, int textureheight, uint32_t one, uint32_t texturefracx) + FORCEINLINE static unsigned int VECTORCALL Sample(uint32_t frac, const uint32_t *source, const uint32_t *source2, int textureheight, uint32_t one, uint32_t texturefracx) { using namespace DrawWall32TModes; @@ -239,7 +232,7 @@ namespace swrenderer } template - FORCEINLINE __m128i VECTORCALL Shade(__m128i fgcolor, __m128i mlight, unsigned int ifgcolor0, unsigned int ifgcolor1, int desaturate, __m128i inv_desaturate, __m128i shade_fade, __m128i shade_light, const DrawerLight *lights, int num_lights, __m128 viewpos_z) + FORCEINLINE static __m128i VECTORCALL Shade(__m128i fgcolor, __m128i mlight, unsigned int ifgcolor0, unsigned int ifgcolor1, int desaturate, __m128i inv_desaturate, __m128i shade_fade, __m128i shade_light, const DrawerLight *lights, int num_lights, __m128 viewpos_z) { using namespace DrawWall32TModes; @@ -271,7 +264,7 @@ namespace swrenderer return AddLights(material, fgcolor, lights, num_lights, viewpos_z); } - FORCEINLINE __m128i VECTORCALL AddLights(__m128i material, __m128i fgcolor, const DrawerLight *lights, int num_lights, __m128 viewpos_z) + FORCEINLINE static __m128i VECTORCALL AddLights(__m128i material, __m128i fgcolor, const DrawerLight *lights, int num_lights, __m128 viewpos_z) { using namespace DrawWall32TModes; @@ -320,7 +313,7 @@ namespace swrenderer return fgcolor; } - FORCEINLINE __m128i VECTORCALL Blend(__m128i fgcolor, __m128i bgcolor, unsigned int ifgcolor0, unsigned int ifgcolor1, uint32_t srcalpha, uint32_t destalpha) + FORCEINLINE static __m128i VECTORCALL Blend(__m128i fgcolor, __m128i bgcolor, unsigned int ifgcolor0, unsigned int ifgcolor1, uint32_t srcalpha, uint32_t destalpha) { using namespace DrawWall32TModes; diff --git a/src/rendering/swrenderer/line/r_walldraw.cpp b/src/rendering/swrenderer/line/r_walldraw.cpp index 61945fefb01..1d4a4c64cb8 100644 --- a/src/rendering/swrenderer/line/r_walldraw.cpp +++ b/src/rendering/swrenderer/line/r_walldraw.cpp @@ -81,8 +81,6 @@ 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())) { diff --git a/src/rendering/swrenderer/plane/r_skyplane.cpp b/src/rendering/swrenderer/plane/r_skyplane.cpp index cb1069913a9..48639768ac2 100644 --- a/src/rendering/swrenderer/plane/r_skyplane.cpp +++ b/src/rendering/swrenderer/plane/r_skyplane.cpp @@ -59,8 +59,6 @@ CVAR(Bool, r_linearsky, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); EXTERN_CVAR(Int, r_skymode) EXTERN_CVAR(Bool, cl_oldfreelooklimit) -std::pair& R_GetSkyCapColor(FGameTexture* tex); - namespace swrenderer { static FSoftwareTexture *GetSWTex(FTextureID texid, bool allownull = true) @@ -216,9 +214,6 @@ namespace swrenderer drawerargs.SetStyle(); - Thread->PrepareTexture(frontskytex, DefaultRenderStyle()); - Thread->PrepareTexture(backskytex, DefaultRenderStyle()); - DrawSky(pl); } @@ -255,6 +250,8 @@ 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); @@ -262,9 +259,8 @@ namespace swrenderer drawerargs.SetDest(viewport, start_x, y1); drawerargs.SetCount(y2 - y1); drawerargs.SetFadeSky(r_skymode == 2 && !(Level->flags & LEVEL_FORCETILEDSKY)); - auto& col = R_GetSkyCapColor(frontskytex->GetTexture()); - drawerargs.SetSolidTop(col.first); - drawerargs.SetSolidBottom(col.second); + drawerargs.SetSolidTop(skycapcolors.first); + drawerargs.SetSolidBottom(skycapcolors.second); if (!backskytex) drawerargs.DrawSingleSkyColumn(Thread); diff --git a/src/rendering/swrenderer/r_renderthread.cpp b/src/rendering/swrenderer/r_renderthread.cpp index f2fb7bb99de..4c3e4d2c665 100644 --- a/src/rendering/swrenderer/r_renderthread.cpp +++ b/src/rendering/swrenderer/r_renderthread.cpp @@ -53,6 +53,9 @@ #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& R_GetSkyCapColor(FGameTexture* tex); namespace swrenderer { @@ -63,7 +66,6 @@ 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()); @@ -73,8 +75,9 @@ namespace swrenderer PlaneList.reset(new VisiblePlaneList(this)); DrawSegments.reset(new DrawSegmentList(this)); ClipSegments.reset(new RenderClipSegment()); - tc_drawers.reset(new SWTruecolorDrawers(DrawQueue)); - pal_drawers.reset(new SWPalDrawers(DrawQueue)); + Poly.reset(new PolyTriangleThreadData(0, 1, 0, 1, 0, screen->GetHeight())); + tc_drawers.reset(new SWTruecolorDrawers(this)); + pal_drawers.reset(new SWPalDrawers(this)); } RenderThread::~RenderThread() @@ -89,33 +92,13 @@ namespace swrenderer return pal_drawers.get(); } - 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::mutex loadmutex; + std::pair RenderThread::GetSkyCapColor(FSoftwareTexture* tex) + { std::unique_lock lock(loadmutex); - - 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); - } + std::pair colors = R_GetSkyCapColor(tex->GetTexture()); + return colors; } static std::mutex polyobjmutex; diff --git a/src/rendering/swrenderer/r_renderthread.h b/src/rendering/swrenderer/r_renderthread.h index 5e7b4f818e4..ba862c77524 100644 --- a/src/rendering/swrenderer/r_renderthread.h +++ b/src/rendering/swrenderer/r_renderthread.h @@ -25,9 +25,8 @@ #include #include -class DrawerCommandQueue; -typedef std::shared_ptr DrawerCommandQueuePtr; class RenderMemory; +class PolyTriangleThreadData; struct FDynamicLight; EXTERN_CVAR(Bool, r_models); @@ -51,6 +50,7 @@ namespace swrenderer class SWPixelFormatDrawers; class SWTruecolorDrawers; class SWPalDrawers; + class WallColumnDrawerArgs; class RenderThread { @@ -75,7 +75,7 @@ namespace swrenderer std::unique_ptr ClipSegments; std::unique_ptr Viewport; std::unique_ptr Light; - DrawerCommandQueuePtr DrawQueue; + std::unique_ptr Poly; TArray 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 GetSkyCapColor(FSoftwareTexture* tex); private: std::unique_ptr tc_drawers; diff --git a/src/rendering/swrenderer/scene/r_scene.cpp b/src/rendering/swrenderer/scene/r_scene.cpp index 7c6e6f6a3d6..2558a2f2aff 100644 --- a/src/rendering/swrenderer/scene/r_scene.cpp +++ b/src/rendering/swrenderer/scene/r_scene.cpp @@ -66,14 +66,14 @@ void PeekThreadedErrorPane(); EXTERN_CVAR(Int, r_clearbuffer) EXTERN_CVAR(Int, r_debug_draw) -CVAR(Int, r_scene_multithreaded, 0, 0); +CVAR(Int, r_scene_multithreaded, 1, 0); CVAR(Bool, r_models, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); bool r_modelscene = false; namespace swrenderer { - cycle_t WallCycles, PlaneCycles, MaskedCycles, DrawerWaitCycles; + cycle_t WallCycles, PlaneCycles, MaskedCycles; RenderScene::RenderScene() { @@ -131,7 +131,6 @@ namespace swrenderer for (int i = 0; i < size; i++) dest[i] = bgracolor.d; } - DrawerThreads::ResetDebugDrawPos(); } RenderActorView(player->mo, true, false); @@ -141,11 +140,8 @@ namespace swrenderer auto copyqueue = std::make_shared(MainThread()->FrameMemory.get()); copyqueue->Push(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) @@ -153,7 +149,6 @@ namespace swrenderer WallCycles.Reset(); PlaneCycles.Reset(); MaskedCycles.Reset(); - DrawerWaitCycles.Reset(); R_SetupFrame(MainThread()->Viewport->viewpoint, MainThread()->Viewport->viewwindow, actor); @@ -194,14 +189,7 @@ 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() @@ -231,6 +219,7 @@ namespace swrenderer Threads[i]->X2 = viewwidth * (i + 1) / numThreads; } run_id++; + FSoftwareTexture::CurrentUpdate = run_id; start_lock.unlock(); // Notify threads to run @@ -267,7 +256,6 @@ namespace swrenderer void RenderScene::RenderThreadSlice(RenderThread *thread) { - thread->DrawQueue->Clear(); thread->FrameMemory->Clear(); thread->Clip3D->Cleanup(); thread->Clip3D->ResetClip(); // reset clips (floor/ceiling) @@ -306,7 +294,37 @@ namespace swrenderer thread->TranslucentPass->Render(); } - DrawerThreads::Execute(thread->DrawQueue); +#if 0 // shows the render slice edges + if (thread->Viewport->RenderTarget->IsBgra()) + { + uint32_t* left = (uint32_t*)thread->Viewport->GetDest(thread->X1, 0); + uint32_t* right = (uint32_t*)thread->Viewport->GetDest(thread->X2 - 1, 0); + int pitch = thread->Viewport->RenderTarget->GetPitch(); + uint32_t c = MAKEARGB(255, 0, 0, 0); + for (int i = 0; i < viewheight; i++) + { + *left = c; + *right = c; + left += pitch; + right += pitch; + } + } + else + { + uint8_t* left = (uint8_t*)thread->Viewport->GetDest(thread->X1, 0); + uint8_t* right = (uint8_t*)thread->Viewport->GetDest(thread->X2 - 1, 0); + int pitch = thread->Viewport->RenderTarget->GetPitch(); + int r = 0, g = 0, b = 0; + uint8_t c = RGB32k.RGB[(r >> 3)][(g >> 3)][(b >> 3)]; + for (int i = 0; i < viewheight; i++) + { + *left = c; + *right = c; + left += pitch; + right += pitch; + } + } +#endif } void RenderScene::StartThreads(size_t numThreads) @@ -390,9 +408,6 @@ namespace swrenderer // Render: RenderActorView(actor, false, dontmaplines); - DrawerWaitCycles.Clock(); - DrawerThreads::WaitForWorkers(); - DrawerWaitCycles.Unclock(); viewport->RenderingToCanvas = false; @@ -418,12 +433,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 drawers=%04.1f ms", - FrameCycles.TimeMS(), WallCycles.TimeMS(), PlaneCycles.TimeMS(), MaskedCycles.TimeMS(), DrawerWaitCycles.TimeMS()); + 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()); return out; } - static double f_acc, w_acc, p_acc, m_acc, drawer_acc; + static double f_acc, w_acc, p_acc, m_acc; static int acc_c; ADD_STAT(fps_accumulated) @@ -432,11 +447,10 @@ 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 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); + 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); Printf(PRINT_LOG, "%s\n", out.GetChars()); return out; } diff --git a/src/rendering/swrenderer/textures/r_swtexture.cpp b/src/rendering/swrenderer/textures/r_swtexture.cpp index c41837d36fd..662c12d573f 100644 --- a/src/rendering/swrenderer/textures/r_swtexture.cpp +++ b/src/rendering/swrenderer/textures/r_swtexture.cpp @@ -39,7 +39,7 @@ #include "m_alloc.h" #include "imagehelpers.h" #include "texturemanager.h" - +#include inline EUpscaleFlags scaleFlagFromUseType(ETextureType useType) { @@ -119,7 +119,7 @@ void FSoftwareTexture::CalcBitSize () // //========================================================================== -const uint8_t *FSoftwareTexture::GetPixels(int style) +const uint8_t *FSoftwareTexture::GetPixelsLocked(int style) { if (Pixels.Size() == 0 || CheckModified(style)) { @@ -158,13 +158,7 @@ const uint8_t *FSoftwareTexture::GetPixels(int style) return Pixels.Data(); } -//========================================================================== -// -// -// -//========================================================================== - -const uint32_t *FSoftwareTexture::GetPixelsBgra() +const uint32_t *FSoftwareTexture::GetPixelsBgraLocked() { if (PixelsBgra.Size() == 0 || CheckModified(2)) { @@ -197,60 +191,31 @@ const uint32_t *FSoftwareTexture::GetPixelsBgra() // //========================================================================== -const uint8_t *FSoftwareTexture::GetColumn(int index, unsigned int column, const FSoftwareTextureSpan **spans_out) -{ - auto Pixeldata = GetPixels(index); - if ((unsigned)column >= (unsigned)GetPhysicalWidth()) - { - if (WidthMask + 1 == GetPhysicalWidth()) - { - column &= WidthMask; - } - else - { - column %= GetPhysicalWidth(); - } - } - if (spans_out != nullptr) - { - if (Spandata[index] == nullptr) - { - Spandata[index] = CreateSpans(Pixeldata); - } - *spans_out = Spandata[index][column]; - } - return Pixeldata + column * GetPhysicalHeight(); -} - -//========================================================================== -// -// -// -//========================================================================== +int FSoftwareTexture::CurrentUpdate = 0; +namespace swrenderer { extern std::mutex loadmutex; } -const uint32_t *FSoftwareTexture::GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out) +void FSoftwareTexture::UpdatePixels(int index) { - auto Pixeldata = GetPixelsBgra(); - if ((unsigned)column >= (unsigned)GetPhysicalWidth()) + std::unique_lock lock(swrenderer::loadmutex); + if (Unlockeddata[index].LastUpdate != CurrentUpdate) { - if (WidthMask + 1 == GetPhysicalWidth()) + if (index != 2) { - column &= WidthMask; + const uint8_t* Pixeldata = GetPixelsLocked(index); + if (Spandata[index] == nullptr) + Spandata[index] = CreateSpans(Pixeldata); + Unlockeddata[index].Pixels = Pixeldata; + Unlockeddata[index].LastUpdate = CurrentUpdate; } else { - column %= GetPhysicalWidth(); - } - } - if (spans_out != nullptr) - { - if (Spandata[2] == nullptr) - { - Spandata[2] = CreateSpans(Pixeldata); + const uint32_t* Pixeldata = GetPixelsBgraLocked(); + if (Spandata[index] == nullptr) + Spandata[index] = CreateSpans(Pixeldata); + Unlockeddata[index].Pixels = Pixeldata; + Unlockeddata[index].LastUpdate = CurrentUpdate; } - *spans_out = Spandata[2][column]; } - return Pixeldata + column * GetPhysicalHeight(); } //========================================================================== @@ -562,15 +527,23 @@ void FSoftwareTexture::FreeAllSpans() } } +// Note: this function needs to be thread safe FSoftwareTexture* GetSoftwareTexture(FGameTexture* tex) { FSoftwareTexture* SoftwareTexture = static_cast(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); + static std::mutex loadmutex; + std::unique_lock lock(loadmutex); + + SoftwareTexture = static_cast(tex->GetSoftwareTexture()); + if (!SoftwareTexture) + { + if (tex->isSoftwareCanvas()) SoftwareTexture = new FSWCanvasTexture(tex); + else if (tex->isWarped()) SoftwareTexture = new FWarpTexture(tex, tex->isWarped()); + else SoftwareTexture = new FSoftwareTexture(tex); + tex->SetSoftwareTexture(SoftwareTexture); + } } return SoftwareTexture; } @@ -582,6 +555,7 @@ 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(); diff --git a/src/rendering/swrenderer/textures/r_swtexture.h b/src/rendering/swrenderer/textures/r_swtexture.h index f053f8552d2..54597d0c6de 100644 --- a/src/rendering/swrenderer/textures/r_swtexture.h +++ b/src/rendering/swrenderer/textures/r_swtexture.h @@ -20,6 +20,11 @@ class FSoftwareTexture : public ISoftwareTexture FTexture *mSource; TArray Pixels; TArray PixelsBgra; + struct + { + const void* Pixels = nullptr; + int LastUpdate = -1; + } Unlockeddata[3]; FSoftwareTextureSpan **Spandata[3] = { }; DVector2 Scale; uint8_t WidthBits = 0, HeightBits = 0; @@ -94,6 +99,7 @@ class FSoftwareTexture : public ISoftwareTexture { Pixels.Reset(); PixelsBgra.Reset(); + for (auto& d : Unlockeddata) d = {}; } // Returns true if the next call to GetPixels() will return an image different from the @@ -110,16 +116,69 @@ class FSoftwareTexture : public ISoftwareTexture virtual bool Mipmapped() { return true; } // Returns a single column of the texture - virtual const uint8_t *GetColumn(int style, unsigned int column, const FSoftwareTextureSpan **spans_out); + const uint8_t* GetColumn(int style, unsigned int column, const FSoftwareTextureSpan** spans_out) + { + column = WrapColumn(column); + const uint8_t* pixels = GetPixels(style); + if (spans_out) + *spans_out = Spandata[style][column]; + return pixels + column * GetPhysicalHeight(); + } // Returns a single column of the texture, in BGRA8 format - virtual const uint32_t *GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out); + const uint32_t* GetColumnBgra(unsigned int column, const FSoftwareTextureSpan** spans_out) + { + column = WrapColumn(column); + const uint32_t* pixels = GetPixelsBgra(); + if (spans_out) + *spans_out = Spandata[2][column]; + return pixels + column * GetPhysicalHeight(); + } + + unsigned int WrapColumn(unsigned int column) + { + if ((unsigned)column >= (unsigned)GetPhysicalWidth()) + { + if (WidthMask + 1 == GetPhysicalWidth()) + { + column &= WidthMask; + } + else + { + column %= GetPhysicalWidth(); + } + } + return column; + } // Returns the whole texture, stored in column-major order, in BGRA8 format - virtual const uint32_t *GetPixelsBgra(); + const uint32_t* GetPixelsBgra() + { + int style = 2; + if (Unlockeddata[2].LastUpdate == CurrentUpdate) + { + return static_cast(Unlockeddata[style].Pixels); + } + else + { + UpdatePixels(style); + return static_cast(Unlockeddata[style].Pixels); + } + } // Returns the whole texture, stored in column-major order - virtual const uint8_t *GetPixels(int style); + const uint8_t* GetPixels(int style) + { + if (Unlockeddata[style].LastUpdate == CurrentUpdate) + { + return static_cast(Unlockeddata[style].Pixels); + } + else + { + UpdatePixels(style); + return static_cast(Unlockeddata[style].Pixels); + } + } const uint8_t *GetPixels(FRenderStyle style) { @@ -139,6 +198,11 @@ class FSoftwareTexture : public ISoftwareTexture 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. @@ -154,8 +218,8 @@ class FWarpTexture : public FSoftwareTexture public: FWarpTexture (FGameTexture *source, int warptype); - const uint32_t *GetPixelsBgra() override; - const uint8_t *GetPixels(int style) override; + const uint32_t *GetPixelsBgraLocked() override; + const uint8_t *GetPixelsLocked(int style) override; bool CheckModified (int which) override; void GenerateBgraMipmapsFast(); @@ -179,8 +243,8 @@ class FSWCanvasTexture : public FSoftwareTexture ~FSWCanvasTexture(); // Returns the whole texture, stored in column-major order - const uint32_t *GetPixelsBgra() override; - const uint8_t *GetPixels(int style) override; + const uint32_t *GetPixelsBgraLocked() override; + const uint8_t *GetPixelsLocked(int style) override; virtual void Unload() override; void UpdatePixels(bool truecolor); diff --git a/src/rendering/swrenderer/textures/swcanvastexture.cpp b/src/rendering/swrenderer/textures/swcanvastexture.cpp index db9471774b2..91385fe0cd0 100644 --- a/src/rendering/swrenderer/textures/swcanvastexture.cpp +++ b/src/rendering/swrenderer/textures/swcanvastexture.cpp @@ -77,7 +77,7 @@ FSWCanvasTexture::~FSWCanvasTexture() // //========================================================================== -const uint8_t *FSWCanvasTexture::GetPixels(int style) +const uint8_t *FSWCanvasTexture::GetPixelsLocked(int style) { static_cast(mSource)->NeedUpdate(); if (Canvas == nullptr) @@ -94,7 +94,7 @@ const uint8_t *FSWCanvasTexture::GetPixels(int style) // //========================================================================== -const uint32_t *FSWCanvasTexture::GetPixelsBgra() +const uint32_t *FSWCanvasTexture::GetPixelsBgraLocked() { static_cast(mSource)->NeedUpdate(); if (CanvasBgra == nullptr) diff --git a/src/rendering/swrenderer/textures/warptexture.cpp b/src/rendering/swrenderer/textures/warptexture.cpp index 49869f8d6da..ce3cb2f522c 100644 --- a/src/rendering/swrenderer/textures/warptexture.cpp +++ b/src/rendering/swrenderer/textures/warptexture.cpp @@ -57,7 +57,7 @@ bool FWarpTexture::CheckModified (int style) return screen->FrameTime != GenTime[style]; } -const uint32_t *FWarpTexture::GetPixelsBgra() +const uint32_t *FWarpTexture::GetPixelsBgraLocked() { uint64_t time = screen->FrameTime; uint64_t resizeMult = gl_texture_hqresizemult; @@ -67,7 +67,7 @@ const uint32_t *FWarpTexture::GetPixelsBgra() if (gl_texture_hqresizemode == 0 || gl_texture_hqresizemult < 1 || !(gl_texture_hqresize_targets & 1)) resizeMult = 1; - auto otherpix = FSoftwareTexture::GetPixelsBgra(); + auto otherpix = FSoftwareTexture::GetPixelsBgraLocked(); 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::GetPixelsBgra() } -const uint8_t *FWarpTexture::GetPixels(int index) +const uint8_t *FWarpTexture::GetPixelsLocked(int index) { uint64_t time = screen->FrameTime; uint64_t resizeMult = gl_texture_hqresizemult; @@ -88,7 +88,7 @@ const uint8_t *FWarpTexture::GetPixels(int index) if (gl_texture_hqresizemode == 0 || gl_texture_hqresizemult < 1 || !(gl_texture_hqresize_targets & 1)) resizeMult = 1; - const uint8_t *otherpix = FSoftwareTexture::GetPixels(index); + const uint8_t *otherpix = FSoftwareTexture::GetPixelsLocked(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(); diff --git a/src/rendering/swrenderer/things/r_decal.cpp b/src/rendering/swrenderer/things/r_decal.cpp index df8f6fb387b..ffe06c0a1bd 100644 --- a/src/rendering/swrenderer/things/r_decal.cpp +++ b/src/rendering/swrenderer/things/r_decal.cpp @@ -240,7 +240,6 @@ 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); } diff --git a/src/rendering/swrenderer/things/r_particle.cpp b/src/rendering/swrenderer/things/r_particle.cpp index a91ddb47392..6e9f2b00ed8 100644 --- a/src/rendering/swrenderer/things/r_particle.cpp +++ b/src/rendering/swrenderer/things/r_particle.cpp @@ -231,7 +231,6 @@ 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; @@ -250,33 +249,18 @@ namespace swrenderer uint32_t alpha = fglevel * 256 / FRACUNIT; auto viewport = thread->Viewport.get(); - - spacing = viewport->RenderTarget->GetPitch(); + auto drawers = thread->Drawers(viewport); uint32_t fracstepx = PARTICLE_TEXTURE_SIZE * FRACUNIT / countbase; uint32_t fracposx = fracstepx / 2; RenderTranslucentPass *translucentPass = thread->TranslucentPass.get(); - if (viewport->RenderTarget->IsBgra()) + for (int x = x1; x < (x1 + countbase); x++, fracposx += fracstepx) { - for (int x = x1; x < (x1 + countbase); x++, fracposx += fracstepx) - { - if (translucentPass->ClipSpriteColumnWithPortals(x, vis)) - continue; - uint32_t *dest = (uint32_t*)viewport->GetDest(x, yl); - thread->DrawQueue->Push(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(dest, yl, spacing, ycount, fg, alpha, fracposx); - } + if (translucentPass->ClipSpriteColumnWithPortals(x, vis)) + continue; + drawers->DrawParticleColumn(x, yl, ycount, fg, alpha, fracposx); } } diff --git a/src/rendering/swrenderer/things/r_sprite.cpp b/src/rendering/swrenderer/things/r_sprite.cpp index 2a7722a58bf..8f47c524b7b 100644 --- a/src/rendering/swrenderer/things/r_sprite.cpp +++ b/src/rendering/swrenderer/things/r_sprite.cpp @@ -262,8 +262,7 @@ namespace swrenderer { RenderTranslucentPass *translucentPass = thread->TranslucentPass.get(); short portalfloorclip[MAXWIDTH]; - int x2 = wallc.sx2; - for (int x = wallc.sx1; x < x2; x++) + for (int x = x1; x < x2; x++) { if (translucentPass->ClipSpriteColumnWithPortals(x, this)) portalfloorclip[x] = mceilingclip[x]; @@ -271,8 +270,6 @@ namespace swrenderer portalfloorclip[x] = mfloorclip[x]; } - thread->PrepareTexture(pic, RenderStyle); - ProjectedWallLight mlight; mlight.SetSpriteLight(); diff --git a/src/rendering/swrenderer/things/r_wallsprite.cpp b/src/rendering/swrenderer/things/r_wallsprite.cpp index bccea75a6eb..bc14fc148ee 100644 --- a/src/rendering/swrenderer/things/r_wallsprite.cpp +++ b/src/rendering/swrenderer/things/r_wallsprite.cpp @@ -176,8 +176,6 @@ 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++) diff --git a/src/rendering/swrenderer/viewport/r_spandrawer.cpp b/src/rendering/swrenderer/viewport/r_spandrawer.cpp index 51da4fb4630..c101ac80c4d 100644 --- a/src/rendering/swrenderer/viewport/r_spandrawer.cpp +++ b/src/rendering/swrenderer/viewport/r_spandrawer.cpp @@ -32,8 +32,6 @@ 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(); diff --git a/src/rendering/swrenderer/viewport/r_spritedrawer.h b/src/rendering/swrenderer/viewport/r_spritedrawer.h index 2ab3b97cc7f..e1c504f7c63 100644 --- a/src/rendering/swrenderer/viewport/r_spritedrawer.h +++ b/src/rendering/swrenderer/viewport/r_spritedrawer.h @@ -111,7 +111,7 @@ namespace swrenderer RenderViewport *dc_viewport = nullptr; - friend class DrawVoxelBlocksRGBACommand; - friend class DrawVoxelBlocksPalCommand; + friend class SWTruecolorDrawers; + friend class SWPalDrawers; }; }