Move particle drawing to a command to prevent pipeline stalls

This commit is contained in:
Magnus Norddahl 2016-12-24 01:50:54 +01:00
parent 2bb2395569
commit 52892cb7ef
3 changed files with 70 additions and 23 deletions

View file

@ -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:

View file

@ -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";
}
}

View file

@ -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<DrawParticleColumnRGBACommand>(dest, yl, spacing, ycount, fg, alpha);
}
}