Implement VK_EXT_depth_clip_enable

Normally the vertex processor will clip geometry that's outside of the near and far planes. However, when depthClamp is enabled, depth clipping must be disabled. So this change also enables the extension that allows users to explicitly control depth clipping. Bug: b/185814882 Tests: dEQP-VK.clipping.clip_volume.depth_clip.* Change-Id: Iaab31c17cac382cf55a8c50d8e7e7d4c87b55272 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/53968 Presubmit-Ready: Alexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Commit-Queue: Sean Risser <srisser@google.com> Tested-by: 's avatarSean Risser <srisser@google.com>
parent f6afa763
...@@ -261,14 +261,15 @@ void clipBottom(sw::Polygon &polygon) ...@@ -261,14 +261,15 @@ void clipBottom(sw::Polygon &polygon)
namespace sw { namespace sw {
unsigned int Clipper::ComputeClipFlags(const float4 &v) unsigned int Clipper::ComputeClipFlags(const float4 &v, bool depthClipEnable)
{ {
int depthClipFlags = ((v.z > v.w) ? CLIP_FAR : 0) |
((v.z < 0) ? CLIP_NEAR : 0);
return ((v.x > v.w) ? CLIP_RIGHT : 0) | return ((v.x > v.w) ? CLIP_RIGHT : 0) |
((v.y > v.w) ? CLIP_TOP : 0) | ((v.y > v.w) ? CLIP_TOP : 0) |
((v.z > v.w) ? CLIP_FAR : 0) |
((v.x < -v.w) ? CLIP_LEFT : 0) | ((v.x < -v.w) ? CLIP_LEFT : 0) |
((v.y < -v.w) ? CLIP_BOTTOM : 0) | ((v.y < -v.w) ? CLIP_BOTTOM : 0) |
((v.z < 0) ? CLIP_NEAR : 0) | (depthClipEnable ? depthClipFlags : 0) |
Clipper::CLIP_FINITE; // FIXME: xyz finite Clipper::CLIP_FINITE; // FIXME: xyz finite
} }
......
...@@ -39,7 +39,7 @@ struct Clipper ...@@ -39,7 +39,7 @@ struct Clipper
CLIP_FINITE = 1 << 7, // All position coordinates are finite CLIP_FINITE = 1 << 7, // All position coordinates are finite
}; };
static unsigned int ComputeClipFlags(const float4 &v); static unsigned int ComputeClipFlags(const float4 &v, bool depthClipEnable);
static bool Clip(Polygon &polygon, int clipFlagsOr, const DrawCall &draw); static bool Clip(Polygon &polygon, int clipFlagsOr, const DrawCall &draw);
}; };
......
...@@ -324,6 +324,8 @@ GraphicsState::GraphicsState(const Device *device, const VkGraphicsPipelineCreat ...@@ -324,6 +324,8 @@ GraphicsState::GraphicsState(const Device *device, const VkGraphicsPipelineCreat
slopeDepthBias = (rasterizationState->depthBiasEnable != VK_FALSE) ? rasterizationState->depthBiasSlopeFactor : 0.0f; slopeDepthBias = (rasterizationState->depthBiasEnable != VK_FALSE) ? rasterizationState->depthBiasSlopeFactor : 0.0f;
depthBiasClamp = (rasterizationState->depthBiasEnable != VK_FALSE) ? rasterizationState->depthBiasClamp : 0.0f; depthBiasClamp = (rasterizationState->depthBiasEnable != VK_FALSE) ? rasterizationState->depthBiasClamp : 0.0f;
depthRangeUnrestricted = device->hasExtension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME); depthRangeUnrestricted = device->hasExtension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME);
depthClampEnable = rasterizationState->depthClampEnable != VK_FALSE;
depthClipEnable = !depthClampEnable;
// From the Vulkan spec for vkCmdSetDepthBias: // From the Vulkan spec for vkCmdSetDepthBias:
// The bias value O for a polygon is: // The bias value O for a polygon is:
...@@ -361,6 +363,14 @@ GraphicsState::GraphicsState(const Device *device, const VkGraphicsPipelineCreat ...@@ -361,6 +363,14 @@ GraphicsState::GraphicsState(const Device *device, const VkGraphicsPipelineCreat
provokingVertexMode = provokingVertexModeCreateInfo->provokingVertexMode; provokingVertexMode = provokingVertexModeCreateInfo->provokingVertexMode;
} }
break; break;
case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT:
{
const auto *depthClipInfo = reinterpret_cast<const VkPipelineRasterizationDepthClipStateCreateInfoEXT *>(extensionCreateInfo);
// Reserved for future use.
ASSERT(depthClipInfo->flags == 0);
depthClipEnable = depthClipInfo->depthClipEnable != VK_FALSE;
}
break;
default: default:
WARN("pCreateInfo->pRasterizationState->pNext sType = %s", vk::Stringify(extensionCreateInfo->sType).c_str()); WARN("pCreateInfo->pRasterizationState->pNext sType = %s", vk::Stringify(extensionCreateInfo->sType).c_str());
break; break;
......
...@@ -158,6 +158,8 @@ struct GraphicsState ...@@ -158,6 +158,8 @@ struct GraphicsState
inline float getMinDepthBounds() const { return minDepthBounds; } inline float getMinDepthBounds() const { return minDepthBounds; }
inline float getMaxDepthBounds() const { return maxDepthBounds; } inline float getMaxDepthBounds() const { return maxDepthBounds; }
inline bool hasDepthRangeUnrestricted() const { return depthRangeUnrestricted; } inline bool hasDepthRangeUnrestricted() const { return depthRangeUnrestricted; }
inline bool getDepthClampEnable() const { return depthClampEnable; }
inline bool getDepthClipEnable() const { return depthClipEnable; }
// Pixel processor states // Pixel processor states
inline bool hasRasterizerDiscard() const { return rasterizerDiscard; } inline bool hasRasterizerDiscard() const { return rasterizerDiscard; }
...@@ -232,6 +234,8 @@ private: ...@@ -232,6 +234,8 @@ private:
bool depthBufferEnable; bool depthBufferEnable;
VkCompareOp depthCompareMode; VkCompareOp depthCompareMode;
bool depthWriteEnable; bool depthWriteEnable;
bool depthClampEnable;
bool depthClipEnable;
float lineWidth; float lineWidth;
......
...@@ -267,6 +267,7 @@ void Renderer::draw(const vk::GraphicsPipeline *pipeline, const vk::DynamicState ...@@ -267,6 +267,7 @@ void Renderer::draw(const vk::GraphicsPipeline *pipeline, const vk::DynamicState
draw->lineRasterizationMode = pipelineState.getLineRasterizationMode(); draw->lineRasterizationMode = pipelineState.getLineRasterizationMode();
draw->descriptorSetObjects = inputs.getDescriptorSetObjects(); draw->descriptorSetObjects = inputs.getDescriptorSetObjects();
draw->pipelineLayout = pipelineState.getPipelineLayout(); draw->pipelineLayout = pipelineState.getPipelineLayout();
draw->depthClipEnable = pipelineState.getDepthClipEnable();
draw->vertexRoutine = vertexRoutine; draw->vertexRoutine = vertexRoutine;
draw->setupRoutine = setupRoutine; draw->setupRoutine = setupRoutine;
...@@ -355,6 +356,7 @@ void Renderer::draw(const vk::GraphicsPipeline *pipeline, const vk::DynamicState ...@@ -355,6 +356,7 @@ void Renderer::draw(const vk::GraphicsPipeline *pipeline, const vk::DynamicState
data->constantDepthBias = pipelineState.getConstantDepthBias(); data->constantDepthBias = pipelineState.getConstantDepthBias();
data->slopeDepthBias = pipelineState.getSlopeDepthBias(); data->slopeDepthBias = pipelineState.getSlopeDepthBias();
data->depthBiasClamp = pipelineState.getDepthBiasClamp(); data->depthBiasClamp = pipelineState.getDepthBiasClamp();
data->depthClipEnable = pipelineState.getDepthClipEnable();
const vk::Attachments attachments = pipeline->getAttachments(); const vk::Attachments attachments = pipeline->getAttachments();
if(attachments.depthBuffer) if(attachments.depthBuffer)
...@@ -901,19 +903,19 @@ bool DrawCall::setupLine(Primitive &primitive, Triangle &triangle, const DrawCal ...@@ -901,19 +903,19 @@ bool DrawCall::setupLine(Primitive &primitive, Triangle &triangle, const DrawCal
P[0].x += -dy0w; P[0].x += -dy0w;
P[0].y += +dx0h; P[0].y += +dx0h;
C[0] = Clipper::ComputeClipFlags(P[0]); C[0] = Clipper::ComputeClipFlags(P[0], draw.depthClipEnable);
P[1].x += -dy1w; P[1].x += -dy1w;
P[1].y += +dx1h; P[1].y += +dx1h;
C[1] = Clipper::ComputeClipFlags(P[1]); C[1] = Clipper::ComputeClipFlags(P[1], draw.depthClipEnable);
P[2].x += +dy1w; P[2].x += +dy1w;
P[2].y += -dx1h; P[2].y += -dx1h;
C[2] = Clipper::ComputeClipFlags(P[2]); C[2] = Clipper::ComputeClipFlags(P[2], draw.depthClipEnable);
P[3].x += +dy0w; P[3].x += +dy0w;
P[3].y += -dx0h; P[3].y += -dx0h;
C[3] = Clipper::ComputeClipFlags(P[3]); C[3] = Clipper::ComputeClipFlags(P[3], draw.depthClipEnable);
if((C[0] & C[1] & C[2] & C[3]) == Clipper::CLIP_FINITE) if((C[0] & C[1] & C[2] & C[3]) == Clipper::CLIP_FINITE)
{ {
...@@ -958,28 +960,28 @@ bool DrawCall::setupLine(Primitive &primitive, Triangle &triangle, const DrawCal ...@@ -958,28 +960,28 @@ bool DrawCall::setupLine(Primitive &primitive, Triangle &triangle, const DrawCal
float dy1 = lineWidth * 0.5f * P1.w / H; float dy1 = lineWidth * 0.5f * P1.w / H;
P[0].x += -dx0; P[0].x += -dx0;
C[0] = Clipper::ComputeClipFlags(P[0]); C[0] = Clipper::ComputeClipFlags(P[0], draw.depthClipEnable);
P[1].y += +dy0; P[1].y += +dy0;
C[1] = Clipper::ComputeClipFlags(P[1]); C[1] = Clipper::ComputeClipFlags(P[1], draw.depthClipEnable);
P[2].x += +dx0; P[2].x += +dx0;
C[2] = Clipper::ComputeClipFlags(P[2]); C[2] = Clipper::ComputeClipFlags(P[2], draw.depthClipEnable);
P[3].y += -dy0; P[3].y += -dy0;
C[3] = Clipper::ComputeClipFlags(P[3]); C[3] = Clipper::ComputeClipFlags(P[3], draw.depthClipEnable);
P[4].x += -dx1; P[4].x += -dx1;
C[4] = Clipper::ComputeClipFlags(P[4]); C[4] = Clipper::ComputeClipFlags(P[4], draw.depthClipEnable);
P[5].y += +dy1; P[5].y += +dy1;
C[5] = Clipper::ComputeClipFlags(P[5]); C[5] = Clipper::ComputeClipFlags(P[5], draw.depthClipEnable);
P[6].x += +dx1; P[6].x += +dx1;
C[6] = Clipper::ComputeClipFlags(P[6]); C[6] = Clipper::ComputeClipFlags(P[6], draw.depthClipEnable);
P[7].y += -dy1; P[7].y += -dy1;
C[7] = Clipper::ComputeClipFlags(P[7]); C[7] = Clipper::ComputeClipFlags(P[7], draw.depthClipEnable);
if((C[0] & C[1] & C[2] & C[3] & C[4] & C[5] & C[6] & C[7]) == Clipper::CLIP_FINITE) if((C[0] & C[1] & C[2] & C[3] & C[4] & C[5] & C[6] & C[7]) == Clipper::CLIP_FINITE)
{ {
...@@ -1112,10 +1114,10 @@ bool DrawCall::setupLine(Primitive &primitive, Triangle &triangle, const DrawCal ...@@ -1112,10 +1114,10 @@ bool DrawCall::setupLine(Primitive &primitive, Triangle &triangle, const DrawCal
} }
} }
int C0 = Clipper::ComputeClipFlags(L[0]); int C0 = Clipper::ComputeClipFlags(L[0], draw.depthClipEnable);
int C1 = Clipper::ComputeClipFlags(L[1]); int C1 = Clipper::ComputeClipFlags(L[1], draw.depthClipEnable);
int C2 = Clipper::ComputeClipFlags(L[2]); int C2 = Clipper::ComputeClipFlags(L[2], draw.depthClipEnable);
int C3 = Clipper::ComputeClipFlags(L[3]); int C3 = Clipper::ComputeClipFlags(L[3], draw.depthClipEnable);
if((C0 & C1 & C2 & C3) == Clipper::CLIP_FINITE) if((C0 & C1 & C2 & C3) == Clipper::CLIP_FINITE)
{ {
...@@ -1166,19 +1168,19 @@ bool DrawCall::setupPoint(Primitive &primitive, Triangle &triangle, const DrawCa ...@@ -1166,19 +1168,19 @@ bool DrawCall::setupPoint(Primitive &primitive, Triangle &triangle, const DrawCa
P[0].x -= X; P[0].x -= X;
P[0].y += Y; P[0].y += Y;
C[0] = Clipper::ComputeClipFlags(P[0]); C[0] = Clipper::ComputeClipFlags(P[0], draw.depthClipEnable);
P[1].x += X; P[1].x += X;
P[1].y += Y; P[1].y += Y;
C[1] = Clipper::ComputeClipFlags(P[1]); C[1] = Clipper::ComputeClipFlags(P[1], draw.depthClipEnable);
P[2].x += X; P[2].x += X;
P[2].y -= Y; P[2].y -= Y;
C[2] = Clipper::ComputeClipFlags(P[2]); C[2] = Clipper::ComputeClipFlags(P[2], draw.depthClipEnable);
P[3].x -= X; P[3].x -= X;
P[3].y -= Y; P[3].y -= Y;
C[3] = Clipper::ComputeClipFlags(P[3]); C[3] = Clipper::ComputeClipFlags(P[3], draw.depthClipEnable);
Polygon polygon(P, 4); Polygon polygon(P, 4);
......
...@@ -93,6 +93,7 @@ struct DrawData ...@@ -93,6 +93,7 @@ struct DrawData
float constantDepthBias; float constantDepthBias;
float slopeDepthBias; float slopeDepthBias;
float depthBiasClamp; float depthBiasClamp;
bool depthClipEnable;
unsigned int *colorBuffer[RENDERTARGETS]; unsigned int *colorBuffer[RENDERTARGETS];
int colorPitchB[RENDERTARGETS]; int colorPitchB[RENDERTARGETS];
...@@ -158,6 +159,8 @@ struct DrawCall ...@@ -158,6 +159,8 @@ struct DrawCall
VkIndexType indexType; VkIndexType indexType;
VkLineRasterizationModeEXT lineRasterizationMode; VkLineRasterizationModeEXT lineRasterizationMode;
bool depthClipEnable;
VertexProcessor::RoutineType vertexRoutine; VertexProcessor::RoutineType vertexRoutine;
SetupProcessor::RoutineType setupRoutine; SetupProcessor::RoutineType setupRoutine;
PixelProcessor::RoutineType pixelRoutine; PixelProcessor::RoutineType pixelRoutine;
......
...@@ -73,6 +73,7 @@ const VertexProcessor::State VertexProcessor::update(const vk::GraphicsState &pi ...@@ -73,6 +73,7 @@ const VertexProcessor::State VertexProcessor::update(const vk::GraphicsState &pi
state.pipelineLayoutIdentifier = pipelineState.getPipelineLayout()->identifier; state.pipelineLayoutIdentifier = pipelineState.getPipelineLayout()->identifier;
state.robustBufferAccess = pipelineState.getRobustBufferAccess(); state.robustBufferAccess = pipelineState.getRobustBufferAccess();
state.isPoint = pipelineState.getTopology() == VK_PRIMITIVE_TOPOLOGY_POINT_LIST; state.isPoint = pipelineState.getTopology() == VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
state.depthClipEnable = pipelineState.getDepthClipEnable();
for(size_t i = 0; i < MAX_INTERFACE_COMPONENTS / 4; i++) for(size_t i = 0; i < MAX_INTERFACE_COMPONENTS / 4; i++)
{ {
......
...@@ -81,6 +81,7 @@ public: ...@@ -81,6 +81,7 @@ public:
Input input[MAX_INTERFACE_COMPONENTS / 4]; Input input[MAX_INTERFACE_COMPONENTS / 4];
bool robustBufferAccess : 1; bool robustBufferAccess : 1;
bool isPoint : 1; bool isPoint : 1;
bool depthClipEnable : 1;
}; };
struct State : States struct State : States
......
...@@ -125,17 +125,20 @@ void VertexRoutine::computeClipFlags() ...@@ -125,17 +125,20 @@ void VertexRoutine::computeClipFlags()
Int4 maxX = CmpLT(posW, posX); Int4 maxX = CmpLT(posW, posX);
Int4 maxY = CmpLT(posW, posY); Int4 maxY = CmpLT(posW, posY);
Int4 maxZ = CmpLT(posW, posZ);
Int4 minX = CmpNLE(-posW, posX); Int4 minX = CmpNLE(-posW, posX);
Int4 minY = CmpNLE(-posW, posY); Int4 minY = CmpNLE(-posW, posY);
Int4 minZ = CmpNLE(Float4(0.0f), posZ);
clipFlags = Pointer<Int>(constants + OFFSET(Constants, maxX))[SignMask(maxX)]; clipFlags = Pointer<Int>(constants + OFFSET(Constants, maxX))[SignMask(maxX)];
clipFlags |= Pointer<Int>(constants + OFFSET(Constants, maxY))[SignMask(maxY)]; clipFlags |= Pointer<Int>(constants + OFFSET(Constants, maxY))[SignMask(maxY)];
clipFlags |= Pointer<Int>(constants + OFFSET(Constants, maxZ))[SignMask(maxZ)];
clipFlags |= Pointer<Int>(constants + OFFSET(Constants, minX))[SignMask(minX)]; clipFlags |= Pointer<Int>(constants + OFFSET(Constants, minX))[SignMask(minX)];
clipFlags |= Pointer<Int>(constants + OFFSET(Constants, minY))[SignMask(minY)]; clipFlags |= Pointer<Int>(constants + OFFSET(Constants, minY))[SignMask(minY)];
if(state.depthClipEnable)
{
Int4 maxZ = CmpLT(posW, posZ);
Int4 minZ = CmpNLE(Float4(0.0f), posZ);
clipFlags |= Pointer<Int>(constants + OFFSET(Constants, maxZ))[SignMask(maxZ)];
clipFlags |= Pointer<Int>(constants + OFFSET(Constants, minZ))[SignMask(minZ)]; clipFlags |= Pointer<Int>(constants + OFFSET(Constants, minZ))[SignMask(minZ)];
}
Float4 maxPos = As<Float4>(Int4(0x7F7FFFFF)); Float4 maxPos = As<Float4>(Int4(0x7F7FFFFF));
Int4 finiteX = CmpLE(Abs(posX), maxPos); Int4 finiteX = CmpLE(Abs(posX), maxPos);
......
...@@ -319,6 +319,12 @@ static void getPhysicalDeviceVulkan12Features(T *features) ...@@ -319,6 +319,12 @@ static void getPhysicalDeviceVulkan12Features(T *features)
features->subgroupBroadcastDynamicId = VK_TRUE; features->subgroupBroadcastDynamicId = VK_TRUE;
} }
template<typename T>
static void getPhysicalDeviceDepthClipEnableFeaturesExt(T *features)
{
features->depthClipEnable = VK_TRUE;
}
void PhysicalDevice::getFeatures2(VkPhysicalDeviceFeatures2 *features) const void PhysicalDevice::getFeatures2(VkPhysicalDeviceFeatures2 *features) const
{ {
features->features = getFeatures(); features->features = getFeatures();
...@@ -405,6 +411,9 @@ void PhysicalDevice::getFeatures2(VkPhysicalDeviceFeatures2 *features) const ...@@ -405,6 +411,9 @@ void PhysicalDevice::getFeatures2(VkPhysicalDeviceFeatures2 *features) const
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES:
getPhysicalDeviceDescriptorIndexingFeatures(reinterpret_cast<VkPhysicalDeviceDescriptorIndexingFeatures *>(curExtension)); getPhysicalDeviceDescriptorIndexingFeatures(reinterpret_cast<VkPhysicalDeviceDescriptorIndexingFeatures *>(curExtension));
break; break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT:
getPhysicalDeviceDepthClipEnableFeaturesExt(reinterpret_cast<VkPhysicalDeviceDepthClipEnableFeaturesEXT *>(curExtension));
break;
default: default:
LOG_TRAP("curExtension->pNext->sType = %s", vk::Stringify(curExtension->sType).c_str()); LOG_TRAP("curExtension->pNext->sType = %s", vk::Stringify(curExtension->sType).c_str());
break; break;
......
...@@ -365,6 +365,7 @@ static const ExtensionProperties deviceExtensionProperties[] = { ...@@ -365,6 +365,7 @@ static const ExtensionProperties deviceExtensionProperties[] = {
{ { VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME, VK_KHR_RELAXED_BLOCK_LAYOUT_SPEC_VERSION } }, { { VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME, VK_KHR_RELAXED_BLOCK_LAYOUT_SPEC_VERSION } },
{ { VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION } }, { { VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION } },
{ { VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME, VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION } }, { { VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME, VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION } },
{ { VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, VK_EXT_DEPTH_CLIP_ENABLE_SPEC_VERSION} },
// Only 1.1 core version of this is supported. The extension has additional requirements // Only 1.1 core version of this is supported. The extension has additional requirements
//{{ VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION }}, //{{ VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION }},
{ { VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME, VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_SPEC_VERSION } }, { { VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME, VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_SPEC_VERSION } },
......
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