Implement depthBoundsTest

The depthBoundsTest checks if the depth is withing a certain range, and if not, sets coverage to 0 for the particular fragment. Tests: dEQP-VK.pipeline.depth.nocolor.format.d16_unorm.compare_ops.* Tests: dEQP-VK.pipeline.depth.nocolor.format.d32_sfloat.compare_ops.* Tests: dEQP-VK.pipeline.depth.nocolor.format.d32_sfloat_s8_uint.compare_ops.* Tests: dEQP-VK.pipeline.depth.nocolor.format.d32_sfloat_s8_uint_separate_layouts.compare_ops.* Tests: dEQP-VK.dynamic_state.ds_state.depth_bounds_1 Tests: dEQP-VK.dynamic_state.ds_state.depth_bounds_2 Tests: dEQP-VK.rasterization.frag_side_effects.color_at_end.depth_bounds Tests: dEQP-VK.rasterization.frag_side_effects.color_at_beginning.depth_bounds Bug: b/181656417 Change-Id: I50076834afa21f5b93e59b27a5438ba26f8008c8 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/53888 Kokoro-Result: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarSean Risser <srisser@google.com> Commit-Queue: Sean Risser <srisser@google.com>
parent 45be1bc3
...@@ -457,12 +457,10 @@ GraphicsState::GraphicsState(const Device *device, const VkGraphicsPipelineCreat ...@@ -457,12 +457,10 @@ GraphicsState::GraphicsState(const Device *device, const VkGraphicsPipelineCreat
UNSUPPORTED("pCreateInfo->pDepthStencilState->flags %d", int(pCreateInfo->pDepthStencilState->flags)); UNSUPPORTED("pCreateInfo->pDepthStencilState->flags %d", int(pCreateInfo->pDepthStencilState->flags));
} }
if(depthStencilState->depthBoundsTestEnable != VK_FALSE)
{
UNSUPPORTED("VkPhysicalDeviceFeatures::depthBounds");
}
depthBoundsTestEnable = (depthStencilState->depthBoundsTestEnable != VK_FALSE); depthBoundsTestEnable = (depthStencilState->depthBoundsTestEnable != VK_FALSE);
minDepthBounds = depthStencilState->minDepthBounds;
maxDepthBounds = depthStencilState->maxDepthBounds;
depthBufferEnable = (depthStencilState->depthTestEnable != VK_FALSE); depthBufferEnable = (depthStencilState->depthTestEnable != VK_FALSE);
depthWriteEnable = (depthStencilState->depthWriteEnable != VK_FALSE); depthWriteEnable = (depthStencilState->depthWriteEnable != VK_FALSE);
depthCompareMode = depthStencilState->depthCompareOp; depthCompareMode = depthStencilState->depthCompareOp;
...@@ -593,6 +591,11 @@ bool GraphicsState::stencilActive(const Attachments &attachments) const ...@@ -593,6 +591,11 @@ bool GraphicsState::stencilActive(const Attachments &attachments) const
return attachments.stencilBuffer && stencilEnable; return attachments.stencilBuffer && stencilEnable;
} }
bool GraphicsState::depthBoundsTestActive() const
{
return depthBoundsTestEnable;
}
const GraphicsState GraphicsState::combineStates(const DynamicState &dynamicState) const const GraphicsState GraphicsState::combineStates(const DynamicState &dynamicState) const
{ {
GraphicsState combinedState = *this; GraphicsState combinedState = *this;
...@@ -627,7 +630,8 @@ const GraphicsState GraphicsState::combineStates(const DynamicState &dynamicStat ...@@ -627,7 +630,8 @@ const GraphicsState GraphicsState::combineStates(const DynamicState &dynamicStat
ASSERT(dynamicState.minDepthBounds >= 0.0f && dynamicState.minDepthBounds <= 1.0f); ASSERT(dynamicState.minDepthBounds >= 0.0f && dynamicState.minDepthBounds <= 1.0f);
ASSERT(dynamicState.maxDepthBounds >= 0.0f && dynamicState.maxDepthBounds <= 1.0f); ASSERT(dynamicState.maxDepthBounds >= 0.0f && dynamicState.maxDepthBounds <= 1.0f);
UNSUPPORTED("VkPhysicalDeviceFeatures::depthBounds"); combinedState.minDepthBounds = dynamicState.minDepthBounds;
combinedState.maxDepthBounds = dynamicState.maxDepthBounds;
} }
if(hasDynamicState(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK) && stencilEnable) if(hasDynamicState(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK) && stencilEnable)
......
...@@ -155,6 +155,8 @@ struct GraphicsState ...@@ -155,6 +155,8 @@ struct GraphicsState
inline float getConstantDepthBias() const { return constantDepthBias; } inline float getConstantDepthBias() const { return constantDepthBias; }
inline float getSlopeDepthBias() const { return slopeDepthBias; } inline float getSlopeDepthBias() const { return slopeDepthBias; }
inline float getDepthBiasClamp() const { return depthBiasClamp; } inline float getDepthBiasClamp() const { return depthBiasClamp; }
inline float getMinDepthBounds() const { return minDepthBounds; }
inline float getMaxDepthBounds() const { return maxDepthBounds; }
inline bool hasDepthRangeUnrestricted() const { return depthRangeUnrestricted; } inline bool hasDepthRangeUnrestricted() const { return depthRangeUnrestricted; }
// Pixel processor states // Pixel processor states
...@@ -184,6 +186,7 @@ struct GraphicsState ...@@ -184,6 +186,7 @@ struct GraphicsState
bool depthWriteActive(const Attachments &attachments) const; bool depthWriteActive(const Attachments &attachments) const;
bool depthBufferActive(const Attachments &attachments) const; bool depthBufferActive(const Attachments &attachments) const;
bool stencilActive(const Attachments &attachments) const; bool stencilActive(const Attachments &attachments) const;
bool depthBoundsTestActive() const;
private: private:
inline bool hasDynamicState(VkDynamicState dynamicState) const { return (dynamicStateFlags & (1 << dynamicState)) != 0; } inline bool hasDynamicState(VkDynamicState dynamicState) const { return (dynamicStateFlags & (1 << dynamicState)) != 0; }
...@@ -219,6 +222,8 @@ private: ...@@ -219,6 +222,8 @@ private:
float constantDepthBias; float constantDepthBias;
float slopeDepthBias; float slopeDepthBias;
float depthBiasClamp; float depthBiasClamp;
float minDepthBounds;
float maxDepthBounds;
bool depthRangeUnrestricted; bool depthRangeUnrestricted;
// Pixel processor states // Pixel processor states
......
...@@ -123,6 +123,10 @@ const PixelProcessor::State PixelProcessor::update(const vk::GraphicsState &pipe ...@@ -123,6 +123,10 @@ const PixelProcessor::State PixelProcessor::update(const vk::GraphicsState &pipe
state.depthClamp = !state.depthFormat.isFloatFormat() || !pipelineState.hasDepthRangeUnrestricted(); state.depthClamp = !state.depthFormat.isFloatFormat() || !pipelineState.hasDepthRangeUnrestricted();
} }
state.depthBoundsTestActive = pipelineState.depthBoundsTestActive();
state.minDepthBounds = pipelineState.getMinDepthBounds();
state.maxDepthBounds = pipelineState.getMaxDepthBounds();
state.occlusionEnabled = occlusionEnabled; state.occlusionEnabled = occlusionEnabled;
bool fragmentContainsKill = (fragmentShader && fragmentShader->getModes().ContainsKill); bool fragmentContainsKill = (fragmentShader && fragmentShader->getModes().ContainsKill);
......
...@@ -77,6 +77,7 @@ public: ...@@ -77,6 +77,7 @@ public:
StencilOpState backStencil; StencilOpState backStencil;
bool depthTestActive; bool depthTestActive;
bool depthBoundsTestActive;
bool occlusionEnabled; bool occlusionEnabled;
bool perspective; bool perspective;
...@@ -91,6 +92,8 @@ public: ...@@ -91,6 +92,8 @@ public:
bool centroid; bool centroid;
bool sampleShadingEnabled; bool sampleShadingEnabled;
float minSampleShading; float minSampleShading;
float minDepthBounds;
float maxDepthBounds;
VkFrontFace frontFace; VkFrontFace frontFace;
vk::Format depthFormat; vk::Format depthFormat;
bool depthBias; bool depthBias;
......
...@@ -83,7 +83,7 @@ void QuadRasterizer::rasterize(Int &yMin, Int &yMax) ...@@ -83,7 +83,7 @@ void QuadRasterizer::rasterize(Int &yMin, Int &yMax)
} }
} }
if(state.depthTestActive) if(state.depthTestActive || state.depthBoundsTestActive)
{ {
zBuffer = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData, depthBuffer)) + yMin * *Pointer<Int>(data + OFFSET(DrawData, depthPitchB)); zBuffer = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData, depthBuffer)) + yMin * *Pointer<Int>(data + OFFSET(DrawData, depthPitchB));
} }
...@@ -216,7 +216,7 @@ void QuadRasterizer::rasterize(Int &yMin, Int &yMax) ...@@ -216,7 +216,7 @@ void QuadRasterizer::rasterize(Int &yMin, Int &yMax)
} }
} }
if(state.depthTestActive) if(state.depthTestActive || state.depthBoundsTestActive)
{ {
zBuffer += *Pointer<Int>(data + OFFSET(DrawData, depthPitchB)) << (1 + clusterCountLog2); // FIXME: Precompute zBuffer += *Pointer<Int>(data + OFFSET(DrawData, depthPitchB)) << (1 + clusterCountLog2); // FIXME: Precompute
} }
......
...@@ -141,6 +141,7 @@ void PixelRoutine::quad(Pointer<Byte> cBuffer[RENDERTARGETS], Pointer<Byte> &zBu ...@@ -141,6 +141,7 @@ void PixelRoutine::quad(Pointer<Byte> cBuffer[RENDERTARGETS], Pointer<Byte> &zBu
for(unsigned int q = sampleLoopInit; q < sampleLoopEnd; q++) for(unsigned int q = sampleLoopInit; q < sampleLoopEnd; q++)
{ {
depthPass = depthPass || depthTest(zBuffer, q, x, z[q], sMask[q], zMask[q], cMask[q]); depthPass = depthPass || depthTest(zBuffer, q, x, z[q], sMask[q], zMask[q], cMask[q]);
depthBoundsTest(zBuffer, q, x, zMask[q], cMask[q]);
} }
} }
...@@ -307,6 +308,7 @@ void PixelRoutine::quad(Pointer<Byte> cBuffer[RENDERTARGETS], Pointer<Byte> &zBu ...@@ -307,6 +308,7 @@ void PixelRoutine::quad(Pointer<Byte> cBuffer[RENDERTARGETS], Pointer<Byte> &zBu
for(unsigned int q = sampleLoopInit; q < sampleLoopEnd; q++) for(unsigned int q = sampleLoopInit; q < sampleLoopEnd; q++)
{ {
depthPass = depthPass || depthTest(zBuffer, q, x, z[q], sMask[q], zMask[q], cMask[q]); depthPass = depthPass || depthTest(zBuffer, q, x, z[q], sMask[q], zMask[q], cMask[q]);
depthBoundsTest(zBuffer, q, x, zMask[q], cMask[q]);
} }
} }
...@@ -604,6 +606,58 @@ Bool PixelRoutine::depthTest(const Pointer<Byte> &zBuffer, int q, const Int &x, ...@@ -604,6 +606,58 @@ Bool PixelRoutine::depthTest(const Pointer<Byte> &zBuffer, int q, const Int &x,
} }
} }
Int4 PixelRoutine::depthBoundsTest16(const Pointer<Byte> &zBuffer, int q, const Int &x)
{
Pointer<Byte> buffer = zBuffer + 2 * x;
Int pitch = *Pointer<Int>(data + OFFSET(DrawData, depthPitchB));
if(q > 0)
{
buffer += q * *Pointer<Int>(data + OFFSET(DrawData, depthSliceB));
}
Float4 minDepthBound(state.minDepthBounds);
Float4 maxDepthBound(state.maxDepthBounds);
Int2 z;
z = Insert(z, *Pointer<Int>(buffer), 0);
z = Insert(z, *Pointer<Int>(buffer + pitch), 1);
Float4 zValue = convertFloat32(As<UShort4>(z));
return Int4(CmpLE(minDepthBound, zValue) & CmpLE(zValue, maxDepthBound));
}
Int4 PixelRoutine::depthBoundsTest32F(const Pointer<Byte> &zBuffer, int q, const Int &x)
{
Pointer<Byte> buffer = zBuffer + 4 * x;
Int pitch = *Pointer<Int>(data + OFFSET(DrawData, depthPitchB));
if(q > 0)
{
buffer += q * *Pointer<Int>(data + OFFSET(DrawData, depthSliceB));
}
Float4 zValue = Float4(*Pointer<Float2>(buffer), *Pointer<Float2>(buffer + pitch));
return Int4(CmpLE(Float4(state.minDepthBounds), zValue) & CmpLE(zValue, Float4(state.maxDepthBounds)));
}
void PixelRoutine::depthBoundsTest(const Pointer<Byte> &zBuffer, int q, const Int &x, Int &zMask, Int &cMask)
{
if(state.depthBoundsTestActive)
{
Int4 zTest = (state.depthFormat == VK_FORMAT_D16_UNORM) ? depthBoundsTest16(zBuffer, q, x) : depthBoundsTest32F(zBuffer, q, x);
if(!state.depthTestActive)
{
cMask &= zMask & SignMask(zTest);
}
else
{
zMask &= cMask & SignMask(zTest);
}
}
}
void PixelRoutine::alphaToCoverage(Int cMask[4], const Float4 &alpha, int sampleId) void PixelRoutine::alphaToCoverage(Int cMask[4], const Float4 &alpha, int sampleId)
{ {
static const int a2c[4] = { static const int a2c[4] = {
...@@ -2788,6 +2842,11 @@ UShort4 PixelRoutine::convertFixed16(const Float4 &cf, bool saturate) ...@@ -2788,6 +2842,11 @@ UShort4 PixelRoutine::convertFixed16(const Float4 &cf, bool saturate)
return UShort4(cf * Float4(0xFFFF), saturate); return UShort4(cf * Float4(0xFFFF), saturate);
} }
Float4 PixelRoutine::convertFloat32(const UShort4 &cf)
{
return Float4(cf) * Float4(1.0f / 65535.0f);
}
void PixelRoutine::sRGBtoLinear16_12_16(Vector4s &c) void PixelRoutine::sRGBtoLinear16_12_16(Vector4s &c)
{ {
Pointer<Byte> LUT = constants + OFFSET(Constants, sRGBtoLinear12_16); Pointer<Byte> LUT = constants + OFFSET(Constants, sRGBtoLinear12_16);
......
...@@ -63,6 +63,7 @@ protected: ...@@ -63,6 +63,7 @@ protected:
bool isSRGB(int index) const; bool isSRGB(int index) const;
UShort4 convertFixed16(const Float4 &cf, bool saturate = true); UShort4 convertFixed16(const Float4 &cf, bool saturate = true);
Float4 convertFloat32(const UShort4 &cf);
void linearToSRGB12_16(Vector4s &c); void linearToSRGB12_16(Vector4s &c);
private: private:
...@@ -72,6 +73,7 @@ private: ...@@ -72,6 +73,7 @@ private:
void stencilOperation(Byte8 &newValue, const Byte8 &bufferValue, const PixelProcessor::States::StencilOpState &ops, bool isBack, const Int &zMask, const Int &sMask); void stencilOperation(Byte8 &newValue, const Byte8 &bufferValue, const PixelProcessor::States::StencilOpState &ops, bool isBack, const Int &zMask, const Int &sMask);
void stencilOperation(Byte8 &output, const Byte8 &bufferValue, VkStencilOp operation, bool isBack); void stencilOperation(Byte8 &output, const Byte8 &bufferValue, VkStencilOp operation, bool isBack);
Bool depthTest(const Pointer<Byte> &zBuffer, int q, const Int &x, const Float4 &z, const Int &sMask, Int &zMask, const Int &cMask); Bool depthTest(const Pointer<Byte> &zBuffer, int q, const Int &x, const Float4 &z, const Int &sMask, Int &zMask, const Int &cMask);
void depthBoundsTest(const Pointer<Byte> &zBuffer, int q, const Int &x, Int &zMask, Int &cMask);
// Raster operations // Raster operations
void blendFactor(Vector4s &blendFactor, const Vector4s &current, const Vector4s &pixel, VkBlendFactor blendFactorActive); void blendFactor(Vector4s &blendFactor, const Vector4s &current, const Vector4s &pixel, VkBlendFactor blendFactorActive);
...@@ -91,6 +93,9 @@ private: ...@@ -91,6 +93,9 @@ private:
void writeDepth32F(Pointer<Byte> &zBuffer, int q, const Int &x, const Float4 &z, const Int &zMask); void writeDepth32F(Pointer<Byte> &zBuffer, int q, const Int &x, const Float4 &z, const Int &zMask);
void writeDepth16(Pointer<Byte> &zBuffer, int q, const Int &x, const Float4 &z, const Int &zMask); void writeDepth16(Pointer<Byte> &zBuffer, int q, const Int &x, const Float4 &z, const Int &zMask);
Int4 depthBoundsTest32F(const Pointer<Byte> &zBuffer, int q, const Int &x);
Int4 depthBoundsTest16(const Pointer<Byte> &zBuffer, int q, const Int &x);
}; };
} // namespace sw } // namespace sw
......
...@@ -62,6 +62,7 @@ namespace sw ...@@ -62,6 +62,7 @@ namespace sw
bool stencilWriteMaskedCCW : 1; bool stencilWriteMaskedCCW : 1;
bool depthTestActive : 1; bool depthTestActive : 1;
bool depthBoundsTestActive : 1;
bool fogActive : 1; bool fogActive : 1;
FogMode pixelFogMode : BITS(FOG_LAST); FogMode pixelFogMode : BITS(FOG_LAST);
bool specularAdd : 1; bool specularAdd : 1;
......
...@@ -49,7 +49,7 @@ const VkPhysicalDeviceFeatures &PhysicalDevice::getFeatures() const ...@@ -49,7 +49,7 @@ const VkPhysicalDeviceFeatures &PhysicalDevice::getFeatures() const
VK_FALSE, // depthClamp VK_FALSE, // depthClamp
VK_TRUE, // depthBiasClamp VK_TRUE, // depthBiasClamp
VK_TRUE, // fillModeNonSolid VK_TRUE, // fillModeNonSolid
VK_FALSE, // depthBounds VK_TRUE, // depthBounds
VK_FALSE, // wideLines VK_FALSE, // wideLines
VK_TRUE, // largePoints VK_TRUE, // largePoints
VK_FALSE, // alphaToOne VK_FALSE, // alphaToOne
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment