Sealing off portal entrances for the transparency pass

This commit is contained in:
Magnus Norddahl 2016-11-25 07:44:51 +01:00
parent e642ed099a
commit b2ad26d2d5
9 changed files with 61 additions and 26 deletions

View file

@ -273,11 +273,7 @@ void DrawTriangleCodegen::LoopBlockX()
SetStencilBlock(x / 8 + y / 8 * stencilPitch);
SSABool covered = a == SSAInt(0xF) && b == SSAInt(0xF) && c == SSAInt(0xF) && !clipneeded;
if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector && variant != TriDrawVariant::FuzzSubsector)
{
covered = covered && StencilIsSingleValue();
}
SSABool covered = a == SSAInt(0xF) && b == SSAInt(0xF) && c == SSAInt(0xF) && !clipneeded && StencilIsSingleValue();
// Accept whole block when totally covered
SSAIfBlock branch_covered;
@ -301,7 +297,11 @@ void DrawTriangleCodegen::LoopBlockX()
void DrawTriangleCodegen::LoopFullBlock()
{
SSAIfBlock branch_stenciltest;
if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector && variant != TriDrawVariant::FuzzSubsector)
if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector || variant == TriDrawVariant::StencilClose)
{
branch_stenciltest.if_block(SSABool::compare_uge(StencilGetSingle(), stencilTestValue));
}
else
{
branch_stenciltest.if_block(StencilGetSingle() == stencilTestValue);
}
@ -310,6 +310,18 @@ void DrawTriangleCodegen::LoopFullBlock()
{
StencilClear(stencilWriteValue);
}
else if (variant == TriDrawVariant::StencilClose)
{
StencilClear(stencilWriteValue);
for (int iy = 0; iy < q; iy++)
{
SSAIntPtr subsectorbuffer = subsectorGBuffer[x + iy * pitch];
for (int ix = 0; ix < q; ix += 4)
{
subsectorbuffer[ix].store_unaligned_vec4i(SSAVec4i(subsectorDepth));
}
}
}
else
{
int pixelsize = truecolor ? 4 : 1;
@ -407,10 +419,7 @@ void DrawTriangleCodegen::LoopFullBlock()
}
}
if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector && variant != TriDrawVariant::FuzzSubsector)
{
branch_stenciltest.end_block();
}
branch_stenciltest.end_block();
}
void DrawTriangleCodegen::LoopPartialBlock()
@ -468,7 +477,11 @@ void DrawTriangleCodegen::LoopPartialBlock()
if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector)
{
covered = covered && subsectorbuffer[ix].load(true) >= subsectorDepth;
covered = covered && SSABool::compare_uge(StencilGet(ix, iy), stencilTestValue) && subsectorbuffer[ix].load(true) >= subsectorDepth;
}
else if (variant == TriDrawVariant::StencilClose)
{
covered = covered && SSABool::compare_uge(StencilGet(ix, iy), stencilTestValue);
}
else
{
@ -482,6 +495,11 @@ void DrawTriangleCodegen::LoopPartialBlock()
{
StencilSet(ix, iy, stencilWriteValue);
}
else if (variant == TriDrawVariant::StencilClose)
{
StencilSet(ix, iy, stencilWriteValue);
subsectorbuffer[ix].store(subsectorDepth);
}
else
{
SSAUBytePtr buf = buffer[ix * pixelsize];

View file

@ -127,7 +127,7 @@ LLVMDrawers *LLVMDrawers::Instance()
LLVMDrawersImpl::LLVMDrawersImpl()
{
int version = 7; // Increment this number if the drawer codegen is modified (forces recreation of the module).
int version = 8; // Increment this number if the drawer codegen is modified (forces recreation of the module).
std::string targetCPU = mProgram.GetTargetCPU();
bool loaded = mProgram.LoadCachedModule(version, targetCPU);
if (!loaded)
@ -208,6 +208,7 @@ LLVMDrawersImpl::LLVMDrawersImpl()
CodegenDrawTriangle("TriFillSubsector32_" + std::to_string(i), TriDrawVariant::FillSubsector, (TriBlendMode)i, true);
}
CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, TriBlendMode::Copy, false);
CodegenDrawTriangle("TriStencilClose", TriDrawVariant::StencilClose, TriBlendMode::Copy, false);
}
mProgram.CreateEE(version, targetCPU, !loaded);
@ -286,6 +287,7 @@ LLVMDrawersImpl::LLVMDrawersImpl()
TriFillSubsector32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector32_" + std::to_string(i)));
}
TriStencil = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriStencil");
TriStencilClose = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriStencilClose");
#if 0
std::vector<uint32_t> foo(1024 * 4);

View file

@ -270,7 +270,8 @@ enum class TriDrawVariant
DrawSubsector,
FillSubsector,
FuzzSubsector,
Stencil
Stencil,
StencilClose
};
enum class TriBlendMode
@ -376,6 +377,7 @@ public:
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillSubsector8;
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillSubsector32;
void(*TriStencil)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
void(*TriStencilClose)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
private:
static LLVMDrawers *Singleton;

View file

@ -67,6 +67,11 @@ SSAVec4i SSABool::select(SSAVec4i a, SSAVec4i b)
return SSAValue::from_llvm(SSAScope::builder().CreateSelect(v, a.v, b.v, SSAScope::hint()));
}
SSABool SSABool::compare_uge(const SSAUByte &a, const SSAUByte &b)
{
return SSABool::from_llvm(SSAScope::builder().CreateICmpUGE(a.v, b.v, SSAScope::hint()));
}
SSABool operator&&(const SSABool &a, const SSABool &b)
{
return SSABool::from_llvm(SSAScope::builder().CreateAnd(a.v, b.v, SSAScope::hint()));

View file

@ -45,6 +45,8 @@ public:
SSAUByte select(SSAUByte a, SSAUByte b);
SSAVec4i select(SSAVec4i a, SSAVec4i b);
static SSABool compare_uge(const SSAUByte &a, const SSAUByte &b);
llvm::Value *v;
};

View file

@ -160,7 +160,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
break;
}
}
if (!portal)
if (!polyportal)
{
sectorPortals.push_back(std::make_unique<PolyDrawSectorPortal>(portal, ceiling));
polyportal = sectorPortals.back().get();
@ -266,7 +266,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
{
args.stencilwritevalue = 252;
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw });
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, subsectorDepth });
}
}
else
@ -274,7 +274,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
if (portal)
{
args.stencilwritevalue = 252;
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw });
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, subsectorDepth });
}
else
{
@ -352,7 +352,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
if (portal)
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw });
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, subsectorDepth });
}
}
}

View file

@ -196,6 +196,7 @@ void RenderPolyPortal::RenderTranslucent()
PolyDrawArgs args;
args.objectToClip = &WorldToClip;
args.mode = TriangleDrawMode::Fan;
args.stenciltestvalue = 253;
args.stencilwritevalue = 1;
for (const auto &verts : (*it)->Shape)
@ -203,7 +204,8 @@ void RenderPolyPortal::RenderTranslucent()
args.vinput = verts.Vertices;
args.vcount = verts.Count;
args.ccw = verts.Ccw;
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
args.uniforms.subsectorDepth = verts.SubsectorDepth;
PolyTriangleDrawer::draw(args, TriDrawVariant::StencilClose, TriBlendMode::Copy);
}
}
@ -213,6 +215,7 @@ void RenderPolyPortal::RenderTranslucent()
PolyDrawArgs args;
args.objectToClip = &WorldToClip;
args.mode = TriangleDrawMode::Fan;
args.stenciltestvalue = 253;
args.stencilwritevalue = 1;
for (const auto &verts : (*it)->Shape)
@ -220,7 +223,8 @@ void RenderPolyPortal::RenderTranslucent()
args.vinput = verts.Vertices;
args.vcount = verts.Count;
args.ccw = verts.Ccw;
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
args.uniforms.subsectorDepth = verts.SubsectorDepth;
PolyTriangleDrawer::draw(args, TriDrawVariant::StencilClose, TriBlendMode::Copy);
}
}
@ -310,12 +314,12 @@ void PolyDrawSectorPortal::RenderTranslucent()
void PolyDrawSectorPortal::SaveGlobals()
{
int savedextralight = extralight;
DVector3 savedpos = ViewPos;
DAngle savedangle = ViewAngle;
double savedvisibility = R_GetVisibility();
AActor *savedcamera = camera;
sector_t *savedsector = viewsector;
savedextralight = extralight;
savedpos = ViewPos;
savedangle = ViewAngle;
savedvisibility = R_GetVisibility();
savedcamera = camera;
savedsector = viewsector;
// Don't let gun flashes brighten the sky box
ASkyViewpoint *sky = barrier_cast<ASkyViewpoint*>(Portal->mSkybox);

View file

@ -112,10 +112,11 @@ private:
struct PolyPortalVertexRange
{
PolyPortalVertexRange(const TriVertex *vertices, int count, bool ccw) : Vertices(vertices), Count(count), Ccw(ccw) { }
PolyPortalVertexRange(const TriVertex *vertices, int count, bool ccw, uint32_t subsectorDepth) : Vertices(vertices), Count(count), Ccw(ccw), SubsectorDepth(subsectorDepth) { }
const TriVertex *Vertices;
int Count;
bool Ccw;
uint32_t SubsectorDepth;
};
class PolyDrawSectorPortal

View file

@ -90,6 +90,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian
case TriDrawVariant::FuzzSubsector:
case TriDrawVariant::FillSubsector: drawfunc = dest_bgra ? llvm->TriFillSubsector32[bmode] : llvm->TriFillSubsector8[bmode]; break;
case TriDrawVariant::Stencil: drawfunc = llvm->TriStencil; break;
case TriDrawVariant::StencilClose: drawfunc = llvm->TriStencilClose; break;
}
TriDrawTriangleArgs args;