diff --git a/src/rendering/polyrenderer/backend/poly_renderstate.cpp b/src/rendering/polyrenderer/backend/poly_renderstate.cpp index 5e770c1db..b75236c81 100644 --- a/src/rendering/polyrenderer/backend/poly_renderstate.cpp +++ b/src/rendering/polyrenderer/backend/poly_renderstate.cpp @@ -108,7 +108,7 @@ void PolyRenderState::Clear(int targets) //if (targets & CT_Color) // PolyTriangleDrawer::ClearColor(GetPolyFrameBuffer()->GetDrawCommands()); if (targets & CT_Depth) - PolyTriangleDrawer::ClearDepth(GetPolyFrameBuffer()->GetDrawCommands(), 0.0f); + PolyTriangleDrawer::ClearDepth(GetPolyFrameBuffer()->GetDrawCommands(), 65535.0f); if (targets & CT_Stencil) PolyTriangleDrawer::ClearStencil(GetPolyFrameBuffer()->GetDrawCommands(), 0); } diff --git a/src/rendering/polyrenderer/drawers/poly_triangle.cpp b/src/rendering/polyrenderer/drawers/poly_triangle.cpp index 6b542f962..7a279ebbb 100644 --- a/src/rendering/polyrenderer/drawers/poly_triangle.cpp +++ b/src/rendering/polyrenderer/drawers/poly_triangle.cpp @@ -338,10 +338,18 @@ void PolyTriangleThreadData::SetDepthFunc(int func) void PolyTriangleThreadData::SetDepthRange(float min, float max) { + // The only two variants used by hwrenderer layer + if (min == 0.0f && max == 1.0f) + { + } + else if (min == 1.0f && max == 1.0f) + { + } } void PolyTriangleThreadData::SetDepthBias(float depthBiasConstantFactor, float depthBiasSlopeFactor) { + depthbias = (float)(depthBiasConstantFactor / 65536.0); } void PolyTriangleThreadData::SetColorMask(bool r, bool g, bool b, bool a) diff --git a/src/rendering/polyrenderer/drawers/poly_triangle.h b/src/rendering/polyrenderer/drawers/poly_triangle.h index a14216cae..81a4bf7e0 100644 --- a/src/rendering/polyrenderer/drawers/poly_triangle.h +++ b/src/rendering/polyrenderer/drawers/poly_triangle.h @@ -121,7 +121,7 @@ public: void SetTransform(const Mat4f *objectToClip, const Mat4f *objectToWorld); void SetCullCCW(bool value) { ccw = value; } void SetTwoSided(bool value) { twosided = value; } - void SetWeaponScene(bool value) { weaponScene = value; } + void SetWeaponScene(bool value) { depthbias = value ? -1.0f : 0.0f; } void SetModelVertexShader(int frame1, int frame2, float interpolationFactor) { modelFrame1 = frame1; modelFrame2 = frame2; swVertexShader.modelInterpolationFactor = interpolationFactor; } void SetInputAssembly(PolyInputAssembly *input) { inputAssembly = input; } @@ -187,6 +187,7 @@ public: int32_t texelV[MAXWIDTH]; uint16_t lightarray[MAXWIDTH]; uint32_t dynlights[MAXWIDTH]; + float depthvalues[MAXWIDTH]; static PolyTriangleThreadData *Get(DrawerThread *thread); @@ -195,7 +196,7 @@ public: int dest_height = 0; bool dest_bgra = false; uint8_t *dest = nullptr; - bool weaponScene = false; + float depthbias = 0.0f; int viewport_y = 0; diff --git a/src/rendering/polyrenderer/drawers/screen_triangle.cpp b/src/rendering/polyrenderer/drawers/screen_triangle.cpp index 5f37e3b87..af6b3ec22 100644 --- a/src/rendering/polyrenderer/drawers/screen_triangle.cpp +++ b/src/rendering/polyrenderer/drawers/screen_triangle.cpp @@ -151,13 +151,37 @@ void ScreenTriangle::Draw(const TriDrawTriangleArgs *args, PolyTriangleThreadDat TriangleDrawers[opt](args, thread, edges, topY, bottomY); } +static void FillDepthValues(float *depthvalues, float posXW, float stepXW, int count, float depthbias) +{ +#ifndef NO_SSE + __m128 mstepXW = _mm_set1_ps(stepXW * 4.0f); + __m128 mfirstStepXW = _mm_setr_ps(0.0f, stepXW, stepXW + stepXW, stepXW + stepXW + stepXW); + __m128 mposXW = _mm_add_ps(_mm_set1_ps(posXW), mfirstStepXW); + __m128 mdepthbias = _mm_set1_ps(depthbias); + while (count > 0) + { + _mm_storeu_ps(depthvalues, _mm_add_ps(_mm_rcp_ps(mposXW), mdepthbias)); + mposXW = _mm_add_ps(mposXW, mstepXW); + depthvalues += 4; + count -= 4; + } +#else + while (count > 0) + { + *(depthvalues++) = 1.0f / posXW + depthbias; + posXW += stepXW; + count--; + } +#endif +} + template void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread, int16_t *edges, int topY, int bottomY) { using namespace TriScreenDrawerModes; void(*drawfunc)(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread); - float stepXW, v1X, v1Y, v1W, posXW; + float stepXW, v1X, v1Y, v1W; uint8_t stencilTestValue, stencilWriteValue; float *zbuffer; float *zbufferLine; @@ -194,12 +218,14 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa if (OptT::Flags & SWTRI_WriteStencil) stencilWriteValue = args->uniforms->StencilWriteValue(); - float weaponWOffset; + float depthbias; if ((OptT::Flags & SWTRI_DepthTest) || (OptT::Flags & SWTRI_WriteDepth)) { - weaponWOffset = thread->weaponScene ? 1.0f : 0.0f; + depthbias = thread->depthbias; } + float *depthvalues = thread->depthvalues; + int num_cores = thread->num_cores; for (int y = topY; y < bottomY; y += num_cores) { @@ -215,16 +241,11 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa float startX = x + (0.5f - v1X); float startY = y + (0.5f - v1Y); - posXW = v1W + stepXW * startX + args->gradientY.W * startY + weaponWOffset; + float posXW = v1W + stepXW * startX + args->gradientY.W * startY; + FillDepthValues(depthvalues + x, posXW, stepXW, xend - x, depthbias); } #ifndef NO_SSE - __m128 mstepXW, mfirstStepXW; - if ((OptT::Flags & SWTRI_DepthTest) || (OptT::Flags & SWTRI_WriteDepth)) - { - mstepXW = _mm_set1_ps(stepXW * 4.0f); - mfirstStepXW = _mm_setr_ps(0.0f, stepXW, stepXW + stepXW, stepXW + stepXW + stepXW); - } while (x < xend) { int xstart = x; @@ -232,9 +253,9 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa if ((OptT::Flags & SWTRI_DepthTest) && (OptT::Flags & SWTRI_StencilTest)) { int xendsse = x + ((xend - x) / 4); - __m128 mposXW = _mm_add_ps(_mm_set1_ps(posXW), mfirstStepXW); + __m128 mposXW; while (x < xendsse && - _mm_movemask_ps(_mm_cmple_ps(_mm_loadu_ps(zbufferLine + x), mposXW)) == 15 && + _mm_movemask_ps(_mm_cmpge_ps(_mm_loadu_ps(zbufferLine + x), mposXW = _mm_loadu_ps(depthvalues + x))) == 15 && stencilLine[x] == stencilTestValue && stencilLine[x + 1] == stencilTestValue && stencilLine[x + 2] == stencilTestValue && @@ -242,37 +263,31 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa { if (OptT::Flags & SWTRI_WriteDepth) _mm_storeu_ps(zbufferLine + x, mposXW); - mposXW = _mm_add_ps(mposXW, mstepXW); x += 4; } - posXW = _mm_cvtss_f32(mposXW); - while (zbufferLine[x] <= posXW && stencilLine[x] == stencilTestValue && x < xend) + while (zbufferLine[x] >= depthvalues[x] && stencilLine[x] == stencilTestValue && x < xend) { if (OptT::Flags & SWTRI_WriteDepth) - zbufferLine[x] = posXW; - posXW += stepXW; + zbufferLine[x] = depthvalues[x]; x++; } } else if (OptT::Flags & SWTRI_DepthTest) { int xendsse = x + ((xend - x) / 4); - __m128 mposXW = _mm_add_ps(_mm_set1_ps(posXW), mfirstStepXW); - while (x < xendsse && _mm_movemask_ps(_mm_cmple_ps(_mm_loadu_ps(zbufferLine + x), mposXW)) == 15) + __m128 mposXW; + while (x < xendsse && _mm_movemask_ps(_mm_cmpge_ps(_mm_loadu_ps(zbufferLine + x), mposXW = _mm_loadu_ps(depthvalues + x))) == 15) { if (OptT::Flags & SWTRI_WriteDepth) _mm_storeu_ps(zbufferLine + x, mposXW); - mposXW = _mm_add_ps(mposXW, mstepXW); x += 4; } - posXW = _mm_cvtss_f32(mposXW); - while (zbufferLine[x] <= posXW && x < xend) + while (zbufferLine[x] >= depthvalues[x] && x < xend) { if (OptT::Flags & SWTRI_WriteDepth) - zbufferLine[x] = posXW; - posXW += stepXW; + zbufferLine[x] = depthvalues[x]; x++; } } @@ -315,8 +330,7 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa { for (int i = xstart; i < x; i++) { - zbufferLine[i] = posXW; - posXW += stepXW; + zbufferLine[i] = depthvalues[i]; } } } @@ -324,39 +338,33 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa if ((OptT::Flags & SWTRI_DepthTest) && (OptT::Flags & SWTRI_StencilTest)) { int xendsse = x + ((xend - x) / 4); - __m128 mposXW = _mm_add_ps(_mm_set1_ps(posXW), mfirstStepXW); + __m128 mposXW; while (x < xendsse && - (_mm_movemask_ps(_mm_cmple_ps(_mm_loadu_ps(zbufferLine + x), mposXW)) == 0 || + (_mm_movemask_ps(_mm_cmpge_ps(_mm_loadu_ps(zbufferLine + x), mposXW = _mm_loadu_ps(depthvalues + x))) == 0 || stencilLine[x] != stencilTestValue || stencilLine[x + 1] != stencilTestValue || stencilLine[x + 2] != stencilTestValue || stencilLine[x + 3] != stencilTestValue)) { - mposXW = _mm_add_ps(mposXW, mstepXW); x += 4; } - posXW = _mm_cvtss_f32(mposXW); - while ((zbufferLine[x] > posXW || stencilLine[x] != stencilTestValue) && x < xend) + while ((zbufferLine[x] < depthvalues[x] || stencilLine[x] != stencilTestValue) && x < xend) { - posXW += stepXW; x++; } } else if (OptT::Flags & SWTRI_DepthTest) { int xendsse = x + ((xend - x) / 4); - __m128 mposXW = _mm_add_ps(_mm_set1_ps(posXW), mfirstStepXW); - while (x < xendsse && _mm_movemask_ps(_mm_cmple_ps(_mm_loadu_ps(zbufferLine + x), mposXW)) == 0) + __m128 mposXW; + while (x < xendsse && _mm_movemask_ps(_mm_cmpge_ps(_mm_loadu_ps(zbufferLine + x), mposXW = _mm_loadu_ps(depthvalues + x))) == 0) { - mposXW = _mm_add_ps(mposXW, mstepXW); x += 4; } - posXW = _mm_cvtss_f32(mposXW); - while (zbufferLine[x] > posXW && x < xend) + while (zbufferLine[x] < depthvalues[x] && x < xend) { - posXW += stepXW; x++; } } @@ -381,21 +389,19 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa if ((OptT::Flags & SWTRI_DepthTest) && (OptT::Flags & SWTRI_StencilTest)) { - while (zbufferLine[x] <= posXW && stencilLine[x] == stencilTestValue && x < xend) + while (zbufferLine[x] >= depthvalues[x] && stencilLine[x] == stencilTestValue && x < xend) { if (OptT::Flags & SWTRI_WriteDepth) - zbufferLine[x] = posXW; - posXW += stepXW; + zbufferLine[x] = depthvalues[x]; x++; } } else if (OptT::Flags & SWTRI_DepthTest) { - while (zbufferLine[x] <= posXW && x < xend) + while (zbufferLine[x] >= depthvalues[x] && x < xend) { if (OptT::Flags & SWTRI_WriteDepth) - zbufferLine[x] = posXW; - posXW += stepXW; + zbufferLine[x] = depthvalues[x]; x++; } } @@ -424,25 +430,22 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa { for (int i = xstart; i < x; i++) { - zbufferLine[i] = posXW; - posXW += stepXW; + zbufferLine[i] = depthvalues[i]; } } } if ((OptT::Flags & SWTRI_DepthTest) && (OptT::Flags & SWTRI_StencilTest)) { - while ((zbufferLine[x] > posXW || stencilLine[x] != stencilTestValue) && x < xend) + while ((zbufferLine[x] < depthvalues[x] || stencilLine[x] != stencilTestValue) && x < xend) { - posXW += stepXW; x++; } } else if (OptT::Flags & SWTRI_DepthTest) { - while (zbufferLine[x] > posXW && x < xend) + while (zbufferLine[x] < depthvalues[x] && x < xend) { - posXW += stepXW; x++; } } diff --git a/src/rendering/swrenderer/drawers/r_draw.cpp b/src/rendering/swrenderer/drawers/r_draw.cpp index 42d9d6c07..20425a7ec 100644 --- a/src/rendering/swrenderer/drawers/r_draw.cpp +++ b/src/rendering/swrenderer/drawers/r_draw.cpp @@ -220,7 +220,7 @@ namespace swrenderer class DepthColumnCommand : public DrawerCommand { public: - DepthColumnCommand(const WallDrawerArgs &args, float idepth) : idepth(idepth) + DepthColumnCommand(const WallDrawerArgs &args, float idepth) : idepth(1.0f / idepth) { auto rendertarget = args.Viewport()->RenderTarget; if (rendertarget->IsBgra()) @@ -244,7 +244,7 @@ namespace swrenderer count = args.Count(); } - DepthColumnCommand(const SkyDrawerArgs &args, float idepth) : idepth(idepth) + DepthColumnCommand(const SkyDrawerArgs &args, float idepth) : idepth(1.0f / idepth) { auto rendertarget = args.Viewport()->RenderTarget; if (rendertarget->IsBgra()) @@ -319,7 +319,7 @@ namespace swrenderer if (idepth1 == idepth2) { - float depth = idepth1; + float depth = 1.0f / idepth1; #ifdef DEPTH_DEBUG uint32_t gray = clamp((int32_t)(1.0f / depth / 4.0f), 0, 255); uint32_t color = MAKEARGB(255, gray, gray, gray); @@ -344,7 +344,7 @@ namespace swrenderer dest[x] = color; #endif - values[x] = depth; + values[x] = 1.0f / depth; depth += step; } }