From c1e2c25907bb9b36de55b6d940a6728f221ef616 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 13 Dec 2016 02:13:48 +0100 Subject: [PATCH] Stencil close --- src/r_poly_triangle.cpp | 59 +++++++++++++++++++++++++++++++++++++++++ src/r_poly_triangle.h | 2 ++ 2 files changed, 61 insertions(+) diff --git a/src/r_poly_triangle.cpp b/src/r_poly_triangle.cpp index a3a48445a..3e334b617 100644 --- a/src/r_poly_triangle.cpp +++ b/src/r_poly_triangle.cpp @@ -94,6 +94,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian default: //case TriDrawVariant::DrawNormal: drawfunc = dest_bgra ? &ScreenTriangle::DrawFunc : llvm->TriDrawNormal8[bmode]; break; //case TriDrawVariant::Stencil: drawfunc = &ScreenTriangle::StencilFunc; break; + //case TriDrawVariant::StencilClose: drawfunc = &ScreenTriangle::StencilCloseFunc; 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; @@ -891,6 +892,57 @@ void ScreenTriangle::StencilWrite(const TriDrawTriangleArgs *args) } } +void ScreenTriangle::SubsectorWrite(const TriDrawTriangleArgs *args) +{ + uint32_t subsectorDepth = args->uniforms->subsectorDepth; + + for (int i = 0; i < NumFullSpans; i++) + { + const auto &span = FullSpans[i]; + + uint32_t *subsector = args->subsectorGBuffer + span.X + span.Y * args->pitch; + int pitch = args->pitch; + int width = span.Length * 8; + int height = 8; + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + subsector[x] = subsectorDepth; + subsector += pitch; + } + } + + for (int i = 0; i < NumPartialBlocks; i++) + { + const auto &block = PartialBlocks[i]; + + uint32_t *subsector = args->subsectorGBuffer + block.X + block.Y * args->pitch; + int pitch = args->pitch; + uint32_t mask0 = block.Mask0; + uint32_t mask1 = block.Mask1; + for (int y = 0; y < 4; y++) + { + for (int x = 0; x < 8; x++) + { + if (mask0 & (1 << 31)) + subsector[x] = subsectorDepth; + mask0 <<= 1; + } + subsector += pitch; + } + for (int y = 4; y < 8; y++) + { + for (int x = 0; x < 8; x++) + { + if (mask1 & (1 << 31)) + subsector[x] = subsectorDepth; + mask1 <<= 1; + } + subsector += pitch; + } + } +} + float ScreenTriangle::FindGradientX(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2) { float top = (c1 - c2) * (y0 - y2) - (c0 - c2) * (y1 - y2); @@ -1158,6 +1210,13 @@ void ScreenTriangle::StencilFunc(const TriDrawTriangleArgs *args, WorkerThreadDa triangle[thread->core].StencilWrite(args); } +void ScreenTriangle::StencilCloseFunc(const TriDrawTriangleArgs *args, WorkerThreadData *thread) +{ + triangle[thread->core].Setup(args, thread); + triangle[thread->core].StencilWrite(args); + triangle[thread->core].SubsectorWrite(args); +} + ScreenTriangle::ScreenTriangle() { FullSpansBuffer.resize(MAXWIDTH / 8 * (MAXHEIGHT / 8)); diff --git a/src/r_poly_triangle.h b/src/r_poly_triangle.h index 6e0508fbb..12591425a 100644 --- a/src/r_poly_triangle.h +++ b/src/r_poly_triangle.h @@ -291,12 +291,14 @@ class ScreenTriangle public: static void DrawFunc(const TriDrawTriangleArgs *args, WorkerThreadData *thread); static void StencilFunc(const TriDrawTriangleArgs *args, WorkerThreadData *thread); + static void StencilCloseFunc(const TriDrawTriangleArgs *args, WorkerThreadData *thread); ScreenTriangle(); void Setup(const TriDrawTriangleArgs *args, WorkerThreadData *thread); void Draw(const TriDrawTriangleArgs *args); void StencilWrite(const TriDrawTriangleArgs *args); + void SubsectorWrite(const TriDrawTriangleArgs *args); ScreenTriangleFullSpan *FullSpans; ScreenTrianglePartialBlock *PartialBlocks;