Fix pal particle performance issue

This commit is contained in:
Magnus Norddahl 2016-12-27 03:31:34 +01:00
parent 66b154a475
commit bafc985282
4 changed files with 119 additions and 104 deletions

View file

@ -3445,4 +3445,85 @@ namespace swrenderer
dest[x] = colormap[dest[x]]; dest[x] = colormap[dest[x]];
} while (++x <= x2); } while (++x <= x2);
} }
/////////////////////////////////////////////////////////////////////////////
namespace
{
static uint32_t particle_texture[16 * 16] =
{
1 * 1, 2 * 1, 3 * 1, 4 * 1, 5 * 1, 6 * 1, 7 * 1, 8 * 1, 8 * 1, 7 * 1, 6 * 1, 5 * 1, 4 * 1, 3 * 1, 2 * 1, 1 * 1,
1 * 2, 2 * 2, 3 * 2, 4 * 2, 5 * 2, 6 * 2, 7 * 2, 8 * 2, 8 * 2, 7 * 2, 6 * 2, 5 * 2, 4 * 2, 3 * 2, 2 * 2, 1 * 2,
1 * 3, 2 * 3, 3 * 3, 4 * 3, 5 * 3, 6 * 3, 7 * 3, 8 * 3, 8 * 3, 7 * 3, 6 * 3, 5 * 3, 4 * 3, 3 * 3, 2 * 3, 1 * 3,
1 * 4, 2 * 4, 3 * 4, 4 * 4, 5 * 4, 6 * 4, 7 * 4, 8 * 4, 8 * 4, 7 * 4, 6 * 4, 5 * 4, 4 * 4, 3 * 4, 2 * 4, 1 * 4,
1 * 5, 2 * 5, 3 * 5, 4 * 5, 5 * 5, 6 * 5, 7 * 5, 8 * 5, 8 * 5, 7 * 5, 6 * 5, 5 * 5, 4 * 5, 3 * 5, 2 * 5, 1 * 5,
1 * 6, 2 * 6, 3 * 6, 4 * 6, 5 * 6, 6 * 6, 7 * 6, 8 * 6, 8 * 6, 7 * 6, 6 * 6, 5 * 6, 4 * 6, 3 * 6, 2 * 6, 1 * 6,
1 * 7, 2 * 7, 3 * 7, 4 * 7, 5 * 7, 6 * 7, 7 * 7, 8 * 7, 8 * 7, 7 * 7, 6 * 7, 5 * 7, 4 * 7, 3 * 7, 2 * 7, 1 * 7,
1 * 8, 2 * 8, 3 * 8, 4 * 8, 5 * 8, 6 * 8, 7 * 8, 8 * 8, 8 * 8, 7 * 8, 6 * 8, 5 * 8, 4 * 8, 3 * 8, 2 * 8, 1 * 8,
1 * 8, 2 * 8, 3 * 8, 4 * 8, 5 * 8, 6 * 8, 7 * 8, 8 * 8, 8 * 8, 7 * 8, 6 * 8, 5 * 8, 4 * 8, 3 * 8, 2 * 8, 1 * 8,
1 * 7, 2 * 7, 3 * 7, 4 * 7, 5 * 7, 6 * 7, 7 * 7, 8 * 7, 8 * 7, 7 * 7, 6 * 7, 5 * 7, 4 * 7, 3 * 7, 2 * 7, 1 * 7,
1 * 6, 2 * 6, 3 * 6, 4 * 6, 5 * 6, 6 * 6, 7 * 6, 8 * 6, 8 * 6, 7 * 6, 6 * 6, 5 * 6, 4 * 6, 3 * 6, 2 * 6, 1 * 6,
1 * 5, 2 * 5, 3 * 5, 4 * 5, 5 * 5, 6 * 5, 7 * 5, 8 * 5, 8 * 5, 7 * 5, 6 * 5, 5 * 5, 4 * 5, 3 * 5, 2 * 5, 1 * 5,
1 * 4, 2 * 4, 3 * 4, 4 * 4, 5 * 4, 6 * 4, 7 * 4, 8 * 4, 8 * 4, 7 * 4, 6 * 4, 5 * 4, 4 * 4, 3 * 4, 2 * 4, 1 * 4,
1 * 3, 2 * 3, 3 * 3, 4 * 3, 5 * 3, 6 * 3, 7 * 3, 8 * 3, 8 * 3, 7 * 3, 6 * 3, 5 * 3, 4 * 3, 3 * 3, 2 * 3, 1 * 3,
1 * 2, 2 * 2, 3 * 2, 4 * 2, 5 * 2, 6 * 2, 7 * 2, 8 * 2, 8 * 2, 7 * 2, 6 * 2, 5 * 2, 4 * 2, 3 * 2, 2 * 2, 1 * 2,
1 * 1, 2 * 1, 3 * 1, 4 * 1, 5 * 1, 6 * 1, 7 * 1, 8 * 1, 8 * 1, 7 * 1, 6 * 1, 5 * 1, 4 * 1, 3 * 1, 2 * 1, 1 * 1
};
}
DrawParticleColumnPalCommand::DrawParticleColumnPalCommand(uint8_t *dest, int dest_y, int pitch, 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;
}
void DrawParticleColumnPalCommand::Execute(DrawerThread *thread)
{
int count = thread->count_for_thread(_dest_y, _count);
if (count <= 0)
return;
uint8_t *dest = thread->dest_for_thread(_dest_y, _pitch, _dest);
int pitch = _pitch * thread->num_cores;
const uint32_t *source = &particle_texture[(_fracposx >> FRACBITS) * 16];
uint32_t particle_alpha = _alpha;
uint32_t fracstep = 16 * FRACUNIT / _count;
uint32_t fracpos = fracstep * thread->skipped_by_thread(_dest_y) + fracstep / 2;
fracstep *= thread->num_cores;
uint32_t fg_red = (_fg >> 16) & 0xff;
uint32_t fg_green = (_fg >> 8) & 0xff;
uint32_t fg_blue = _fg & 0xff;
for (int y = 0; y < count; y++)
{
uint32_t alpha = (source[fracpos >> FRACBITS] * particle_alpha) >> 6;
uint32_t inv_alpha = 256 - alpha;
int bg = *dest;
uint32_t bg_red = GPalette.BaseColors[bg].r;
uint32_t bg_green = GPalette.BaseColors[bg].g;
uint32_t bg_blue = GPalette.BaseColors[bg].b;
uint32_t red = (fg_red * alpha + bg_red * inv_alpha) / 256;
uint32_t green = (fg_green * alpha + bg_green * inv_alpha) / 256;
uint32_t blue = (fg_blue * alpha + bg_blue * inv_alpha) / 256;
*dest = RGB256k.All[((red >> 2) << 12) | ((green >> 2) << 6) | (blue >> 2)];
dest += pitch;
fracpos += fracstep;
}
}
FString DrawParticleColumnPalCommand::DebugInfo()
{
return "DrawParticle";
}
} }

View file

@ -260,4 +260,20 @@ namespace swrenderer
const uint8_t *_colormap; const uint8_t *_colormap;
uint8_t *_destorg; uint8_t *_destorg;
}; };
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;
FString DebugInfo() override;
private:
uint8_t *_dest;
int _pitch;
int _count;
uint32_t _fg;
uint32_t _alpha;
uint32_t _fracposx;
};
} }

View file

@ -59,6 +59,7 @@
#include "r_segs.h" #include "r_segs.h"
#include "r_3dfloors.h" #include "r_3dfloors.h"
#include "r_draw_rgba.h" #include "r_draw_rgba.h"
#include "r_draw_pal.h"
#include "v_palette.h" #include "v_palette.h"
#include "r_data/r_translate.h" #include "r_data/r_translate.h"
#include "r_data/colormaps.h" #include "r_data/colormaps.h"
@ -2712,105 +2713,9 @@ static void R_DrawMaskedSegsBehindParticle (const vissprite_t *vis)
} }
} }
//inline int clamp(int x, int y, int z) { return ((x < y) ? x : (z < y) ? z : y); } void R_DrawParticle(vissprite_t *vis)
void R_DrawParticle (vissprite_t *vis)
{
if (r_swtruecolor)
return R_DrawParticle_rgba(vis);
DWORD *bg2rgb;
int spacing;
BYTE *dest;
DWORD fg;
BYTE color = vis->Style.BaseColormap->Maps[(vis->Style.ColormapNum << COLORMAPSHIFT) + vis->startfrac];
int yl = vis->y1;
int ycount = vis->y2 - yl + 1;
int x1 = vis->x1;
int countbase = vis->x2 - x1;
R_DrawMaskedSegsBehindParticle (vis);
DrawerCommandQueue::WaitForWorkers();
// vis->renderflags holds translucency level (0-255)
fixed_t fglevel, bglevel;
{
DWORD *fg2rgb;
fglevel = ((vis->renderflags + 1) << 8) & ~0x3ff;
bglevel = FRACUNIT-fglevel;
fg2rgb = Col2RGB8[fglevel>>10];
bg2rgb = Col2RGB8[bglevel>>10];
fg = fg2rgb[color];
}
/*
spacing = RenderTarget->GetPitch() - countbase;
dest = ylookup[yl] + x1 + dc_destorg;
do
{
int count = countbase;
do
{
DWORD bg = bg2rgb[*dest];
bg = (fg+bg) | 0x1f07c1f;
*dest++ = RGB32k.All[bg & (bg>>15)];
} while (--count);
dest += spacing;
} while (--ycount);*/
// original was row-wise
// width = countbase
// height = ycount
spacing = RenderTarget->GetPitch();
if (!r_blendmethod)
{
for (int x = x1; x < (x1+countbase); x++)
{
dc_x = x;
if (R_ClipSpriteColumnWithPortals(vis))
continue;
dest = ylookup[yl] + x + dc_destorg;
for (int y = 0; y < ycount; y++)
{
DWORD bg = bg2rgb[*dest];
bg = (fg+bg) | 0x1f07c1f;
*dest = RGB32k.All[bg & (bg>>15)];
dest += spacing;
}
}
}
else
{
for (int x = x1; x < (x1+countbase); x++)
{
dc_x = x;
if (R_ClipSpriteColumnWithPortals(vis))
continue;
dest = ylookup[yl] + x + dc_destorg;
for (int y = 0; y < ycount; y++)
{
uint32_t dest_r = MIN((GPalette.BaseColors[*dest].r * bglevel + GPalette.BaseColors[color].r * fglevel) >> 18, 63);
uint32_t dest_g = MIN((GPalette.BaseColors[*dest].g * bglevel + GPalette.BaseColors[color].g * fglevel) >> 18, 63);
uint32_t dest_b = MIN((GPalette.BaseColors[*dest].b * bglevel + GPalette.BaseColors[color].b * fglevel) >> 18, 63);
*dest = RGB256k.RGB[dest_r][dest_g][dest_b];
dest += spacing;
}
}
}
}
void R_DrawParticle_rgba(vissprite_t *vis)
{ {
int spacing; int spacing;
uint32_t *dest;
BYTE color = vis->Style.BaseColormap->Maps[vis->startfrac]; BYTE color = vis->Style.BaseColormap->Maps[vis->startfrac];
int yl = vis->y1; int yl = vis->y1;
int ycount = vis->y2 - yl + 1; int ycount = vis->y2 - yl + 1;
@ -2833,13 +2738,27 @@ void R_DrawParticle_rgba(vissprite_t *vis)
uint32_t fracstepx = 16 * FRACUNIT / countbase; uint32_t fracstepx = 16 * FRACUNIT / countbase;
uint32_t fracposx = fracstepx / 2; uint32_t fracposx = fracstepx / 2;
for (int x = x1; x < (x1 + countbase); x++, fracposx += fracstepx) if (r_swtruecolor)
{ {
dc_x = x; for (int x = x1; x < (x1 + countbase); x++, fracposx += fracstepx)
if (R_ClipSpriteColumnWithPortals(vis)) {
continue; dc_x = x;
dest = ylookup[yl] + x + (uint32_t*)dc_destorg; if (R_ClipSpriteColumnWithPortals(vis))
DrawerCommandQueue::QueueCommand<DrawParticleColumnRGBACommand>(dest, yl, spacing, ycount, fg, alpha, fracposx); continue;
uint32_t *dest = ylookup[yl] + x + (uint32_t*)dc_destorg;
DrawerCommandQueue::QueueCommand<DrawParticleColumnRGBACommand>(dest, yl, spacing, ycount, fg, alpha, fracposx);
}
}
else
{
for (int x = x1; x < (x1 + countbase); x++, fracposx += fracstepx)
{
dc_x = x;
if (R_ClipSpriteColumnWithPortals(vis))
continue;
uint8_t *dest = ylookup[yl] + x + dc_destorg;
DrawerCommandQueue::QueueCommand<DrawParticleColumnPalCommand>(dest, yl, spacing, ycount, fg, alpha, fracposx);
}
} }
} }

View file

@ -101,7 +101,6 @@ struct vissprite_t
}; };
void R_DrawParticle (vissprite_t *); void R_DrawParticle (vissprite_t *);
void R_DrawParticle_rgba (vissprite_t *);
void R_ProjectParticle (particle_t *, const sector_t *sector, int shade, int fakeside); void R_ProjectParticle (particle_t *, const sector_t *sector, int shade, int fakeside);