diff --git a/src/r_draw_rgba.h b/src/r_draw_rgba.h index afb3bc22d6..6d16558c06 100644 --- a/src/r_draw_rgba.h +++ b/src/r_draw_rgba.h @@ -440,6 +440,23 @@ namespace swrenderer FString DebugInfo() override; }; + ///////////////////////////////////////////////////////////////////////////// + + class DrawParticleColumnRGBACommand : public DrawerCommand + { + public: + DrawParticleColumnRGBACommand(uint32_t *dest, int dest_y, int pitch, int count, uint32_t fg, uint32_t alpha); + void Execute(DrawerThread *thread) override; + FString DebugInfo() override; + + private: + uint32_t *_dest; + int _pitch; + int _count; + uint32_t _fg; + uint32_t _alpha; + }; + ///////////////////////////////////////////////////////////////////////////// // Pixel shading inline functions: diff --git a/src/r_drawt_rgba.cpp b/src/r_drawt_rgba.cpp index 5d3064e5d7..3609956fe4 100644 --- a/src/r_drawt_rgba.cpp +++ b/src/r_drawt_rgba.cpp @@ -231,4 +231,56 @@ namespace swrenderer { return "FillColumnHoriz"; } + + ///////////////////////////////////////////////////////////////////////////// + + DrawParticleColumnRGBACommand::DrawParticleColumnRGBACommand(uint32_t *dest, int dest_y, int pitch, int count, uint32_t fg, uint32_t alpha) + { + _dest = dest; + _pitch = pitch; + _count = count; + _fg = fg; + _alpha = alpha; + _dest_y = dest_y; + } + + void DrawParticleColumnRGBACommand::Execute(DrawerThread *thread) + { + int count = thread->count_for_thread(_dest_y, _count); + if (count <= 0) + return; + + uint32_t *dest = thread->dest_for_thread(_dest_y, _pitch, _dest); + int pitch = _pitch * thread->num_cores; + + uint32_t alpha = _alpha; + uint32_t inv_alpha = 256 - alpha; + + uint32_t fg_red = (_fg >> 16) & 0xff; + uint32_t fg_green = (_fg >> 8) & 0xff; + uint32_t fg_blue = _fg & 0xff; + + fg_red *= alpha; + fg_green *= alpha; + fg_blue *= alpha; + + for (int y = 0; y < count; y++) + { + uint32_t bg_red = (*dest >> 16) & 0xff; + uint32_t bg_green = (*dest >> 8) & 0xff; + uint32_t bg_blue = (*dest) & 0xff; + + uint32_t red = (fg_red + bg_red * inv_alpha) / 256; + uint32_t green = (fg_green + bg_green * inv_alpha) / 256; + uint32_t blue = (fg_blue + bg_blue * inv_alpha) / 256; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + } + } + + FString DrawParticleColumnRGBACommand::DebugInfo() + { + return "DrawParticle"; + } } diff --git a/src/r_things.cpp b/src/r_things.cpp index 6e1261c1bb..bbd9eb9cf8 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -2865,21 +2865,11 @@ void R_DrawParticle_rgba(vissprite_t *vis) R_DrawMaskedSegsBehindParticle(vis); - DrawerCommandQueue::WaitForWorkers(); - uint32_t fg = LightBgra::shade_pal_index_simple(color, LightBgra::calc_light_multiplier(LIGHTSCALE(0, vis->Style.ColormapNum << FRACBITS))); - uint32_t fg_red = (fg >> 16) & 0xff; - uint32_t fg_green = (fg >> 8) & 0xff; - uint32_t fg_blue = fg & 0xff; // vis->renderflags holds translucency level (0-255) fixed_t fglevel = ((vis->renderflags + 1) << 8) & ~0x3ff; uint32_t alpha = fglevel * 256 / FRACUNIT; - uint32_t inv_alpha = 256 - alpha; - - fg_red *= alpha; - fg_green *= alpha; - fg_blue *= alpha; spacing = RenderTarget->GetPitch(); @@ -2889,19 +2879,7 @@ void R_DrawParticle_rgba(vissprite_t *vis) if (R_ClipSpriteColumnWithPortals(vis)) continue; dest = ylookup[yl] + x + (uint32_t*)dc_destorg; - for (int y = 0; y < ycount; y++) - { - uint32_t bg_red = (*dest >> 16) & 0xff; - uint32_t bg_green = (*dest >> 8) & 0xff; - uint32_t bg_blue = (*dest) & 0xff; - - uint32_t red = (fg_red + bg_red * inv_alpha) / 256; - uint32_t green = (fg_green + bg_green * inv_alpha) / 256; - uint32_t blue = (fg_blue + bg_blue * inv_alpha) / 256; - - *dest = 0xff000000 | (red << 16) | (green << 8) | blue; - dest += spacing; - } + DrawerCommandQueue::QueueCommand(dest, yl, spacing, ycount, fg, alpha); } }