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); 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 && StencilIsSingleValue();
if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector && variant != TriDrawVariant::FuzzSubsector)
{
covered = covered && StencilIsSingleValue();
}
// Accept whole block when totally covered // Accept whole block when totally covered
SSAIfBlock branch_covered; SSAIfBlock branch_covered;
@ -301,7 +297,11 @@ void DrawTriangleCodegen::LoopBlockX()
void DrawTriangleCodegen::LoopFullBlock() void DrawTriangleCodegen::LoopFullBlock()
{ {
SSAIfBlock branch_stenciltest; 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); branch_stenciltest.if_block(StencilGetSingle() == stencilTestValue);
} }
@ -310,6 +310,18 @@ void DrawTriangleCodegen::LoopFullBlock()
{ {
StencilClear(stencilWriteValue); 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 else
{ {
int pixelsize = truecolor ? 4 : 1; 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() void DrawTriangleCodegen::LoopPartialBlock()
@ -468,7 +477,11 @@ void DrawTriangleCodegen::LoopPartialBlock()
if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector) 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 else
{ {
@ -482,6 +495,11 @@ void DrawTriangleCodegen::LoopPartialBlock()
{ {
StencilSet(ix, iy, stencilWriteValue); StencilSet(ix, iy, stencilWriteValue);
} }
else if (variant == TriDrawVariant::StencilClose)
{
StencilSet(ix, iy, stencilWriteValue);
subsectorbuffer[ix].store(subsectorDepth);
}
else else
{ {
SSAUBytePtr buf = buffer[ix * pixelsize]; SSAUBytePtr buf = buffer[ix * pixelsize];

View File

@ -127,7 +127,7 @@ LLVMDrawers *LLVMDrawers::Instance()
LLVMDrawersImpl::LLVMDrawersImpl() 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(); std::string targetCPU = mProgram.GetTargetCPU();
bool loaded = mProgram.LoadCachedModule(version, targetCPU); bool loaded = mProgram.LoadCachedModule(version, targetCPU);
if (!loaded) if (!loaded)
@ -208,6 +208,7 @@ LLVMDrawersImpl::LLVMDrawersImpl()
CodegenDrawTriangle("TriFillSubsector32_" + std::to_string(i), TriDrawVariant::FillSubsector, (TriBlendMode)i, true); CodegenDrawTriangle("TriFillSubsector32_" + std::to_string(i), TriDrawVariant::FillSubsector, (TriBlendMode)i, true);
} }
CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, TriBlendMode::Copy, false); CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, TriBlendMode::Copy, false);
CodegenDrawTriangle("TriStencilClose", TriDrawVariant::StencilClose, TriBlendMode::Copy, false);
} }
mProgram.CreateEE(version, targetCPU, !loaded); 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))); 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");
TriStencilClose = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriStencilClose");
#if 0 #if 0
std::vector<uint32_t> foo(1024 * 4); std::vector<uint32_t> foo(1024 * 4);

View File

@ -270,7 +270,8 @@ enum class TriDrawVariant
DrawSubsector, DrawSubsector,
FillSubsector, FillSubsector,
FuzzSubsector, FuzzSubsector,
Stencil Stencil,
StencilClose
}; };
enum class TriBlendMode enum class TriBlendMode
@ -376,6 +377,7 @@ public:
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillSubsector8; std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillSubsector8;
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillSubsector32; std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillSubsector32;
void(*TriStencil)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; void(*TriStencil)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
void(*TriStencilClose)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
private: private:
static LLVMDrawers *Singleton; 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())); 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) SSABool operator&&(const SSABool &a, const SSABool &b)
{ {
return SSABool::from_llvm(SSAScope::builder().CreateAnd(a.v, b.v, SSAScope::hint())); 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); SSAUByte select(SSAUByte a, SSAUByte b);
SSAVec4i select(SSAVec4i a, SSAVec4i b); SSAVec4i select(SSAVec4i a, SSAVec4i b);
static SSABool compare_uge(const SSAUByte &a, const SSAUByte &b);
llvm::Value *v; llvm::Value *v;
}; };

View File

@ -160,7 +160,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
break; break;
} }
} }
if (!portal) if (!polyportal)
{ {
sectorPortals.push_back(std::make_unique<PolyDrawSectorPortal>(portal, ceiling)); sectorPortals.push_back(std::make_unique<PolyDrawSectorPortal>(portal, ceiling));
polyportal = sectorPortals.back().get(); polyportal = sectorPortals.back().get();
@ -266,7 +266,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
{ {
args.stencilwritevalue = 252; args.stencilwritevalue = 252;
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy); 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 else
@ -274,7 +274,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
if (portal) if (portal)
{ {
args.stencilwritevalue = 252; 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 else
{ {
@ -352,7 +352,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy); PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
if (portal) 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; PolyDrawArgs args;
args.objectToClip = &WorldToClip; args.objectToClip = &WorldToClip;
args.mode = TriangleDrawMode::Fan;
args.stenciltestvalue = 253; args.stenciltestvalue = 253;
args.stencilwritevalue = 1; args.stencilwritevalue = 1;
for (const auto &verts : (*it)->Shape) for (const auto &verts : (*it)->Shape)
@ -203,7 +204,8 @@ void RenderPolyPortal::RenderTranslucent()
args.vinput = verts.Vertices; args.vinput = verts.Vertices;
args.vcount = verts.Count; args.vcount = verts.Count;
args.ccw = verts.Ccw; 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; PolyDrawArgs args;
args.objectToClip = &WorldToClip; args.objectToClip = &WorldToClip;
args.mode = TriangleDrawMode::Fan;
args.stenciltestvalue = 253; args.stenciltestvalue = 253;
args.stencilwritevalue = 1; args.stencilwritevalue = 1;
for (const auto &verts : (*it)->Shape) for (const auto &verts : (*it)->Shape)
@ -220,7 +223,8 @@ void RenderPolyPortal::RenderTranslucent()
args.vinput = verts.Vertices; args.vinput = verts.Vertices;
args.vcount = verts.Count; args.vcount = verts.Count;
args.ccw = verts.Ccw; 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() void PolyDrawSectorPortal::SaveGlobals()
{ {
int savedextralight = extralight; savedextralight = extralight;
DVector3 savedpos = ViewPos; savedpos = ViewPos;
DAngle savedangle = ViewAngle; savedangle = ViewAngle;
double savedvisibility = R_GetVisibility(); savedvisibility = R_GetVisibility();
AActor *savedcamera = camera; savedcamera = camera;
sector_t *savedsector = viewsector; savedsector = viewsector;
// Don't let gun flashes brighten the sky box // Don't let gun flashes brighten the sky box
ASkyViewpoint *sky = barrier_cast<ASkyViewpoint*>(Portal->mSkybox); ASkyViewpoint *sky = barrier_cast<ASkyViewpoint*>(Portal->mSkybox);

View File

@ -112,10 +112,11 @@ private:
struct PolyPortalVertexRange 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; const TriVertex *Vertices;
int Count; int Count;
bool Ccw; bool Ccw;
uint32_t SubsectorDepth;
}; };
class PolyDrawSectorPortal class PolyDrawSectorPortal

View File

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