mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-07 09:01:57 +00:00
Sealing off portal entrances for the transparency pass
This commit is contained in:
parent
e642ed099a
commit
b2ad26d2d5
9 changed files with 61 additions and 26 deletions
|
@ -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];
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()));
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue