mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-30 07:31:12 +00:00
Added blending modes to triangle codegen
This commit is contained in:
parent
5d6ceb868e
commit
272fe7f754
13 changed files with 242 additions and 205 deletions
|
@ -32,11 +32,14 @@
|
|||
#include "r_compiler/ssa/ssa_struct_type.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);
|
||||
Setup(variant, truecolor);
|
||||
LoopBlockY(variant, truecolor);
|
||||
this->variant = variant;
|
||||
this->blendmode = blendmode;
|
||||
this->truecolor = truecolor;
|
||||
LoadArgs(args, thread_data);
|
||||
Setup();
|
||||
LoopBlockY();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void DrawTriangleCodegen::Setup(TriDrawVariant variant, bool truecolor)
|
||||
void DrawTriangleCodegen::Setup()
|
||||
{
|
||||
int pixelsize = truecolor ? 4 : 1;
|
||||
|
||||
|
@ -154,7 +157,7 @@ SSAFloat DrawTriangleCodegen::grady(SSAFloat x0, SSAFloat y0, SSAFloat x1, SSAFl
|
|||
return top / bottom;
|
||||
}
|
||||
|
||||
void DrawTriangleCodegen::LoopBlockY(TriDrawVariant variant, bool truecolor)
|
||||
void DrawTriangleCodegen::LoopBlockY()
|
||||
{
|
||||
int pixelsize = truecolor ? 4 : 1;
|
||||
|
||||
|
@ -171,7 +174,7 @@ void DrawTriangleCodegen::LoopBlockY(TriDrawVariant variant, bool truecolor)
|
|||
SSAIfBlock branch;
|
||||
branch.if_block((y / q) % thread.num_cores == thread.core);
|
||||
{
|
||||
LoopBlockX(variant, truecolor);
|
||||
LoopBlockX();
|
||||
}
|
||||
branch.end_block();
|
||||
|
||||
|
@ -182,7 +185,7 @@ void DrawTriangleCodegen::LoopBlockY(TriDrawVariant variant, bool truecolor)
|
|||
loop.end_block();
|
||||
}
|
||||
|
||||
void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor)
|
||||
void DrawTriangleCodegen::LoopBlockX()
|
||||
{
|
||||
stack_x.store(minx);
|
||||
|
||||
|
@ -260,7 +263,7 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor)
|
|||
SetStencilBlock(x / 8 + y / 8 * stencilPitch);
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -269,11 +272,11 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor)
|
|||
SSAIfBlock branch_covered;
|
||||
branch_covered.if_block(covered);
|
||||
{
|
||||
LoopFullBlock(variant, truecolor);
|
||||
LoopFullBlock();
|
||||
}
|
||||
branch_covered.else_block();
|
||||
{
|
||||
LoopPartialBlock(variant, truecolor);
|
||||
LoopPartialBlock();
|
||||
}
|
||||
branch_covered.end_block();
|
||||
|
||||
|
@ -284,10 +287,10 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor)
|
|||
loop.end_block();
|
||||
}
|
||||
|
||||
void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor)
|
||||
void DrawTriangleCodegen::LoopFullBlock()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -325,18 +328,18 @@ void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor)
|
|||
varying[i] = stack_varying[i].load();
|
||||
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;
|
||||
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();
|
||||
}
|
||||
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++)
|
||||
|
@ -353,13 +356,13 @@ void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor)
|
|||
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();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolor)
|
||||
void DrawTriangleCodegen::LoopPartialBlock()
|
||||
{
|
||||
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 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;
|
||||
}
|
||||
|
@ -422,7 +425,7 @@ void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolo
|
|||
}
|
||||
else
|
||||
{
|
||||
ProcessPixel(buffer[ix * pixelsize], subsectorbuffer[ix], varying, variant, truecolor);
|
||||
ProcessPixel(buffer[ix * pixelsize], subsectorbuffer[ix], varying);
|
||||
}
|
||||
}
|
||||
branch.end_block();
|
||||
|
@ -447,91 +450,101 @@ void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolo
|
|||
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);
|
||||
else
|
||||
return translation[texturePixels[uvoffset].load(true).zext_int() * 4].load_vec4ub(true);
|
||||
}
|
||||
|
||||
SSAVec4i DrawTriangleCodegen::Sample(SSAInt uvoffset)
|
||||
{
|
||||
if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector)
|
||||
return SSAVec4i::unpack(color);
|
||||
else
|
||||
return texturePixels[uvoffset * 4].load_vec4ub(true);
|
||||
}
|
||||
|
||||
void DrawTriangleCodegen::ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbuffer, SSAInt *varying)
|
||||
{
|
||||
SSAInt ufrac = varying[0];
|
||||
SSAInt vfrac = varying[1];
|
||||
|
||||
SSAInt upos = ((ufrac >> 16) * textureWidth) >> 16;
|
||||
SSAInt vpos = ((vfrac >> 16) * textureHeight) >> 16;
|
||||
SSAInt uvoffset = upos * textureHeight + vpos;
|
||||
|
||||
if (truecolor)
|
||||
{
|
||||
if (truecolor)
|
||||
SSAVec4i fg;
|
||||
SSAVec4i bg = buffer.load_vec4ub(false);
|
||||
SSAInt alpha, inv_alpha;
|
||||
SSAVec4i output;
|
||||
|
||||
switch (blendmode)
|
||||
{
|
||||
buffer.store_vec4ub(SSAVec4i::unpack(solidcolor));
|
||||
}
|
||||
else
|
||||
{
|
||||
//buffer.store(solidcolor);
|
||||
default:
|
||||
case TriBlendMode::Copy:
|
||||
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;
|
||||
}
|
||||
|
||||
if (variant != TriDrawVariant::FillSubsector)
|
||||
subsectorbuffer.store(subsectorDepth);
|
||||
buffer.store_vec4ub(output);
|
||||
}
|
||||
else
|
||||
{
|
||||
SSAInt ufrac = varying[0];
|
||||
SSAInt vfrac = varying[1];
|
||||
|
||||
SSAInt upos = ((ufrac >> 16) * textureWidth) >> 16;
|
||||
SSAInt vpos = ((vfrac >> 16) * textureHeight) >> 16;
|
||||
SSAInt uvoffset = upos * textureHeight + vpos;
|
||||
|
||||
if (truecolor)
|
||||
if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector)
|
||||
{
|
||||
if (variant == TriDrawVariant::DrawMasked || variant == TriDrawVariant::DrawSubsector)
|
||||
{
|
||||
SSAVec4i fg = texturePixels[uvoffset * 4].load_vec4ub(true);
|
||||
SSAInt fg_alpha = fg[3];
|
||||
fg = (fg * currentlight) >> 8;
|
||||
fg.insert(3, fg_alpha);
|
||||
|
||||
SSAIfBlock branch_transparency;
|
||||
branch_transparency.if_block(fg_alpha > SSAInt(127));
|
||||
{
|
||||
buffer.store_vec4ub(fg);
|
||||
if (variant != TriDrawVariant::DrawSubsector)
|
||||
subsectorbuffer.store(subsectorDepth);
|
||||
}
|
||||
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(blend_add(shade_bgra_simple(SSAVec4i::unpack(solidcolor), currentlight), bgcolor, alpha, inv_alpha));
|
||||
}
|
||||
else
|
||||
{
|
||||
SSAVec4i fg = texturePixels[uvoffset * 4].load_vec4ub(true);
|
||||
SSAInt fg_alpha = fg[3];
|
||||
fg = (fg * currentlight) >> 8;
|
||||
fg.insert(3, fg_alpha);
|
||||
|
||||
buffer.store_vec4ub(fg);
|
||||
subsectorbuffer.store(subsectorDepth);
|
||||
}
|
||||
buffer.store(color.trunc_ubyte());
|
||||
}
|
||||
else
|
||||
{
|
||||
SSAUByte palindex = texturePixels[uvoffset].load(true);
|
||||
|
||||
if (variant == TriDrawVariant::DrawMasked || variant == TriDrawVariant::DrawSubsector)
|
||||
{
|
||||
SSAIfBlock branch_transparency;
|
||||
branch_transparency.if_block(!(palindex.zext_int() == SSAInt(0)));
|
||||
{
|
||||
buffer.store(palindex);
|
||||
if (variant != TriDrawVariant::DrawSubsector)
|
||||
subsectorbuffer.store(subsectorDepth);
|
||||
}
|
||||
branch_transparency.end_block();
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.store(palindex);
|
||||
subsectorbuffer.store(subsectorDepth);
|
||||
}
|
||||
SSAUByte fg = texturePixels[uvoffset].load(true);
|
||||
buffer.store(fg);
|
||||
}
|
||||
}
|
||||
|
||||
if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector && variant != TriDrawVariant::FuzzSubsector)
|
||||
subsectorbuffer.store(subsectorDepth);
|
||||
}
|
||||
|
||||
void DrawTriangleCodegen::SetStencilBlock(SSAInt block)
|
||||
|
@ -582,7 +595,7 @@ SSABool DrawTriangleCodegen::StencilIsSingleValue()
|
|||
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);
|
||||
pitch = args[0][1].load(true);
|
||||
|
@ -596,7 +609,7 @@ void DrawTriangleCodegen::LoadArgs(TriDrawVariant variant, bool truecolor, SSAVa
|
|||
texturePixels = args[0][9].load(true);
|
||||
textureWidth = args[0][10].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));
|
||||
stencilValues = args[0][14].load(true);
|
||||
stencilMasks = args[0][15].load(true);
|
||||
|
@ -625,17 +638,20 @@ void DrawTriangleCodegen::LoadUniforms(SSAValue uniforms)
|
|||
{
|
||||
light = uniforms[0][0].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_red = uniforms[0][3].load(true);
|
||||
SSAShort light_green = uniforms[0][4].load(true);
|
||||
SSAShort light_blue = uniforms[0][5].load(true);
|
||||
SSAShort fade_alpha = uniforms[0][6].load(true);
|
||||
SSAShort fade_red = uniforms[0][7].load(true);
|
||||
SSAShort fade_green = uniforms[0][8].load(true);
|
||||
SSAShort fade_blue = uniforms[0][9].load(true);
|
||||
SSAShort desaturate = uniforms[0][10].load(true);
|
||||
SSAInt flags = uniforms[0][11].load(true);
|
||||
SSAShort light_alpha = uniforms[0][5].load(true);
|
||||
SSAShort light_red = uniforms[0][6].load(true);
|
||||
SSAShort light_green = uniforms[0][7].load(true);
|
||||
SSAShort light_blue = uniforms[0][8].load(true);
|
||||
SSAShort fade_alpha = uniforms[0][9].load(true);
|
||||
SSAShort fade_red = uniforms[0][10].load(true);
|
||||
SSAShort fade_green = uniforms[0][11].load(true);
|
||||
SSAShort fade_blue = uniforms[0][12].load(true);
|
||||
SSAShort desaturate = uniforms[0][13].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.fade = SSAVec4i(fade_blue.zext_int(), fade_green.zext_int(), fade_red.zext_int(), fade_alpha.zext_int());
|
||||
shade_constants.desaturate = desaturate.zext_int();
|
||||
|
|
|
@ -33,20 +33,23 @@ struct SSATriVertex
|
|||
class DrawTriangleCodegen : public DrawerCodegen
|
||||
{
|
||||
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:
|
||||
void LoadArgs(TriDrawVariant variant, bool truecolor, SSAValue args, SSAValue thread_data);
|
||||
void LoadArgs(SSAValue args, SSAValue thread_data);
|
||||
SSATriVertex LoadTriVertex(SSAValue v);
|
||||
void LoadUniforms(SSAValue uniforms);
|
||||
void Setup(TriDrawVariant variant, bool truecolor);
|
||||
void Setup();
|
||||
SSAInt FloatTo28_4(SSAFloat v);
|
||||
void LoopBlockY(TriDrawVariant variant, bool truecolor);
|
||||
void LoopBlockX(TriDrawVariant variant, bool truecolor);
|
||||
void LoopFullBlock(TriDrawVariant variant, bool truecolor);
|
||||
void LoopPartialBlock(TriDrawVariant variant, bool truecolor);
|
||||
void LoopBlockY();
|
||||
void LoopBlockX();
|
||||
void LoopFullBlock();
|
||||
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 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 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_y;
|
||||
SSAStack<SSAUBytePtr> stack_dest;
|
||||
|
@ -82,7 +89,8 @@ private:
|
|||
SSAUBytePtr texturePixels;
|
||||
SSAInt textureWidth;
|
||||
SSAInt textureHeight;
|
||||
SSAInt solidcolor;
|
||||
SSAUBytePtr translation;
|
||||
SSAInt color, srcalpha, destalpha;
|
||||
|
||||
SSAInt light;
|
||||
SSAInt subsectorDepth;
|
||||
|
|
|
@ -57,7 +57,7 @@ public:
|
|||
void StopLogFatalErrors();
|
||||
|
||||
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::Module *module() { return mModule.get(); }
|
||||
|
@ -82,7 +82,7 @@ private:
|
|||
void CodegenDrawSpan(const char *name, DrawSpanVariant variant);
|
||||
void CodegenDrawWall(const char *name, DrawWallVariant 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 *GetDrawSpanArgsStruct(llvm::LLVMContext &context);
|
||||
|
@ -186,17 +186,18 @@ LLVMDrawersImpl::LLVMDrawersImpl()
|
|||
CodegenDrawSky("DrawSky4", DrawSkyVariant::Single, 4);
|
||||
CodegenDrawSky("DrawDoubleSky1", DrawSkyVariant::Double, 1);
|
||||
CodegenDrawSky("DrawDoubleSky4", DrawSkyVariant::Double, 4);
|
||||
CodegenDrawTriangle("TriDraw8", TriDrawVariant::Draw, false);
|
||||
CodegenDrawTriangle("TriDraw32", TriDrawVariant::Draw, true);
|
||||
CodegenDrawTriangle("TriDrawSubsector8", TriDrawVariant::DrawSubsector, false);
|
||||
CodegenDrawTriangle("TriDrawSubsector32", TriDrawVariant::DrawSubsector, true);
|
||||
CodegenDrawTriangle("TriDrawShadedSubsector8", TriDrawVariant::DrawShadedSubsector, false);
|
||||
CodegenDrawTriangle("TriDrawShadedSubsector32", TriDrawVariant::DrawShadedSubsector, true);
|
||||
CodegenDrawTriangle("TriFillSubsector8", TriDrawVariant::FillSubsector, false);
|
||||
CodegenDrawTriangle("TriFillSubsector32", TriDrawVariant::FillSubsector, true);
|
||||
CodegenDrawTriangle("TriFill8", TriDrawVariant::Fill, false);
|
||||
CodegenDrawTriangle("TriFill32", TriDrawVariant::Fill, true);
|
||||
CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, false);
|
||||
for (int i = 0; i < NumTriBlendModes(); i++)
|
||||
{
|
||||
CodegenDrawTriangle("TriDraw8_" + std::to_string(i), TriDrawVariant::DrawNormal, (TriBlendMode)i, false);
|
||||
CodegenDrawTriangle("TriDraw32_" + std::to_string(i), TriDrawVariant::DrawNormal, (TriBlendMode)i, true);
|
||||
CodegenDrawTriangle("TriFill8_" + std::to_string(i), TriDrawVariant::FillNormal, (TriBlendMode)i, false);
|
||||
CodegenDrawTriangle("TriFill32_" + std::to_string(i), TriDrawVariant::FillNormal, (TriBlendMode)i, true);
|
||||
CodegenDrawTriangle("TriDrawSubsector8_" + std::to_string(i), TriDrawVariant::DrawSubsector, (TriBlendMode)i, false);
|
||||
CodegenDrawTriangle("TriDrawSubsector32_" + std::to_string(i), TriDrawVariant::DrawSubsector, (TriBlendMode)i, true);
|
||||
CodegenDrawTriangle("TriFillSubsector8_" + std::to_string(i), TriDrawVariant::FillSubsector, (TriBlendMode)i, false);
|
||||
CodegenDrawTriangle("TriFillSubsector32_" + std::to_string(i), TriDrawVariant::FillSubsector, (TriBlendMode)i, true);
|
||||
}
|
||||
CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, TriBlendMode::Copy, false);
|
||||
|
||||
mProgram.CreateEE();
|
||||
|
||||
|
@ -262,16 +263,17 @@ LLVMDrawersImpl::LLVMDrawersImpl()
|
|||
DrawSky4 = mProgram.GetProcAddress<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawSky4");
|
||||
DrawDoubleSky1 = mProgram.GetProcAddress<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawDoubleSky1");
|
||||
DrawDoubleSky4 = mProgram.GetProcAddress<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawDoubleSky4");
|
||||
TriDraw8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw8");
|
||||
TriDraw32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw32");
|
||||
TriDrawSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector8");
|
||||
TriDrawSubsector32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector32");
|
||||
TriDrawShadedSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawShadedSubsector8");
|
||||
TriDrawShadedSubsector32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawShadedSubsector32");
|
||||
TriFillSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector8");
|
||||
TriFillSubsector32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector32");
|
||||
TriFill8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill8");
|
||||
TriFill32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill32");
|
||||
for (int i = 0; i < NumTriBlendModes(); i++)
|
||||
{
|
||||
TriDrawNormal8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw8_" + std::to_string(i)));
|
||||
TriDrawNormal32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw32_" + std::to_string(i)));
|
||||
TriFillNormal8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill8_" + std::to_string(i)));
|
||||
TriFillNormal32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill32_" + std::to_string(i)));
|
||||
TriDrawSubsector8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector8_" + std::to_string(i)));
|
||||
TriDrawSubsector32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector32_" + std::to_string(i)));
|
||||
TriFillSubsector8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector8_" + std::to_string(i)));
|
||||
TriFillSubsector32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector32_" + std::to_string(i)));
|
||||
}
|
||||
TriStencil = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriStencil");
|
||||
|
||||
#if 0
|
||||
|
@ -383,7 +385,7 @@ void LLVMDrawersImpl::CodegenDrawSky(const char *name, DrawSkyVariant variant, i
|
|||
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());
|
||||
SSAScope ssa_scope(&mProgram.context(), mProgram.module(), &builder);
|
||||
|
@ -394,12 +396,12 @@ void LLVMDrawersImpl::CodegenDrawTriangle(const char *name, TriDrawVariant varia
|
|||
function.create_public();
|
||||
|
||||
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();
|
||||
|
||||
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)
|
||||
|
@ -529,6 +531,9 @@ llvm::Type *LLVMDrawersImpl::GetTriUniformsStruct(llvm::LLVMContext &context)
|
|||
std::vector<llvm::Type *> elements;
|
||||
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 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_red;
|
||||
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::getInt32Ty(context)); // uint32_t textureWidth;
|
||||
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(llvm::Type::getInt8PtrTy(context)); // uint8_t *stencilValues;
|
||||
elements.push_back(llvm::Type::getInt32PtrTy(context)); // uint32_t *stencilMasks;
|
||||
|
|
|
@ -215,7 +215,9 @@ struct TriUniforms
|
|||
{
|
||||
uint32_t light;
|
||||
uint32_t subsectorDepth;
|
||||
|
||||
uint32_t color;
|
||||
uint32_t srcalpha;
|
||||
uint32_t destalpha;
|
||||
uint16_t light_alpha;
|
||||
uint16_t light_red;
|
||||
uint16_t light_green;
|
||||
|
@ -250,7 +252,7 @@ struct TriDrawTriangleArgs
|
|||
const uint8_t *texturePixels;
|
||||
uint32_t textureWidth;
|
||||
uint32_t textureHeight;
|
||||
uint32_t solidcolor;
|
||||
const uint8_t *translation;
|
||||
const TriUniforms *uniforms;
|
||||
uint8_t *stencilValues;
|
||||
uint32_t *stencilMasks;
|
||||
|
@ -262,15 +264,31 @@ struct TriDrawTriangleArgs
|
|||
|
||||
enum class TriDrawVariant
|
||||
{
|
||||
Draw,
|
||||
DrawMasked,
|
||||
Fill,
|
||||
DrawNormal,
|
||||
FillNormal,
|
||||
DrawSubsector,
|
||||
DrawShadedSubsector,
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
@ -346,16 +364,14 @@ public:
|
|||
void(*DrawDoubleSky1)(const DrawSkyArgs *, const WorkerThreadData *) = nullptr;
|
||||
void(*DrawDoubleSky4)(const DrawSkyArgs *, const WorkerThreadData *) = nullptr;
|
||||
|
||||
void(*TriDraw8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||
void(*TriDraw32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||
void(*TriDrawSubsector8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||
void(*TriDrawSubsector32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||
void(*TriDrawShadedSubsector8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||
void(*TriDrawShadedSubsector32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||
void(*TriFillSubsector8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||
void(*TriFillSubsector32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||
void(*TriFill8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||
void(*TriFill32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDrawNormal8;
|
||||
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDrawNormal32;
|
||||
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillNormal8;
|
||||
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillNormal32;
|
||||
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDrawSubsector8;
|
||||
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDrawSubsector32;
|
||||
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillSubsector8;
|
||||
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillSubsector32;
|
||||
void(*TriStencil)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||
|
||||
private:
|
||||
|
|
|
@ -141,6 +141,7 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, DBaseDecal *decal, co
|
|||
uniforms.flags = 0;
|
||||
}
|
||||
uniforms.subsectorDepth = subsectorDepth;
|
||||
uniforms.color = decal->AlphaColor;
|
||||
|
||||
PolyDrawArgs args;
|
||||
args.uniforms = uniforms;
|
||||
|
@ -151,7 +152,6 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, DBaseDecal *decal, co
|
|||
args.stenciltestvalue = 0;
|
||||
args.stencilwritevalue = 1;
|
||||
args.SetTexture(tex);
|
||||
args.solidcolor = 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);
|
||||
}
|
||||
|
|
|
@ -83,8 +83,8 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, particle_t *partic
|
|||
uniforms.flags = 0;
|
||||
}
|
||||
uniforms.subsectorDepth = subsectorDepth;
|
||||
|
||||
uint32_t alpha = particle->trans;
|
||||
uniforms.color = (alpha << 24) | (particle->color & 0xffffff);
|
||||
|
||||
PolyDrawArgs args;
|
||||
args.uniforms = uniforms;
|
||||
|
@ -94,6 +94,5 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, particle_t *partic
|
|||
args.ccw = true;
|
||||
args.stenciltestvalue = 0;
|
||||
args.stencilwritevalue = 1;
|
||||
args.solidcolor = (alpha << 24) | (particle->color & 0xffffff);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::FillSubsector);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::FillSubsector, TriBlendMode::AlphaBlend);
|
||||
}
|
||||
|
|
|
@ -140,8 +140,8 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, subsector_t *s
|
|||
args.stenciltestvalue = 0;
|
||||
args.stencilwritevalue = 1;
|
||||
args.SetTexture(tex);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Draw);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawNormal, TriBlendMode::Copy);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
args.SetTexture(tex);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Draw);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawNormal, TriBlendMode::Copy);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.stencilwritevalue = 255;
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
|
||||
|
||||
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.vcount = 4;
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ void PolySkyDome::RenderRow(PolyDrawArgs &args, int row)
|
|||
args.vcount = mPrimStart[row + 1] - mPrimStart[row];
|
||||
args.mode = TriangleDrawMode::Strip;
|
||||
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)
|
||||
|
@ -92,8 +92,8 @@ void PolySkyDome::RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int ro
|
|||
args.vcount = mPrimStart[row + 1] - mPrimStart[row];
|
||||
args.mode = TriangleDrawMode::Fan;
|
||||
args.ccw = bottomCap;
|
||||
args.solidcolor = solid;
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Fill);
|
||||
args.uniforms.color = solid;
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::FillNormal, TriBlendMode::Copy);
|
||||
}
|
||||
|
||||
void PolySkyDome::CreateDome()
|
||||
|
|
|
@ -136,7 +136,7 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, AActor *thing, subse
|
|||
args.stenciltestvalue = 0;
|
||||
args.stencilwritevalue = 1;
|
||||
args.SetTexture(tex);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::AlphaBlend);
|
||||
}
|
||||
|
||||
bool RenderPolySprite::IsThingCulled(AActor *thing)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
void PolyTriangleDrawer::draw(const PolyDrawArgs &args, TriDrawVariant variant)
|
||||
void PolyTriangleDrawer::draw(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode)
|
||||
{
|
||||
if (dest_bgra)
|
||||
DrawerCommandQueue::QueueCommand<DrawPolyTrianglesCommand>(args, variant);
|
||||
DrawerCommandQueue::QueueCommand<DrawPolyTrianglesCommand>(args, variant, blendmode);
|
||||
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)
|
||||
return;
|
||||
|
||||
auto llvm = LLVMDrawers::Instance();
|
||||
void(*drawfunc)(const TriDrawTriangleArgs *, WorkerThreadData *);
|
||||
#if 1
|
||||
int bmode = (int)blendmode;
|
||||
switch (variant)
|
||||
{
|
||||
default:
|
||||
case TriDrawVariant::Draw: drawfunc = dest_bgra ? llvm->TriDraw32: llvm->TriDraw8; break;
|
||||
case TriDrawVariant::Fill: drawfunc = dest_bgra ? llvm->TriFill32 : llvm->TriFill8; break;
|
||||
case TriDrawVariant::DrawSubsector: drawfunc = dest_bgra ? llvm->TriDrawSubsector32 : llvm->TriDrawSubsector8; break;
|
||||
case TriDrawVariant::DrawShadedSubsector: drawfunc = dest_bgra ? llvm->TriDrawShadedSubsector32 : llvm->TriDrawShadedSubsector8; break;
|
||||
case TriDrawVariant::FillSubsector: drawfunc = dest_bgra ? llvm->TriFillSubsector32 : llvm->TriFillSubsector8; break;
|
||||
case TriDrawVariant::DrawNormal: drawfunc = dest_bgra ? llvm->TriDrawNormal32[bmode] : llvm->TriDrawNormal8[bmode]; break;
|
||||
case TriDrawVariant::FillNormal: drawfunc = dest_bgra ? llvm->TriFillNormal32[bmode] : llvm->TriFillNormal8[bmode]; break;
|
||||
case TriDrawVariant::DrawSubsector: drawfunc = dest_bgra ? llvm->TriDrawSubsector32[bmode] : llvm->TriDrawSubsector8[bmode]; break;
|
||||
case TriDrawVariant::FuzzSubsector:
|
||||
case TriDrawVariant::FillSubsector: drawfunc = dest_bgra ? llvm->TriFillSubsector32[bmode] : llvm->TriFillSubsector8[bmode]; 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;
|
||||
args.dest = dest;
|
||||
|
@ -121,7 +109,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian
|
|||
args.texturePixels = drawargs.texturePixels;
|
||||
args.textureWidth = drawargs.textureWidth;
|
||||
args.textureHeight = drawargs.textureHeight;
|
||||
args.solidcolor = drawargs.solidcolor;
|
||||
args.translation = drawargs.translation;
|
||||
args.uniforms = &drawargs.uniforms;
|
||||
args.stencilTestValue = drawargs.stenciltestvalue;
|
||||
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)
|
||||
{
|
||||
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));
|
||||
return top / bottom;
|
||||
}
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant)
|
||||
: args(args), variant(variant)
|
||||
DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode)
|
||||
: 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.temp = thread->dc_temp_rgba;
|
||||
|
||||
PolyTriangleDrawer::draw_arrays(args, variant, &thread_data);
|
||||
PolyTriangleDrawer::draw_arrays(args, variant, blendmode, &thread_data);
|
||||
}
|
||||
|
||||
FString DrawPolyTrianglesCommand::DebugInfo()
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
const uint8_t *texturePixels = nullptr;
|
||||
int textureWidth = 0;
|
||||
int textureHeight = 0;
|
||||
uint32_t solidcolor = 0;
|
||||
const uint8_t *translation = nullptr;
|
||||
uint8_t stenciltestvalue = 0;
|
||||
uint8_t stencilwritevalue = 0;
|
||||
|
||||
|
@ -58,11 +58,11 @@ class PolyTriangleDrawer
|
|||
{
|
||||
public:
|
||||
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:
|
||||
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 bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2);
|
||||
static void clipedge(const TriVertex *verts, TriVertex *clippedvert, int &numclipvert);
|
||||
|
@ -188,6 +188,7 @@ private:
|
|||
std::vector<uint32_t> masks;
|
||||
};
|
||||
|
||||
#if 0
|
||||
class ScreenPolyTriangleDrawer
|
||||
{
|
||||
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 grady(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2);
|
||||
};
|
||||
#endif
|
||||
|
||||
class DrawPolyTrianglesCommand : public DrawerCommand
|
||||
{
|
||||
public:
|
||||
DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant);
|
||||
DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode);
|
||||
|
||||
void Execute(DrawerThread *thread) override;
|
||||
FString DebugInfo() override;
|
||||
|
@ -216,6 +218,7 @@ public:
|
|||
private:
|
||||
PolyDrawArgs args;
|
||||
TriDrawVariant variant;
|
||||
TriBlendMode blendmode;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -193,12 +193,12 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip)
|
|||
|
||||
if (!Masked)
|
||||
{
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Draw);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawNormal, TriBlendMode::Copy);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
|
||||
}
|
||||
else
|
||||
{
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::AlphaBlend);
|
||||
}
|
||||
|
||||
RenderPolyDecal::RenderWallDecals(worldToClip, Line, SubsectorDepth);
|
||||
|
|
|
@ -121,5 +121,5 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, AActor *thing, s
|
|||
args.stenciltestvalue = 0;
|
||||
args.stencilwritevalue = 1;
|
||||
args.SetTexture(tex);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector);
|
||||
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::AlphaBlend);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue