Added blending modes to triangle codegen

This commit is contained in:
Magnus Norddahl 2016-11-19 02:53:32 +01:00
parent 5d6ceb868e
commit 272fe7f754
13 changed files with 242 additions and 205 deletions

View file

@ -32,11 +32,14 @@
#include "r_compiler/ssa/ssa_struct_type.h" #include "r_compiler/ssa/ssa_struct_type.h"
#include "r_compiler/ssa/ssa_value.h" #include "r_compiler/ssa/ssa_value.h"
void DrawTriangleCodegen::Generate(TriDrawVariant variant, bool truecolor, SSAValue args, SSAValue thread_data) void DrawTriangleCodegen::Generate(TriDrawVariant variant, TriBlendMode blendmode, bool truecolor, SSAValue args, SSAValue thread_data)
{ {
LoadArgs(variant, truecolor, args, thread_data); this->variant = variant;
Setup(variant, truecolor); this->blendmode = blendmode;
LoopBlockY(variant, truecolor); this->truecolor = truecolor;
LoadArgs(args, thread_data);
Setup();
LoopBlockY();
} }
SSAInt DrawTriangleCodegen::FloatTo28_4(SSAFloat v) SSAInt DrawTriangleCodegen::FloatTo28_4(SSAFloat v)
@ -46,7 +49,7 @@ SSAInt DrawTriangleCodegen::FloatTo28_4(SSAFloat v)
return (a + (a.ashr(31) | SSAInt(1))).ashr(1); return (a + (a.ashr(31) | SSAInt(1))).ashr(1);
} }
void DrawTriangleCodegen::Setup(TriDrawVariant variant, bool truecolor) void DrawTriangleCodegen::Setup()
{ {
int pixelsize = truecolor ? 4 : 1; int pixelsize = truecolor ? 4 : 1;
@ -154,7 +157,7 @@ SSAFloat DrawTriangleCodegen::grady(SSAFloat x0, SSAFloat y0, SSAFloat x1, SSAFl
return top / bottom; return top / bottom;
} }
void DrawTriangleCodegen::LoopBlockY(TriDrawVariant variant, bool truecolor) void DrawTriangleCodegen::LoopBlockY()
{ {
int pixelsize = truecolor ? 4 : 1; int pixelsize = truecolor ? 4 : 1;
@ -171,7 +174,7 @@ void DrawTriangleCodegen::LoopBlockY(TriDrawVariant variant, bool truecolor)
SSAIfBlock branch; SSAIfBlock branch;
branch.if_block((y / q) % thread.num_cores == thread.core); branch.if_block((y / q) % thread.num_cores == thread.core);
{ {
LoopBlockX(variant, truecolor); LoopBlockX();
} }
branch.end_block(); branch.end_block();
@ -182,7 +185,7 @@ void DrawTriangleCodegen::LoopBlockY(TriDrawVariant variant, bool truecolor)
loop.end_block(); loop.end_block();
} }
void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor) void DrawTriangleCodegen::LoopBlockX()
{ {
stack_x.store(minx); stack_x.store(minx);
@ -260,7 +263,7 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor)
SetStencilBlock(x / 8 + y / 8 * stencilPitch); SetStencilBlock(x / 8 + y / 8 * stencilPitch);
SSABool covered = a == SSAInt(0xF) && b == SSAInt(0xF) && c == SSAInt(0xF) && !clipneeded; SSABool covered = a == SSAInt(0xF) && b == SSAInt(0xF) && c == SSAInt(0xF) && !clipneeded;
if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::DrawShadedSubsector && variant != TriDrawVariant::FillSubsector) if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector && variant != TriDrawVariant::FuzzSubsector)
{ {
covered = covered && StencilIsSingleValue(); covered = covered && StencilIsSingleValue();
} }
@ -269,11 +272,11 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor)
SSAIfBlock branch_covered; SSAIfBlock branch_covered;
branch_covered.if_block(covered); branch_covered.if_block(covered);
{ {
LoopFullBlock(variant, truecolor); LoopFullBlock();
} }
branch_covered.else_block(); branch_covered.else_block();
{ {
LoopPartialBlock(variant, truecolor); LoopPartialBlock();
} }
branch_covered.end_block(); branch_covered.end_block();
@ -284,10 +287,10 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor)
loop.end_block(); loop.end_block();
} }
void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor) void DrawTriangleCodegen::LoopFullBlock()
{ {
SSAIfBlock branch_stenciltest; SSAIfBlock branch_stenciltest;
if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::DrawShadedSubsector && variant != TriDrawVariant::FillSubsector) if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector && variant != TriDrawVariant::FuzzSubsector)
{ {
branch_stenciltest.if_block(StencilGetSingle() == stencilTestValue); branch_stenciltest.if_block(StencilGetSingle() == stencilTestValue);
} }
@ -325,18 +328,18 @@ void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor)
varying[i] = stack_varying[i].load(); varying[i] = stack_varying[i].load();
loopx.loop_block(ix < SSAInt(q), q); loopx.loop_block(ix < SSAInt(q), q);
{ {
if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::DrawShadedSubsector || variant == TriDrawVariant::FillSubsector) if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector)
{ {
SSAIfBlock branch; SSAIfBlock branch;
branch.if_block(subsectorbuffer[ix].load(true) >= subsectorDepth); branch.if_block(subsectorbuffer[ix].load(true) >= subsectorDepth);
{ {
ProcessPixel(buffer[ix * pixelsize], subsectorbuffer[ix], varying, variant, truecolor); ProcessPixel(buffer[ix * pixelsize], subsectorbuffer[ix], varying);
} }
branch.end_block(); branch.end_block();
} }
else else
{ {
ProcessPixel(buffer[ix * pixelsize], subsectorbuffer[ix], varying, variant, truecolor); ProcessPixel(buffer[ix * pixelsize], subsectorbuffer[ix], varying);
} }
for (int i = 0; i < TriVertex::NumVarying; i++) for (int i = 0; i < TriVertex::NumVarying; i++)
@ -353,13 +356,13 @@ void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor)
loopy.end_block(); loopy.end_block();
} }
if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::DrawShadedSubsector && variant != TriDrawVariant::FillSubsector) if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector && variant != TriDrawVariant::FuzzSubsector)
{ {
branch_stenciltest.end_block(); branch_stenciltest.end_block();
} }
} }
void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolor) void DrawTriangleCodegen::LoopPartialBlock()
{ {
int pixelsize = truecolor ? 4 : 1; int pixelsize = truecolor ? 4 : 1;
@ -404,7 +407,7 @@ void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolo
SSABool visible = (ix + x >= clipleft) && (ix + x < clipright) && (iy + y >= cliptop) && (iy + y < clipbottom); SSABool visible = (ix + x >= clipleft) && (ix + x < clipright) && (iy + y >= cliptop) && (iy + y < clipbottom);
SSABool covered = CX1 > SSAInt(0) && CX2 > SSAInt(0) && CX3 > SSAInt(0) && visible; SSABool covered = CX1 > SSAInt(0) && CX2 > SSAInt(0) && CX3 > SSAInt(0) && visible;
if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::DrawShadedSubsector || variant == TriDrawVariant::FillSubsector) if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector)
{ {
covered = covered && subsectorbuffer[ix].load(true) >= subsectorDepth; covered = covered && subsectorbuffer[ix].load(true) >= subsectorDepth;
} }
@ -422,7 +425,7 @@ void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolo
} }
else else
{ {
ProcessPixel(buffer[ix * pixelsize], subsectorbuffer[ix], varying, variant, truecolor); ProcessPixel(buffer[ix * pixelsize], subsectorbuffer[ix], varying);
} }
} }
branch.end_block(); branch.end_block();
@ -447,23 +450,23 @@ void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolo
loopy.end_block(); loopy.end_block();
} }
void DrawTriangleCodegen::ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbuffer, SSAInt *varying, TriDrawVariant variant, bool truecolor) SSAVec4i DrawTriangleCodegen::TranslateSample(SSAInt uvoffset)
{ {
if (variant == TriDrawVariant::Fill || variant == TriDrawVariant::FillSubsector) if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector)
{ return translation[color * 4].load_vec4ub(true);
if (truecolor)
{
buffer.store_vec4ub(SSAVec4i::unpack(solidcolor));
}
else else
{ return translation[texturePixels[uvoffset].load(true).zext_int() * 4].load_vec4ub(true);
//buffer.store(solidcolor);
} }
if (variant != TriDrawVariant::FillSubsector) SSAVec4i DrawTriangleCodegen::Sample(SSAInt uvoffset)
subsectorbuffer.store(subsectorDepth); {
} if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector)
return SSAVec4i::unpack(color);
else else
return texturePixels[uvoffset * 4].load_vec4ub(true);
}
void DrawTriangleCodegen::ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbuffer, SSAInt *varying)
{ {
SSAInt ufrac = varying[0]; SSAInt ufrac = varying[0];
SSAInt vfrac = varying[1]; SSAInt vfrac = varying[1];
@ -474,65 +477,75 @@ void DrawTriangleCodegen::ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbu
if (truecolor) if (truecolor)
{ {
if (variant == TriDrawVariant::DrawMasked || variant == TriDrawVariant::DrawSubsector) SSAVec4i fg;
{ SSAVec4i bg = buffer.load_vec4ub(false);
SSAVec4i fg = texturePixels[uvoffset * 4].load_vec4ub(true); SSAInt alpha, inv_alpha;
SSAInt fg_alpha = fg[3]; SSAVec4i output;
fg = (fg * currentlight) >> 8;
fg.insert(3, fg_alpha);
SSAIfBlock branch_transparency; switch (blendmode)
branch_transparency.if_block(fg_alpha > SSAInt(127));
{ {
buffer.store_vec4ub(fg); default:
if (variant != TriDrawVariant::DrawSubsector) case TriBlendMode::Copy:
subsectorbuffer.store(subsectorDepth); fg = Sample(uvoffset);
output = blend_copy(shade_bgra_simple(fg, currentlight)); break;
case TriBlendMode::AlphaBlend:
fg = Sample(uvoffset);
output = blend_alpha_blend(shade_bgra_simple(fg, currentlight), bg); break;
case TriBlendMode::AddSolid:
fg = Sample(uvoffset);
output = blend_add(shade_bgra_simple(fg, currentlight), bg, srcalpha, destalpha); break;
case TriBlendMode::Add:
fg = Sample(uvoffset);
output = blend_add(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); break;
case TriBlendMode::Sub:
fg = Sample(uvoffset);
output = blend_sub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); break;
case TriBlendMode::RevSub:
fg = Sample(uvoffset);
output = blend_revsub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); break;
case TriBlendMode::Shaded:
fg = Sample(uvoffset);
alpha = fg[0];
alpha = alpha + (alpha >> 7); // 255 -> 256
inv_alpha = 256 - alpha;
output = blend_add(shade_bgra_simple(SSAVec4i::unpack(color), currentlight), bg, alpha, inv_alpha);
break;
case TriBlendMode::TranslateCopy:
fg = TranslateSample(uvoffset);
output = blend_copy(shade_bgra_simple(fg, currentlight));
break;
case TriBlendMode::TranslateAdd:
fg = TranslateSample(uvoffset);
output = blend_add(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha));
break;
case TriBlendMode::TranslateSub:
fg = TranslateSample(uvoffset);
output = blend_sub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha));
break;
case TriBlendMode::TranslateRevSub:
fg = TranslateSample(uvoffset);
output = blend_revsub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha));
break;
} }
branch_transparency.end_block();
}
else if (variant == TriDrawVariant::DrawShadedSubsector)
{
SSAInt alpha = texturePixels[uvoffset * 4].load(true).zext_int();
alpha = alpha + (alpha >> 7); // // 255 -> 256
SSAInt inv_alpha = 256 - alpha;
SSAVec4i bgcolor = buffer.load_vec4ub(false); buffer.store_vec4ub(output);
buffer.store_vec4ub(blend_add(shade_bgra_simple(SSAVec4i::unpack(solidcolor), currentlight), bgcolor, alpha, inv_alpha));
} }
else else
{ {
SSAVec4i fg = texturePixels[uvoffset * 4].load_vec4ub(true); if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector)
SSAInt fg_alpha = fg[3]; {
fg = (fg * currentlight) >> 8; buffer.store(color.trunc_ubyte());
fg.insert(3, fg_alpha);
buffer.store_vec4ub(fg);
subsectorbuffer.store(subsectorDepth);
}
} }
else else
{ {
SSAUByte palindex = texturePixels[uvoffset].load(true); SSAUByte fg = texturePixels[uvoffset].load(true);
buffer.store(fg);
}
}
if (variant == TriDrawVariant::DrawMasked || variant == TriDrawVariant::DrawSubsector) if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector && variant != TriDrawVariant::FuzzSubsector)
{
SSAIfBlock branch_transparency;
branch_transparency.if_block(!(palindex.zext_int() == SSAInt(0)));
{
buffer.store(palindex);
if (variant != TriDrawVariant::DrawSubsector)
subsectorbuffer.store(subsectorDepth); subsectorbuffer.store(subsectorDepth);
} }
branch_transparency.end_block();
}
else
{
buffer.store(palindex);
subsectorbuffer.store(subsectorDepth);
}
}
}
}
void DrawTriangleCodegen::SetStencilBlock(SSAInt block) void DrawTriangleCodegen::SetStencilBlock(SSAInt block)
{ {
@ -582,7 +595,7 @@ SSABool DrawTriangleCodegen::StencilIsSingleValue()
return (StencilBlockMask.load(false) & SSAInt(0xffffff00)) == SSAInt(0xffffff00); return (StencilBlockMask.load(false) & SSAInt(0xffffff00)) == SSAInt(0xffffff00);
} }
void DrawTriangleCodegen::LoadArgs(TriDrawVariant variant, bool truecolor, SSAValue args, SSAValue thread_data) void DrawTriangleCodegen::LoadArgs(SSAValue args, SSAValue thread_data)
{ {
dest = args[0][0].load(true); dest = args[0][0].load(true);
pitch = args[0][1].load(true); pitch = args[0][1].load(true);
@ -596,7 +609,7 @@ void DrawTriangleCodegen::LoadArgs(TriDrawVariant variant, bool truecolor, SSAVa
texturePixels = args[0][9].load(true); texturePixels = args[0][9].load(true);
textureWidth = args[0][10].load(true); textureWidth = args[0][10].load(true);
textureHeight = args[0][11].load(true); textureHeight = args[0][11].load(true);
solidcolor = args[0][12].load(true); translation = args[0][12].load(true);
LoadUniforms(args[0][13].load(true)); LoadUniforms(args[0][13].load(true));
stencilValues = args[0][14].load(true); stencilValues = args[0][14].load(true);
stencilMasks = args[0][15].load(true); stencilMasks = args[0][15].load(true);
@ -625,17 +638,20 @@ void DrawTriangleCodegen::LoadUniforms(SSAValue uniforms)
{ {
light = uniforms[0][0].load(true); light = uniforms[0][0].load(true);
subsectorDepth = uniforms[0][1].load(true); subsectorDepth = uniforms[0][1].load(true);
color = uniforms[0][2].load(true);
srcalpha = uniforms[0][3].load(true);
destalpha = uniforms[0][4].load(true);
SSAShort light_alpha = uniforms[0][2].load(true); SSAShort light_alpha = uniforms[0][5].load(true);
SSAShort light_red = uniforms[0][3].load(true); SSAShort light_red = uniforms[0][6].load(true);
SSAShort light_green = uniforms[0][4].load(true); SSAShort light_green = uniforms[0][7].load(true);
SSAShort light_blue = uniforms[0][5].load(true); SSAShort light_blue = uniforms[0][8].load(true);
SSAShort fade_alpha = uniforms[0][6].load(true); SSAShort fade_alpha = uniforms[0][9].load(true);
SSAShort fade_red = uniforms[0][7].load(true); SSAShort fade_red = uniforms[0][10].load(true);
SSAShort fade_green = uniforms[0][8].load(true); SSAShort fade_green = uniforms[0][11].load(true);
SSAShort fade_blue = uniforms[0][9].load(true); SSAShort fade_blue = uniforms[0][12].load(true);
SSAShort desaturate = uniforms[0][10].load(true); SSAShort desaturate = uniforms[0][13].load(true);
SSAInt flags = uniforms[0][11].load(true); SSAInt flags = uniforms[0][14].load(true);
shade_constants.light = SSAVec4i(light_blue.zext_int(), light_green.zext_int(), light_red.zext_int(), light_alpha.zext_int()); shade_constants.light = SSAVec4i(light_blue.zext_int(), light_green.zext_int(), light_red.zext_int(), light_alpha.zext_int());
shade_constants.fade = SSAVec4i(fade_blue.zext_int(), fade_green.zext_int(), fade_red.zext_int(), fade_alpha.zext_int()); shade_constants.fade = SSAVec4i(fade_blue.zext_int(), fade_green.zext_int(), fade_red.zext_int(), fade_alpha.zext_int());
shade_constants.desaturate = desaturate.zext_int(); shade_constants.desaturate = desaturate.zext_int();

View file

@ -33,20 +33,23 @@ struct SSATriVertex
class DrawTriangleCodegen : public DrawerCodegen class DrawTriangleCodegen : public DrawerCodegen
{ {
public: public:
void Generate(TriDrawVariant variant, bool truecolor, SSAValue args, SSAValue thread_data); void Generate(TriDrawVariant variant, TriBlendMode blendmode, bool truecolor, SSAValue args, SSAValue thread_data);
private: private:
void LoadArgs(TriDrawVariant variant, bool truecolor, SSAValue args, SSAValue thread_data); void LoadArgs(SSAValue args, SSAValue thread_data);
SSATriVertex LoadTriVertex(SSAValue v); SSATriVertex LoadTriVertex(SSAValue v);
void LoadUniforms(SSAValue uniforms); void LoadUniforms(SSAValue uniforms);
void Setup(TriDrawVariant variant, bool truecolor); void Setup();
SSAInt FloatTo28_4(SSAFloat v); SSAInt FloatTo28_4(SSAFloat v);
void LoopBlockY(TriDrawVariant variant, bool truecolor); void LoopBlockY();
void LoopBlockX(TriDrawVariant variant, bool truecolor); void LoopBlockX();
void LoopFullBlock(TriDrawVariant variant, bool truecolor); void LoopFullBlock();
void LoopPartialBlock(TriDrawVariant variant, bool truecolor); void LoopPartialBlock();
void ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbuffer, SSAInt *varying, TriDrawVariant variant, bool truecolor); void ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbuffer, SSAInt *varying);
SSAVec4i TranslateSample(SSAInt uvoffset);
SSAVec4i Sample(SSAInt uvoffset);
void SetStencilBlock(SSAInt block); void SetStencilBlock(SSAInt block);
void StencilSet(SSAInt x, SSAInt y, SSAUByte value); void StencilSet(SSAInt x, SSAInt y, SSAUByte value);
@ -58,6 +61,10 @@ private:
SSAFloat gradx(SSAFloat x0, SSAFloat y0, SSAFloat x1, SSAFloat y1, SSAFloat x2, SSAFloat y2, SSAFloat c0, SSAFloat c1, SSAFloat c2); SSAFloat gradx(SSAFloat x0, SSAFloat y0, SSAFloat x1, SSAFloat y1, SSAFloat x2, SSAFloat y2, SSAFloat c0, SSAFloat c1, SSAFloat c2);
SSAFloat grady(SSAFloat x0, SSAFloat y0, SSAFloat x1, SSAFloat y1, SSAFloat x2, SSAFloat y2, SSAFloat c0, SSAFloat c1, SSAFloat c2); SSAFloat grady(SSAFloat x0, SSAFloat y0, SSAFloat x1, SSAFloat y1, SSAFloat x2, SSAFloat y2, SSAFloat c0, SSAFloat c1, SSAFloat c2);
TriDrawVariant variant;
TriBlendMode blendmode;
bool truecolor;
SSAStack<SSAInt> stack_C1, stack_C2, stack_C3; SSAStack<SSAInt> stack_C1, stack_C2, stack_C3;
SSAStack<SSAInt> stack_y; SSAStack<SSAInt> stack_y;
SSAStack<SSAUBytePtr> stack_dest; SSAStack<SSAUBytePtr> stack_dest;
@ -82,7 +89,8 @@ private:
SSAUBytePtr texturePixels; SSAUBytePtr texturePixels;
SSAInt textureWidth; SSAInt textureWidth;
SSAInt textureHeight; SSAInt textureHeight;
SSAInt solidcolor; SSAUBytePtr translation;
SSAInt color, srcalpha, destalpha;
SSAInt light; SSAInt light;
SSAInt subsectorDepth; SSAInt subsectorDepth;

View file

@ -57,7 +57,7 @@ public:
void StopLogFatalErrors(); void StopLogFatalErrors();
template<typename Func> template<typename Func>
Func *GetProcAddress(const char *name) { return reinterpret_cast<Func*>(PointerToFunction(name)); } Func *GetProcAddress(const std::string &name) { return reinterpret_cast<Func*>(PointerToFunction(name.c_str())); }
llvm::LLVMContext &context() { return *mContext; } llvm::LLVMContext &context() { return *mContext; }
llvm::Module *module() { return mModule.get(); } llvm::Module *module() { return mModule.get(); }
@ -82,7 +82,7 @@ private:
void CodegenDrawSpan(const char *name, DrawSpanVariant variant); void CodegenDrawSpan(const char *name, DrawSpanVariant variant);
void CodegenDrawWall(const char *name, DrawWallVariant variant, int columns); void CodegenDrawWall(const char *name, DrawWallVariant variant, int columns);
void CodegenDrawSky(const char *name, DrawSkyVariant variant, int columns); void CodegenDrawSky(const char *name, DrawSkyVariant variant, int columns);
void CodegenDrawTriangle(const char *name, TriDrawVariant variant, bool truecolor); void CodegenDrawTriangle(const std::string &name, TriDrawVariant variant, TriBlendMode blendmode, bool truecolor);
static llvm::Type *GetDrawColumnArgsStruct(llvm::LLVMContext &context); static llvm::Type *GetDrawColumnArgsStruct(llvm::LLVMContext &context);
static llvm::Type *GetDrawSpanArgsStruct(llvm::LLVMContext &context); static llvm::Type *GetDrawSpanArgsStruct(llvm::LLVMContext &context);
@ -186,17 +186,18 @@ LLVMDrawersImpl::LLVMDrawersImpl()
CodegenDrawSky("DrawSky4", DrawSkyVariant::Single, 4); CodegenDrawSky("DrawSky4", DrawSkyVariant::Single, 4);
CodegenDrawSky("DrawDoubleSky1", DrawSkyVariant::Double, 1); CodegenDrawSky("DrawDoubleSky1", DrawSkyVariant::Double, 1);
CodegenDrawSky("DrawDoubleSky4", DrawSkyVariant::Double, 4); CodegenDrawSky("DrawDoubleSky4", DrawSkyVariant::Double, 4);
CodegenDrawTriangle("TriDraw8", TriDrawVariant::Draw, false); for (int i = 0; i < NumTriBlendModes(); i++)
CodegenDrawTriangle("TriDraw32", TriDrawVariant::Draw, true); {
CodegenDrawTriangle("TriDrawSubsector8", TriDrawVariant::DrawSubsector, false); CodegenDrawTriangle("TriDraw8_" + std::to_string(i), TriDrawVariant::DrawNormal, (TriBlendMode)i, false);
CodegenDrawTriangle("TriDrawSubsector32", TriDrawVariant::DrawSubsector, true); CodegenDrawTriangle("TriDraw32_" + std::to_string(i), TriDrawVariant::DrawNormal, (TriBlendMode)i, true);
CodegenDrawTriangle("TriDrawShadedSubsector8", TriDrawVariant::DrawShadedSubsector, false); CodegenDrawTriangle("TriFill8_" + std::to_string(i), TriDrawVariant::FillNormal, (TriBlendMode)i, false);
CodegenDrawTriangle("TriDrawShadedSubsector32", TriDrawVariant::DrawShadedSubsector, true); CodegenDrawTriangle("TriFill32_" + std::to_string(i), TriDrawVariant::FillNormal, (TriBlendMode)i, true);
CodegenDrawTriangle("TriFillSubsector8", TriDrawVariant::FillSubsector, false); CodegenDrawTriangle("TriDrawSubsector8_" + std::to_string(i), TriDrawVariant::DrawSubsector, (TriBlendMode)i, false);
CodegenDrawTriangle("TriFillSubsector32", TriDrawVariant::FillSubsector, true); CodegenDrawTriangle("TriDrawSubsector32_" + std::to_string(i), TriDrawVariant::DrawSubsector, (TriBlendMode)i, true);
CodegenDrawTriangle("TriFill8", TriDrawVariant::Fill, false); CodegenDrawTriangle("TriFillSubsector8_" + std::to_string(i), TriDrawVariant::FillSubsector, (TriBlendMode)i, false);
CodegenDrawTriangle("TriFill32", TriDrawVariant::Fill, true); CodegenDrawTriangle("TriFillSubsector32_" + std::to_string(i), TriDrawVariant::FillSubsector, (TriBlendMode)i, true);
CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, false); }
CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, TriBlendMode::Copy, false);
mProgram.CreateEE(); mProgram.CreateEE();
@ -262,16 +263,17 @@ LLVMDrawersImpl::LLVMDrawersImpl()
DrawSky4 = mProgram.GetProcAddress<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawSky4"); DrawSky4 = mProgram.GetProcAddress<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawSky4");
DrawDoubleSky1 = mProgram.GetProcAddress<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawDoubleSky1"); DrawDoubleSky1 = mProgram.GetProcAddress<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawDoubleSky1");
DrawDoubleSky4 = mProgram.GetProcAddress<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawDoubleSky4"); DrawDoubleSky4 = mProgram.GetProcAddress<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawDoubleSky4");
TriDraw8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw8"); for (int i = 0; i < NumTriBlendModes(); i++)
TriDraw32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw32"); {
TriDrawSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector8"); TriDrawNormal8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw8_" + std::to_string(i)));
TriDrawSubsector32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector32"); TriDrawNormal32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw32_" + std::to_string(i)));
TriDrawShadedSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawShadedSubsector8"); TriFillNormal8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill8_" + std::to_string(i)));
TriDrawShadedSubsector32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawShadedSubsector32"); TriFillNormal32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill32_" + std::to_string(i)));
TriFillSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector8"); TriDrawSubsector8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector8_" + std::to_string(i)));
TriFillSubsector32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector32"); TriDrawSubsector32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector32_" + std::to_string(i)));
TriFill8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill8"); TriFillSubsector8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector8_" + std::to_string(i)));
TriFill32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill32"); TriFillSubsector32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector32_" + std::to_string(i)));
}
TriStencil = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriStencil"); TriStencil = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriStencil");
#if 0 #if 0
@ -383,7 +385,7 @@ void LLVMDrawersImpl::CodegenDrawSky(const char *name, DrawSkyVariant variant, i
I_FatalError("verifyFunction failed for CodegenDrawSky()"); I_FatalError("verifyFunction failed for CodegenDrawSky()");
} }
void LLVMDrawersImpl::CodegenDrawTriangle(const char *name, TriDrawVariant variant, bool truecolor) void LLVMDrawersImpl::CodegenDrawTriangle(const std::string &name, TriDrawVariant variant, TriBlendMode blendmode, bool truecolor)
{ {
llvm::IRBuilder<> builder(mProgram.context()); llvm::IRBuilder<> builder(mProgram.context());
SSAScope ssa_scope(&mProgram.context(), mProgram.module(), &builder); SSAScope ssa_scope(&mProgram.context(), mProgram.module(), &builder);
@ -394,12 +396,12 @@ void LLVMDrawersImpl::CodegenDrawTriangle(const char *name, TriDrawVariant varia
function.create_public(); function.create_public();
DrawTriangleCodegen codegen; DrawTriangleCodegen codegen;
codegen.Generate(variant, truecolor, function.parameter(0), function.parameter(1)); codegen.Generate(variant, blendmode, truecolor, function.parameter(0), function.parameter(1));
builder.CreateRetVoid(); builder.CreateRetVoid();
if (llvm::verifyFunction(*function.func)) if (llvm::verifyFunction(*function.func))
I_FatalError("verifyFunction failed for CodegenDrawTriangle()"); I_FatalError("verifyFunction failed for CodegenDrawTriangle(%d, %d, %d)", (int)variant, (int)blendmode, (int)truecolor);
} }
llvm::Type *LLVMDrawersImpl::GetDrawColumnArgsStruct(llvm::LLVMContext &context) llvm::Type *LLVMDrawersImpl::GetDrawColumnArgsStruct(llvm::LLVMContext &context)
@ -529,6 +531,9 @@ llvm::Type *LLVMDrawersImpl::GetTriUniformsStruct(llvm::LLVMContext &context)
std::vector<llvm::Type *> elements; std::vector<llvm::Type *> elements;
elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t light; elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t light;
elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t subsectorDepth; elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t subsectorDepth;
elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t color;
elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t srcalpha;
elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t destalpha;
elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_alpha; elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_alpha;
elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_red; elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_red;
elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_green; elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_green;
@ -558,7 +563,7 @@ llvm::Type *LLVMDrawersImpl::GetTriDrawTriangleArgs(llvm::LLVMContext &context)
elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *texturePixels; elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *texturePixels;
elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t textureWidth; elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t textureWidth;
elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t textureHeight; elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t textureHeight;
elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t solidcolor; elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *translation;
elements.push_back(GetTriUniformsStruct(context)); // const TriUniforms *uniforms; elements.push_back(GetTriUniformsStruct(context)); // const TriUniforms *uniforms;
elements.push_back(llvm::Type::getInt8PtrTy(context)); // uint8_t *stencilValues; elements.push_back(llvm::Type::getInt8PtrTy(context)); // uint8_t *stencilValues;
elements.push_back(llvm::Type::getInt32PtrTy(context)); // uint32_t *stencilMasks; elements.push_back(llvm::Type::getInt32PtrTy(context)); // uint32_t *stencilMasks;

View file

@ -215,7 +215,9 @@ struct TriUniforms
{ {
uint32_t light; uint32_t light;
uint32_t subsectorDepth; uint32_t subsectorDepth;
uint32_t color;
uint32_t srcalpha;
uint32_t destalpha;
uint16_t light_alpha; uint16_t light_alpha;
uint16_t light_red; uint16_t light_red;
uint16_t light_green; uint16_t light_green;
@ -250,7 +252,7 @@ struct TriDrawTriangleArgs
const uint8_t *texturePixels; const uint8_t *texturePixels;
uint32_t textureWidth; uint32_t textureWidth;
uint32_t textureHeight; uint32_t textureHeight;
uint32_t solidcolor; const uint8_t *translation;
const TriUniforms *uniforms; const TriUniforms *uniforms;
uint8_t *stencilValues; uint8_t *stencilValues;
uint32_t *stencilMasks; uint32_t *stencilMasks;
@ -262,15 +264,31 @@ struct TriDrawTriangleArgs
enum class TriDrawVariant enum class TriDrawVariant
{ {
Draw, DrawNormal,
DrawMasked, FillNormal,
Fill,
DrawSubsector, DrawSubsector,
DrawShadedSubsector,
FillSubsector, FillSubsector,
Stencil, FuzzSubsector,
Stencil
}; };
enum class TriBlendMode
{
Copy, // blend_copy(shade(fg))
AlphaBlend, // blend_alpha_blend(shade(fg), bg)
AddSolid, // blend_add(shade(fg), bg, srcalpha, destalpha)
Add, // blend_add(shade(fg), bg, srcalpha, calc_blend_bgalpha(fg, destalpha))
Sub, // blend_sub(shade(fg), bg, srcalpha, calc_blend_bgalpha(fg, destalpha))
RevSub, // blend_revsub(shade(fg), bg, srcalpha, calc_blend_bgalpha(fg, destalpha))
Shaded, // blend_add(color, bg, fg.a, 1 - fg.a)
TranslateCopy, // blend_copy(shade(translate(fg)))
TranslateAdd, // blend_add(shade(translate(fg)), bg, srcalpha, calc_blend_bgalpha(fg, destalpha))
TranslateSub, // blend_sub(shade(translate(fg)), bg, srcalpha, calc_blend_bgalpha(fg, destalpha))
TranslateRevSub // blend_revsub(shade(translate(fg)), bg, srcalpha, calc_blend_bgalpha(fg, destalpha))
};
inline int NumTriBlendModes() { return (int)TriBlendMode::TranslateRevSub + 1; }
class LLVMDrawers class LLVMDrawers
{ {
public: public:
@ -346,16 +364,14 @@ public:
void(*DrawDoubleSky1)(const DrawSkyArgs *, const WorkerThreadData *) = nullptr; void(*DrawDoubleSky1)(const DrawSkyArgs *, const WorkerThreadData *) = nullptr;
void(*DrawDoubleSky4)(const DrawSkyArgs *, const WorkerThreadData *) = nullptr; void(*DrawDoubleSky4)(const DrawSkyArgs *, const WorkerThreadData *) = nullptr;
void(*TriDraw8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDrawNormal8;
void(*TriDraw32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDrawNormal32;
void(*TriDrawSubsector8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillNormal8;
void(*TriDrawSubsector32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillNormal32;
void(*TriDrawShadedSubsector8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDrawSubsector8;
void(*TriDrawShadedSubsector32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDrawSubsector32;
void(*TriFillSubsector8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillSubsector8;
void(*TriFillSubsector32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillSubsector32;
void(*TriFill8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
void(*TriFill32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
void(*TriStencil)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; void(*TriStencil)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
private: private:

View file

@ -141,6 +141,7 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, DBaseDecal *decal, co
uniforms.flags = 0; uniforms.flags = 0;
} }
uniforms.subsectorDepth = subsectorDepth; uniforms.subsectorDepth = subsectorDepth;
uniforms.color = decal->AlphaColor;
PolyDrawArgs args; PolyDrawArgs args;
args.uniforms = uniforms; args.uniforms = uniforms;
@ -151,7 +152,6 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, DBaseDecal *decal, co
args.stenciltestvalue = 0; args.stenciltestvalue = 0;
args.stencilwritevalue = 1; args.stencilwritevalue = 1;
args.SetTexture(tex); args.SetTexture(tex);
args.solidcolor = decal->AlphaColor;
//mode = R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor); //mode = R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor);
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawShadedSubsector); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Shaded);
} }

View file

@ -83,8 +83,8 @@ 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; uint32_t alpha = particle->trans;
uniforms.color = (alpha << 24) | (particle->color & 0xffffff);
PolyDrawArgs args; PolyDrawArgs args;
args.uniforms = uniforms; args.uniforms = uniforms;
@ -94,6 +94,5 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, particle_t *partic
args.ccw = true; args.ccw = true;
args.stenciltestvalue = 0; args.stenciltestvalue = 0;
args.stencilwritevalue = 1; args.stencilwritevalue = 1;
args.solidcolor = (alpha << 24) | (particle->color & 0xffffff); PolyTriangleDrawer::draw(args, TriDrawVariant::FillSubsector, TriBlendMode::AlphaBlend);
PolyTriangleDrawer::draw(args, TriDrawVariant::FillSubsector);
} }

View file

@ -140,8 +140,8 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, subsector_t *s
args.stenciltestvalue = 0; args.stenciltestvalue = 0;
args.stencilwritevalue = 1; args.stencilwritevalue = 1;
args.SetTexture(tex); args.SetTexture(tex);
PolyTriangleDrawer::draw(args, TriDrawVariant::Draw); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawNormal, TriBlendMode::Copy);
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil); PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
} }
void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, bool ceiling, double skyHeight) void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, bool ceiling, double skyHeight)
@ -235,13 +235,13 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
if (!isSky) if (!isSky)
{ {
args.SetTexture(tex); args.SetTexture(tex);
PolyTriangleDrawer::draw(args, TriDrawVariant::Draw); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawNormal, TriBlendMode::Copy);
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil); PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
} }
else else
{ {
args.stencilwritevalue = 255; args.stencilwritevalue = 255;
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil); PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
for (uint32_t i = 0; i < sub->numlines; i++) for (uint32_t i = 0; i < sub->numlines; i++)
{ {
@ -309,7 +309,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
args.vinput = wallvert; args.vinput = wallvert;
args.vcount = 4; args.vcount = 4;
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil); PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
} }
} }
} }

View file

@ -79,7 +79,7 @@ void PolySkyDome::RenderRow(PolyDrawArgs &args, int row)
args.vcount = mPrimStart[row + 1] - mPrimStart[row]; args.vcount = mPrimStart[row + 1] - mPrimStart[row];
args.mode = TriangleDrawMode::Strip; args.mode = TriangleDrawMode::Strip;
args.ccw = false; args.ccw = false;
PolyTriangleDrawer::draw(args, TriDrawVariant::Draw); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawNormal, TriBlendMode::Copy);
} }
void PolySkyDome::RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap) void PolySkyDome::RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap)
@ -92,8 +92,8 @@ void PolySkyDome::RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int ro
args.vcount = mPrimStart[row + 1] - mPrimStart[row]; args.vcount = mPrimStart[row + 1] - mPrimStart[row];
args.mode = TriangleDrawMode::Fan; args.mode = TriangleDrawMode::Fan;
args.ccw = bottomCap; args.ccw = bottomCap;
args.solidcolor = solid; args.uniforms.color = solid;
PolyTriangleDrawer::draw(args, TriDrawVariant::Fill); PolyTriangleDrawer::draw(args, TriDrawVariant::FillNormal, TriBlendMode::Copy);
} }
void PolySkyDome::CreateDome() void PolySkyDome::CreateDome()

View file

@ -136,7 +136,7 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, AActor *thing, subse
args.stenciltestvalue = 0; args.stenciltestvalue = 0;
args.stencilwritevalue = 1; args.stencilwritevalue = 1;
args.SetTexture(tex); args.SetTexture(tex);
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::AlphaBlend);
} }
bool RenderPolySprite::IsThingCulled(AActor *thing) bool RenderPolySprite::IsThingCulled(AActor *thing)

View file

@ -72,44 +72,32 @@ void PolyTriangleDrawer::set_viewport(int x, int y, int width, int height, DCanv
dest_height = clamp(viewport_y + viewport_height, 0, dest_height - offsety); dest_height = clamp(viewport_y + viewport_height, 0, dest_height - offsety);
} }
void PolyTriangleDrawer::draw(const PolyDrawArgs &args, TriDrawVariant variant) void PolyTriangleDrawer::draw(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode)
{ {
if (dest_bgra) if (dest_bgra)
DrawerCommandQueue::QueueCommand<DrawPolyTrianglesCommand>(args, variant); DrawerCommandQueue::QueueCommand<DrawPolyTrianglesCommand>(args, variant, blendmode);
else else
draw_arrays(args, variant, nullptr); draw_arrays(args, variant, blendmode, nullptr);
} }
void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVariant variant, WorkerThreadData *thread) void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVariant variant, TriBlendMode blendmode, WorkerThreadData *thread)
{ {
if (drawargs.vcount < 3) if (drawargs.vcount < 3)
return; return;
auto llvm = LLVMDrawers::Instance(); auto llvm = LLVMDrawers::Instance();
void(*drawfunc)(const TriDrawTriangleArgs *, WorkerThreadData *); void(*drawfunc)(const TriDrawTriangleArgs *, WorkerThreadData *);
#if 1 int bmode = (int)blendmode;
switch (variant) switch (variant)
{ {
default: default:
case TriDrawVariant::Draw: drawfunc = dest_bgra ? llvm->TriDraw32: llvm->TriDraw8; break; case TriDrawVariant::DrawNormal: drawfunc = dest_bgra ? llvm->TriDrawNormal32[bmode] : llvm->TriDrawNormal8[bmode]; break;
case TriDrawVariant::Fill: drawfunc = dest_bgra ? llvm->TriFill32 : llvm->TriFill8; break; case TriDrawVariant::FillNormal: drawfunc = dest_bgra ? llvm->TriFillNormal32[bmode] : llvm->TriFillNormal8[bmode]; break;
case TriDrawVariant::DrawSubsector: drawfunc = dest_bgra ? llvm->TriDrawSubsector32 : llvm->TriDrawSubsector8; break; case TriDrawVariant::DrawSubsector: drawfunc = dest_bgra ? llvm->TriDrawSubsector32[bmode] : llvm->TriDrawSubsector8[bmode]; break;
case TriDrawVariant::DrawShadedSubsector: drawfunc = dest_bgra ? llvm->TriDrawShadedSubsector32 : llvm->TriDrawShadedSubsector8; break; case TriDrawVariant::FuzzSubsector:
case TriDrawVariant::FillSubsector: drawfunc = dest_bgra ? llvm->TriFillSubsector32 : llvm->TriFillSubsector8; break; case TriDrawVariant::FillSubsector: drawfunc = dest_bgra ? llvm->TriFillSubsector32[bmode] : llvm->TriFillSubsector8[bmode]; break;
case TriDrawVariant::Stencil: drawfunc = llvm->TriStencil; break; case TriDrawVariant::Stencil: drawfunc = llvm->TriStencil; break;
} }
#else
switch (variant)
{
default:
case TriDrawVariant::Draw: drawfunc = dest_bgra ? ScreenPolyTriangleDrawer::draw32 : ScreenPolyTriangleDrawer::draw; break;
case TriDrawVariant::FillSubsector:
case TriDrawVariant::Fill: drawfunc = dest_bgra ? ScreenPolyTriangleDrawer::fill32 : ScreenPolyTriangleDrawer::fill; break;
case TriDrawVariant::DrawShadedSubsector:
case TriDrawVariant::DrawSubsector: drawfunc = dest_bgra ? ScreenPolyTriangleDrawer::drawsubsector32 : llvm->TriDrawSubsector8; break;
case TriDrawVariant::Stencil: drawfunc = ScreenPolyTriangleDrawer::stencil; break;
}
#endif
TriDrawTriangleArgs args; TriDrawTriangleArgs args;
args.dest = dest; args.dest = dest;
@ -121,7 +109,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian
args.texturePixels = drawargs.texturePixels; args.texturePixels = drawargs.texturePixels;
args.textureWidth = drawargs.textureWidth; args.textureWidth = drawargs.textureWidth;
args.textureHeight = drawargs.textureHeight; args.textureHeight = drawargs.textureHeight;
args.solidcolor = drawargs.solidcolor; args.translation = drawargs.translation;
args.uniforms = &drawargs.uniforms; args.uniforms = &drawargs.uniforms;
args.stencilTestValue = drawargs.stenciltestvalue; args.stencilTestValue = drawargs.stenciltestvalue;
args.stencilWriteValue = drawargs.stencilwritevalue; args.stencilWriteValue = drawargs.stencilwritevalue;
@ -336,6 +324,7 @@ void PolyTriangleDrawer::clipedge(const TriVertex *verts, TriVertex *clippedvert
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#if 0
void ScreenPolyTriangleDrawer::draw(const TriDrawTriangleArgs *args, WorkerThreadData *thread) void ScreenPolyTriangleDrawer::draw(const TriDrawTriangleArgs *args, WorkerThreadData *thread)
{ {
uint8_t *dest = args->dest; uint8_t *dest = args->dest;
@ -1641,11 +1630,12 @@ float ScreenPolyTriangleDrawer::grady(float x0, float y0, float x1, float y1, fl
float bottom = -((x1 - x2) * (y0 - y2) - (x0 - x2) * (y1 - y2)); float bottom = -((x1 - x2) * (y0 - y2) - (x0 - x2) * (y1 - y2));
return top / bottom; return top / bottom;
} }
#endif
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant) DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode)
: args(args), variant(variant) : args(args), variant(variant), blendmode(blendmode)
{ {
} }
@ -1658,7 +1648,7 @@ void DrawPolyTrianglesCommand::Execute(DrawerThread *thread)
thread_data.pass_end_y = thread->pass_end_y; thread_data.pass_end_y = thread->pass_end_y;
thread_data.temp = thread->dc_temp_rgba; thread_data.temp = thread->dc_temp_rgba;
PolyTriangleDrawer::draw_arrays(args, variant, &thread_data); PolyTriangleDrawer::draw_arrays(args, variant, blendmode, &thread_data);
} }
FString DrawPolyTrianglesCommand::DebugInfo() FString DrawPolyTrianglesCommand::DebugInfo()

View file

@ -39,7 +39,7 @@ public:
const uint8_t *texturePixels = nullptr; const uint8_t *texturePixels = nullptr;
int textureWidth = 0; int textureWidth = 0;
int textureHeight = 0; int textureHeight = 0;
uint32_t solidcolor = 0; const uint8_t *translation = nullptr;
uint8_t stenciltestvalue = 0; uint8_t stenciltestvalue = 0;
uint8_t stencilwritevalue = 0; uint8_t stencilwritevalue = 0;
@ -58,11 +58,11 @@ class PolyTriangleDrawer
{ {
public: public:
static void set_viewport(int x, int y, int width, int height, DCanvas *canvas); static void set_viewport(int x, int y, int width, int height, DCanvas *canvas);
static void draw(const PolyDrawArgs &args, TriDrawVariant variant); static void draw(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode);
private: private:
static TriVertex shade_vertex(const TriUniforms &uniforms, TriVertex v); static TriVertex shade_vertex(const TriUniforms &uniforms, TriVertex v);
static void draw_arrays(const PolyDrawArgs &args, TriDrawVariant variant, WorkerThreadData *thread); static void draw_arrays(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode, WorkerThreadData *thread);
static void draw_shaded_triangle(const TriVertex *vertices, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread, void(*drawfunc)(const TriDrawTriangleArgs *, WorkerThreadData *)); static void draw_shaded_triangle(const TriVertex *vertices, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread, void(*drawfunc)(const TriDrawTriangleArgs *, WorkerThreadData *));
static bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2); static bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2);
static void clipedge(const TriVertex *verts, TriVertex *clippedvert, int &numclipvert); static void clipedge(const TriVertex *verts, TriVertex *clippedvert, int &numclipvert);
@ -188,6 +188,7 @@ private:
std::vector<uint32_t> masks; std::vector<uint32_t> masks;
}; };
#if 0
class ScreenPolyTriangleDrawer class ScreenPolyTriangleDrawer
{ {
public: public:
@ -204,11 +205,12 @@ private:
static float gradx(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2); static float gradx(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2);
static float grady(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2); static float grady(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2);
}; };
#endif
class DrawPolyTrianglesCommand : public DrawerCommand class DrawPolyTrianglesCommand : public DrawerCommand
{ {
public: public:
DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant); DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode);
void Execute(DrawerThread *thread) override; void Execute(DrawerThread *thread) override;
FString DebugInfo() override; FString DebugInfo() override;
@ -216,6 +218,7 @@ public:
private: private:
PolyDrawArgs args; PolyDrawArgs args;
TriDrawVariant variant; TriDrawVariant variant;
TriBlendMode blendmode;
}; };
#endif #endif

View file

@ -193,12 +193,12 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip)
if (!Masked) if (!Masked)
{ {
PolyTriangleDrawer::draw(args, TriDrawVariant::Draw); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawNormal, TriBlendMode::Copy);
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil); PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
} }
else else
{ {
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::AlphaBlend);
} }
RenderPolyDecal::RenderWallDecals(worldToClip, Line, SubsectorDepth); RenderPolyDecal::RenderWallDecals(worldToClip, Line, SubsectorDepth);

View file

@ -121,5 +121,5 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, AActor *thing, s
args.stenciltestvalue = 0; args.stenciltestvalue = 0;
args.stencilwritevalue = 1; args.stencilwritevalue = 1;
args.SetTexture(tex); args.SetTexture(tex);
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::AlphaBlend);
} }