Add palette version of the blend modes

This commit is contained in:
Magnus Norddahl 2016-11-20 16:42:53 +01:00
parent 6761e8639a
commit bd9ec843dd
6 changed files with 142 additions and 52 deletions

View file

@ -505,7 +505,7 @@ void DrawTriangleCodegen::LoopPartialBlock()
loopy.end_block(); loopy.end_block();
} }
SSAVec4i DrawTriangleCodegen::TranslateSample(SSAInt uvoffset) SSAVec4i DrawTriangleCodegen::TranslateSample32(SSAInt uvoffset)
{ {
if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector) if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector)
return translation[color * 4].load_vec4ub(true); return translation[color * 4].load_vec4ub(true);
@ -513,7 +513,15 @@ SSAVec4i DrawTriangleCodegen::TranslateSample(SSAInt uvoffset)
return translation[texturePixels[uvoffset].load(true).zext_int() * 4].load_vec4ub(true); return translation[texturePixels[uvoffset].load(true).zext_int() * 4].load_vec4ub(true);
} }
SSAVec4i DrawTriangleCodegen::Sample(SSAInt uvoffset) SSAInt DrawTriangleCodegen::TranslateSample8(SSAInt uvoffset)
{
if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector)
return translation[color].load(true).zext_int();
else
return translation[texturePixels[uvoffset].load(true).zext_int()].load(true).zext_int();
}
SSAVec4i DrawTriangleCodegen::Sample32(SSAInt uvoffset)
{ {
if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector) if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector)
return SSAVec4i::unpack(color); return SSAVec4i::unpack(color);
@ -521,6 +529,19 @@ SSAVec4i DrawTriangleCodegen::Sample(SSAInt uvoffset)
return texturePixels[uvoffset * 4].load_vec4ub(true); return texturePixels[uvoffset * 4].load_vec4ub(true);
} }
SSAInt DrawTriangleCodegen::Sample8(SSAInt uvoffset)
{
if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector)
return color;
else
return texturePixels[uvoffset].load(true).zext_int();
}
SSAInt DrawTriangleCodegen::Shade8(SSAInt c)
{
return currentcolormap[c].load(true).zext_int();
}
SSAVec4i DrawTriangleCodegen::ProcessPixel32(SSAVec4i bg, SSAInt *varying) SSAVec4i DrawTriangleCodegen::ProcessPixel32(SSAVec4i bg, SSAInt *varying)
{ {
SSAInt ufrac = varying[0]; SSAInt ufrac = varying[0];
@ -538,48 +559,54 @@ SSAVec4i DrawTriangleCodegen::ProcessPixel32(SSAVec4i bg, SSAInt *varying)
{ {
default: default:
case TriBlendMode::Copy: case TriBlendMode::Copy:
fg = Sample(uvoffset); fg = Sample32(uvoffset);
output = blend_copy(shade_bgra_simple(fg, currentlight)); break; output = blend_copy(shade_bgra_simple(fg, currentlight));
break;
case TriBlendMode::AlphaBlend: case TriBlendMode::AlphaBlend:
fg = Sample(uvoffset); fg = Sample32(uvoffset);
output = blend_alpha_blend(shade_bgra_simple(fg, currentlight), bg); break; output = blend_alpha_blend(shade_bgra_simple(fg, currentlight), bg);
break;
case TriBlendMode::AddSolid: case TriBlendMode::AddSolid:
fg = Sample(uvoffset); fg = Sample32(uvoffset);
output = blend_add(shade_bgra_simple(fg, currentlight), bg, srcalpha, destalpha); break; output = blend_add(shade_bgra_simple(fg, currentlight), bg, srcalpha, destalpha);
break;
case TriBlendMode::Add: case TriBlendMode::Add:
fg = Sample(uvoffset); fg = Sample32(uvoffset);
output = blend_add(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); break; output = blend_add(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha));
break;
case TriBlendMode::Sub: case TriBlendMode::Sub:
fg = Sample(uvoffset); fg = Sample32(uvoffset);
output = blend_sub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); break; output = blend_sub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha));
break;
case TriBlendMode::RevSub: case TriBlendMode::RevSub:
fg = Sample(uvoffset); fg = Sample32(uvoffset);
output = blend_revsub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); break; output = blend_revsub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha));
break;
case TriBlendMode::Shaded: case TriBlendMode::Shaded:
fg = Sample(uvoffset); fg = Sample32(uvoffset);
alpha = fg[0]; alpha = fg[0];
alpha = alpha + (alpha >> 7); // 255 -> 256 alpha = alpha + (alpha >> 7); // 255 -> 256
inv_alpha = 256 - alpha; inv_alpha = 256 - alpha;
output = blend_add(shade_bgra_simple(SSAVec4i::unpack(color), currentlight), bg, alpha, inv_alpha); output = blend_add(shade_bgra_simple(SSAVec4i::unpack(color), currentlight), bg, alpha, inv_alpha);
break; break;
case TriBlendMode::TranslateCopy: case TriBlendMode::TranslateCopy:
fg = TranslateSample(uvoffset); fg = TranslateSample32(uvoffset);
output = blend_copy(shade_bgra_simple(fg, currentlight)); output = blend_copy(shade_bgra_simple(fg, currentlight));
break; break;
case TriBlendMode::TranslateAlphaBlend: case TriBlendMode::TranslateAlphaBlend:
fg = TranslateSample(uvoffset); fg = TranslateSample32(uvoffset);
output = blend_alpha_blend(shade_bgra_simple(fg, currentlight), bg); break; output = blend_alpha_blend(shade_bgra_simple(fg, currentlight), bg);
break; break;
case TriBlendMode::TranslateAdd: case TriBlendMode::TranslateAdd:
fg = TranslateSample(uvoffset); fg = TranslateSample32(uvoffset);
output = blend_add(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); output = blend_add(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha));
break; break;
case TriBlendMode::TranslateSub: case TriBlendMode::TranslateSub:
fg = TranslateSample(uvoffset); fg = TranslateSample32(uvoffset);
output = blend_sub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); output = blend_sub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha));
break; break;
case TriBlendMode::TranslateRevSub: case TriBlendMode::TranslateRevSub:
fg = TranslateSample(uvoffset); fg = TranslateSample32(uvoffset);
output = blend_revsub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); output = blend_revsub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha));
break; break;
} }
@ -587,6 +614,18 @@ SSAVec4i DrawTriangleCodegen::ProcessPixel32(SSAVec4i bg, SSAInt *varying)
return output; return output;
} }
SSAVec4i DrawTriangleCodegen::ToBgra(SSAInt index)
{
SSAVec4i c = BaseColors[index * 4].load_vec4ub(true);
c = c.insert(3, 255);
return c;
}
SSAInt DrawTriangleCodegen::ToPal8(SSAVec4i c)
{
return RGB32k[((c[2] >> 3) * 32 + (c[1] >> 3)) * 32 + (c[0] >> 3)].load(true).zext_int();
}
SSAInt DrawTriangleCodegen::ProcessPixel8(SSAInt bg, SSAInt *varying) SSAInt DrawTriangleCodegen::ProcessPixel8(SSAInt bg, SSAInt *varying)
{ {
SSAInt ufrac = varying[0]; SSAInt ufrac = varying[0];
@ -596,19 +635,65 @@ SSAInt DrawTriangleCodegen::ProcessPixel8(SSAInt bg, SSAInt *varying)
SSAInt vpos = ((vfrac >> 16) * textureHeight) >> 16; SSAInt vpos = ((vfrac >> 16) * textureHeight) >> 16;
SSAInt uvoffset = upos * textureHeight + vpos; SSAInt uvoffset = upos * textureHeight + vpos;
if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector) SSAVec4i fg;
SSAInt alpha, inv_alpha;
SSAInt output;
SSAInt palindex;
switch (blendmode)
{ {
return currentcolormap[color].load(true).zext_int(); default:
} case TriBlendMode::Copy:
else output = Shade8(Sample8(uvoffset));
{ break;
SSAInt index = texturePixels[uvoffset].load(true).zext_int(); case TriBlendMode::AlphaBlend:
SSAInt fg = currentcolormap[index].load(true).zext_int(); palindex = Sample8(uvoffset);
if (blendmode != TriBlendMode::AlphaBlend) output = (palindex == SSAInt(0)).select(bg, Shade8(palindex));
return fg; break;
else case TriBlendMode::AddSolid:
return (index == SSAInt(0)).select(bg, fg); fg = ToBgra(Shade8(Sample8(uvoffset)));
output = ToPal8(blend_add(fg, ToBgra(bg), srcalpha, destalpha));
break;
case TriBlendMode::Add:
fg = ToBgra(Shade8(Sample8(uvoffset)));
output = ToPal8(blend_add(fg, ToBgra(bg), srcalpha, calc_blend_bgalpha(fg, destalpha)));
break;
case TriBlendMode::Sub:
fg = ToBgra(Shade8(Sample8(uvoffset)));
output = ToPal8(blend_sub(fg, ToBgra(bg), srcalpha, calc_blend_bgalpha(fg, destalpha)));
break;
case TriBlendMode::RevSub:
fg = ToBgra(Shade8(Sample8(uvoffset)));
output = ToPal8(blend_revsub(fg, ToBgra(bg), srcalpha, calc_blend_bgalpha(fg, destalpha)));
break;
case TriBlendMode::Shaded:
alpha = Sample8(uvoffset);
alpha = alpha + (alpha >> 7); // 255 -> 256
inv_alpha = 256 - alpha;
output = ToPal8(blend_add(ToBgra(Shade8(color)), ToBgra(bg), alpha, inv_alpha));
break;
case TriBlendMode::TranslateCopy:
output = Shade8(TranslateSample8(uvoffset));
break;
case TriBlendMode::TranslateAlphaBlend:
palindex = TranslateSample8(uvoffset);
output = (palindex == SSAInt(0)).select(bg, Shade8(palindex));
break;
case TriBlendMode::TranslateAdd:
fg = ToBgra(Shade8(Sample8(uvoffset)));
output = ToPal8(blend_add(fg, ToBgra(bg), srcalpha, calc_blend_bgalpha(fg, destalpha)));
break;
case TriBlendMode::TranslateSub:
fg = ToBgra(Shade8(Sample8(uvoffset)));
output = ToPal8(blend_sub(fg, ToBgra(bg), srcalpha, calc_blend_bgalpha(fg, destalpha)));
break;
case TriBlendMode::TranslateRevSub:
fg = ToBgra(Shade8(Sample8(uvoffset)));
output = ToPal8(blend_revsub(fg, ToBgra(bg), srcalpha, calc_blend_bgalpha(fg, destalpha)));
break;
} }
return output;
} }
void DrawTriangleCodegen::SetStencilBlock(SSAInt block) void DrawTriangleCodegen::SetStencilBlock(SSAInt block)
@ -685,9 +770,7 @@ void DrawTriangleCodegen::LoadArgs(SSAValue args, SSAValue thread_data)
{ {
Colormaps = args[0][20].load(true); Colormaps = args[0][20].load(true);
RGB32k = args[0][21].load(true); RGB32k = args[0][21].load(true);
Col2RGB8 = args[0][22].load(true); BaseColors = args[0][22].load(true);
Col2RGB8_LessPrecision = args[0][23].load(true);
Col2RGB8_Inverse = args[0][24].load(true);
} }
thread.core = thread_data[0][0].load(true); thread.core = thread_data[0][0].load(true);

View file

@ -49,8 +49,13 @@ private:
SSAVec4i ProcessPixel32(SSAVec4i bg, SSAInt *varying); SSAVec4i ProcessPixel32(SSAVec4i bg, SSAInt *varying);
SSAInt ProcessPixel8(SSAInt bg, SSAInt *varying); SSAInt ProcessPixel8(SSAInt bg, SSAInt *varying);
SSAVec4i TranslateSample(SSAInt uvoffset); SSAVec4i TranslateSample32(SSAInt uvoffset);
SSAVec4i Sample(SSAInt uvoffset); SSAInt TranslateSample8(SSAInt uvoffset);
SSAVec4i Sample32(SSAInt uvoffset);
SSAInt Sample8(SSAInt uvoffset);
SSAInt Shade8(SSAInt c);
SSAVec4i ToBgra(SSAInt index);
SSAInt ToPal8(SSAVec4i c);
void SetStencilBlock(SSAInt block); void SetStencilBlock(SSAInt block);
void StencilSet(SSAInt x, SSAInt y, SSAUByte value); void StencilSet(SSAInt x, SSAInt y, SSAUByte value);
@ -109,9 +114,7 @@ private:
SSAUBytePtr Colormaps; SSAUBytePtr Colormaps;
SSAUBytePtr RGB32k; SSAUBytePtr RGB32k;
SSAIntPtr Col2RGB8; SSAUBytePtr BaseColors;
SSAIntPtr Col2RGB8_LessPrecision;
SSAIntPtr Col2RGB8_Inverse;
SSAWorkerThread thread; SSAWorkerThread thread;

View file

@ -127,7 +127,7 @@ LLVMDrawers *LLVMDrawers::Instance()
LLVMDrawersImpl::LLVMDrawersImpl() LLVMDrawersImpl::LLVMDrawersImpl()
{ {
int version = 3; // Increment this number if the drawer codegen is modified (forces recreation of the module). int version = 4; // Increment this number if the drawer codegen is modified (forces recreation of the module).
std::string targetCPU = mProgram.GetTargetCPU(); std::string targetCPU = mProgram.GetTargetCPU();
bool loaded = mProgram.LoadCachedModule(version, targetCPU); bool loaded = mProgram.LoadCachedModule(version, targetCPU);
if (!loaded) if (!loaded)
@ -584,9 +584,7 @@ llvm::Type *LLVMDrawersImpl::GetTriDrawTriangleArgs(llvm::LLVMContext &context)
elements.push_back(llvm::Type::getInt32PtrTy(context)); // uint32_t *subsectorGBuffer; elements.push_back(llvm::Type::getInt32PtrTy(context)); // uint32_t *subsectorGBuffer;
elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *colormaps; elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *colormaps;
elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *RGB32k; elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *RGB32k;
elements.push_back(llvm::Type::getInt32PtrTy(context)); // const uint32_t *Col2RGB8; elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *BaseColors;
elements.push_back(llvm::Type::getInt32PtrTy(context)); // const uint32_t *Col2RGB8_LessPrecision;
elements.push_back(llvm::Type::getInt32PtrTy(context)); // const uint32_t *Col2RGB8_Inverse;
return llvm::StructType::create(context, elements, "TriDrawTriangle", false)->getPointerTo(); return llvm::StructType::create(context, elements, "TriDrawTriangle", false)->getPointerTo();
} }

View file

@ -260,9 +260,7 @@ struct TriDrawTriangleArgs
uint32_t *subsectorGBuffer; uint32_t *subsectorGBuffer;
const uint8_t *colormaps; const uint8_t *colormaps;
const uint8_t *RGB32k; const uint8_t *RGB32k;
const uint32_t *Col2RGB8; const uint8_t *BaseColors;
const uint32_t *Col2RGB8_LessPrecision;
const uint32_t *Col2RGB8_Inverse;
}; };
enum class TriDrawVariant enum class TriDrawVariant

View file

@ -82,8 +82,18 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, particle_t *partic
uniforms.flags = 0; uniforms.flags = 0;
} }
uniforms.subsectorDepth = subsectorDepth; uniforms.subsectorDepth = subsectorDepth;
uint32_t alpha = particle->trans;
uniforms.color = (alpha << 24) | (particle->color & 0xffffff); if (r_swtruecolor)
{
uint32_t alpha = particle->trans;
uniforms.color = (alpha << 24) | (particle->color & 0xffffff);
}
else
{
uniforms.color = ((uint32_t)particle->color) >> 24;
uniforms.srcalpha = particle->trans;
uniforms.destalpha = 255 - particle->trans;
}
PolyDrawArgs args; PolyDrawArgs args;
args.uniforms = uniforms; args.uniforms = uniforms;

View file

@ -112,9 +112,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian
args.subsectorGBuffer = PolySubsectorGBuffer::Instance()->Values(); args.subsectorGBuffer = PolySubsectorGBuffer::Instance()->Values();
args.colormaps = drawargs.colormaps; args.colormaps = drawargs.colormaps;
args.RGB32k = RGB32k.All; args.RGB32k = RGB32k.All;
args.Col2RGB8 = (const uint32_t*)Col2RGB8; args.BaseColors = (const uint8_t *)GPalette.BaseColors;
args.Col2RGB8_Inverse = (const uint32_t*)Col2RGB8_Inverse;
args.Col2RGB8_LessPrecision = (const uint32_t*)Col2RGB8_LessPrecision;
bool ccw = drawargs.ccw; bool ccw = drawargs.ccw;
const TriVertex *vinput = drawargs.vinput; const TriVertex *vinput = drawargs.vinput;