From b2ad26d2d5868cf9d66de3dc8b093b5e03be982f Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 25 Nov 2016 07:44:51 +0100 Subject: [PATCH] Sealing off portal entrances for the transparency pass --- .../fixedfunction/drawtrianglecodegen.cpp | 40 ++++++++++++++----- src/r_compiler/llvmdrawers.cpp | 4 +- src/r_compiler/llvmdrawers.h | 4 +- src/r_compiler/ssa/ssa_bool.cpp | 5 +++ src/r_compiler/ssa/ssa_bool.h | 2 + src/r_poly_plane.cpp | 8 ++-- src/r_poly_portal.cpp | 20 ++++++---- src/r_poly_portal.h | 3 +- src/r_poly_triangle.cpp | 1 + 9 files changed, 61 insertions(+), 26 deletions(-) diff --git a/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp b/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp index b34f34799..09d3a618e 100644 --- a/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp +++ b/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp @@ -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]; diff --git a/src/r_compiler/llvmdrawers.cpp b/src/r_compiler/llvmdrawers.cpp index fc44f67bd..babb7c6e7 100644 --- a/src/r_compiler/llvmdrawers.cpp +++ b/src/r_compiler/llvmdrawers.cpp @@ -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("TriFillSubsector32_" + std::to_string(i))); } TriStencil = mProgram.GetProcAddress("TriStencil"); + TriStencilClose = mProgram.GetProcAddress("TriStencilClose"); #if 0 std::vector foo(1024 * 4); diff --git a/src/r_compiler/llvmdrawers.h b/src/r_compiler/llvmdrawers.h index 6113b1d04..4ce3a3a03 100644 --- a/src/r_compiler/llvmdrawers.h +++ b/src/r_compiler/llvmdrawers.h @@ -270,7 +270,8 @@ enum class TriDrawVariant DrawSubsector, FillSubsector, FuzzSubsector, - Stencil + Stencil, + StencilClose }; enum class TriBlendMode @@ -376,6 +377,7 @@ public: std::vector TriFillSubsector8; std::vector TriFillSubsector32; void(*TriStencil)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; + void(*TriStencilClose)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; private: static LLVMDrawers *Singleton; diff --git a/src/r_compiler/ssa/ssa_bool.cpp b/src/r_compiler/ssa/ssa_bool.cpp index 916350c59..d6ecad4e8 100644 --- a/src/r_compiler/ssa/ssa_bool.cpp +++ b/src/r_compiler/ssa/ssa_bool.cpp @@ -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())); diff --git a/src/r_compiler/ssa/ssa_bool.h b/src/r_compiler/ssa/ssa_bool.h index 372c626c0..9b8a564d8 100644 --- a/src/r_compiler/ssa/ssa_bool.h +++ b/src/r_compiler/ssa/ssa_bool.h @@ -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; }; diff --git a/src/r_poly_plane.cpp b/src/r_poly_plane.cpp index 0c19d9832..c8248bed6 100644 --- a/src/r_poly_plane.cpp +++ b/src/r_poly_plane.cpp @@ -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(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 }); } } } diff --git a/src/r_poly_portal.cpp b/src/r_poly_portal.cpp index e500e24d1..805195835 100644 --- a/src/r_poly_portal.cpp +++ b/src/r_poly_portal.cpp @@ -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(Portal->mSkybox); diff --git a/src/r_poly_portal.h b/src/r_poly_portal.h index 6042d5938..8878f496d 100644 --- a/src/r_poly_portal.h +++ b/src/r_poly_portal.h @@ -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 diff --git a/src/r_poly_triangle.cpp b/src/r_poly_triangle.cpp index 9a389777a..298c5f024 100644 --- a/src/r_poly_triangle.cpp +++ b/src/r_poly_triangle.cpp @@ -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;