mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-02 08:52:12 +00:00
- implement depth bias
This commit is contained in:
parent
bc5b953633
commit
bd591c75fb
5 changed files with 69 additions and 57 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<typename OptT>
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>((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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue