Remove depth-clamping and add depth-clip-control feature
Fixed: dawn:1178 Change-Id: I251a7e05fec9ecef44300d4f948b2d0611888109 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/96320 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
f6f3d496a8
commit
8d73198aca
12
dawn.json
12
dawn.json
|
@ -1365,7 +1365,6 @@
|
||||||
{"value": 6, "name": "texture compression ETC2"},
|
{"value": 6, "name": "texture compression ETC2"},
|
||||||
{"value": 7, "name": "texture compression ASTC"},
|
{"value": 7, "name": "texture compression ASTC"},
|
||||||
{"value": 8, "name": "indirect first instance"},
|
{"value": 8, "name": "indirect first instance"},
|
||||||
{"value": 1000, "name": "depth clamping", "tags": ["emscripten", "dawn"]},
|
|
||||||
{"value": 1001, "name": "dawn shader float 16", "tags": ["dawn"]},
|
{"value": 1001, "name": "dawn shader float 16", "tags": ["dawn"]},
|
||||||
{"value": 1002, "name": "dawn internal usages", "tags": ["dawn"]},
|
{"value": 1002, "name": "dawn internal usages", "tags": ["dawn"]},
|
||||||
{"value": 1003, "name": "dawn multi planar formats", "tags": ["dawn"]},
|
{"value": 1003, "name": "dawn multi planar formats", "tags": ["dawn"]},
|
||||||
|
@ -2150,16 +2149,6 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
"primitive depth clamping state": {
|
|
||||||
"category": "structure",
|
|
||||||
"chained": "in",
|
|
||||||
"chain roots": ["primitive state"],
|
|
||||||
"tags": ["dawn", "emscripten"],
|
|
||||||
"members": [
|
|
||||||
{"name": "clamp depth", "type": "bool", "default": "false"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
"primitive depth clip control": {
|
"primitive depth clip control": {
|
||||||
"category": "structure",
|
"category": "structure",
|
||||||
"chained": "in",
|
"chained": "in",
|
||||||
|
@ -2512,7 +2501,6 @@
|
||||||
{"value": 14, "name": "surface descriptor from windows swap chain panel", "tags": ["dawn"]},
|
{"value": 14, "name": "surface descriptor from windows swap chain panel", "tags": ["dawn"]},
|
||||||
{"value": 15, "name": "render pass descriptor max draw count"},
|
{"value": 15, "name": "render pass descriptor max draw count"},
|
||||||
{"value": 1000, "name": "dawn texture internal usage descriptor", "tags": ["dawn"]},
|
{"value": 1000, "name": "dawn texture internal usage descriptor", "tags": ["dawn"]},
|
||||||
{"value": 1001, "name": "primitive depth clamping state", "tags": ["dawn", "emscripten"]},
|
|
||||||
{"value": 1002, "name": "dawn toggles device descriptor", "tags": ["dawn", "native"]},
|
{"value": 1002, "name": "dawn toggles device descriptor", "tags": ["dawn", "native"]},
|
||||||
{"value": 1003, "name": "dawn encoder internal usage descriptor", "tags": ["dawn"]},
|
{"value": 1003, "name": "dawn encoder internal usage descriptor", "tags": ["dawn"]},
|
||||||
{"value": 1004, "name": "dawn instance descriptor", "tags": ["dawn", "native"]},
|
{"value": 1004, "name": "dawn instance descriptor", "tags": ["dawn", "native"]},
|
||||||
|
|
|
@ -58,9 +58,6 @@ static constexpr FeatureEnumAndInfoList kFeatureNameAndInfoList = {{
|
||||||
{Feature::DepthClipControl,
|
{Feature::DepthClipControl,
|
||||||
{"depth-clip-control", "Disable depth clipping of primitives to the clip volume",
|
{"depth-clip-control", "Disable depth clipping of primitives to the clip volume",
|
||||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=1178"}},
|
"https://bugs.chromium.org/p/dawn/issues/detail?id=1178"}},
|
||||||
{Feature::DepthClamping,
|
|
||||||
{"depth-clamping", "Clamp depth to [0, 1] in NDC space instead of clipping",
|
|
||||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=716"}},
|
|
||||||
{Feature::Depth32FloatStencil8,
|
{Feature::Depth32FloatStencil8,
|
||||||
{"depth32float-stencil8", "Support depth32float-stencil8 texture format",
|
{"depth32float-stencil8", "Support depth32float-stencil8 texture format",
|
||||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=690"}},
|
"https://bugs.chromium.org/p/dawn/issues/detail?id=690"}},
|
||||||
|
@ -102,8 +99,6 @@ Feature FromAPIFeature(wgpu::FeatureName feature) {
|
||||||
return Feature::TextureCompressionASTC;
|
return Feature::TextureCompressionASTC;
|
||||||
case wgpu::FeatureName::DepthClipControl:
|
case wgpu::FeatureName::DepthClipControl:
|
||||||
return Feature::DepthClipControl;
|
return Feature::DepthClipControl;
|
||||||
case wgpu::FeatureName::DepthClamping:
|
|
||||||
return Feature::DepthClamping;
|
|
||||||
case wgpu::FeatureName::Depth32FloatStencil8:
|
case wgpu::FeatureName::Depth32FloatStencil8:
|
||||||
return Feature::Depth32FloatStencil8;
|
return Feature::Depth32FloatStencil8;
|
||||||
case wgpu::FeatureName::IndirectFirstInstance:
|
case wgpu::FeatureName::IndirectFirstInstance:
|
||||||
|
@ -136,8 +131,6 @@ wgpu::FeatureName ToAPIFeature(Feature feature) {
|
||||||
return wgpu::FeatureName::TimestampQuery;
|
return wgpu::FeatureName::TimestampQuery;
|
||||||
case Feature::DepthClipControl:
|
case Feature::DepthClipControl:
|
||||||
return wgpu::FeatureName::DepthClipControl;
|
return wgpu::FeatureName::DepthClipControl;
|
||||||
case Feature::DepthClamping:
|
|
||||||
return wgpu::FeatureName::DepthClamping;
|
|
||||||
case Feature::Depth32FloatStencil8:
|
case Feature::Depth32FloatStencil8:
|
||||||
return wgpu::FeatureName::Depth32FloatStencil8;
|
return wgpu::FeatureName::Depth32FloatStencil8;
|
||||||
case Feature::IndirectFirstInstance:
|
case Feature::IndirectFirstInstance:
|
||||||
|
|
|
@ -34,7 +34,6 @@ enum class Feature {
|
||||||
PipelineStatisticsQuery,
|
PipelineStatisticsQuery,
|
||||||
TimestampQuery,
|
TimestampQuery,
|
||||||
DepthClipControl,
|
DepthClipControl,
|
||||||
DepthClamping,
|
|
||||||
Depth32FloatStencil8,
|
Depth32FloatStencil8,
|
||||||
ChromiumExperimentalDp4a,
|
ChromiumExperimentalDp4a,
|
||||||
IndirectFirstInstance,
|
IndirectFirstInstance,
|
||||||
|
|
|
@ -153,12 +153,7 @@ MaybeError ValidateVertexState(DeviceBase* device,
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError ValidatePrimitiveState(const DeviceBase* device, const PrimitiveState* descriptor) {
|
MaybeError ValidatePrimitiveState(const DeviceBase* device, const PrimitiveState* descriptor) {
|
||||||
DAWN_TRY(ValidateSingleSType(descriptor->nextInChain, wgpu::SType::PrimitiveDepthClampingState,
|
DAWN_TRY(ValidateSingleSType(descriptor->nextInChain, wgpu::SType::PrimitiveDepthClipControl));
|
||||||
wgpu::SType::PrimitiveDepthClipControl));
|
|
||||||
const PrimitiveDepthClampingState* clampInfo = nullptr;
|
|
||||||
FindInChain(descriptor->nextInChain, &clampInfo);
|
|
||||||
DAWN_INVALID_IF(clampInfo && !device->IsFeatureEnabled(Feature::DepthClamping),
|
|
||||||
"%s is not supported", wgpu::FeatureName::DepthClamping);
|
|
||||||
const PrimitiveDepthClipControl* depthClipControl = nullptr;
|
const PrimitiveDepthClipControl* depthClipControl = nullptr;
|
||||||
FindInChain(descriptor->nextInChain, &depthClipControl);
|
FindInChain(descriptor->nextInChain, &depthClipControl);
|
||||||
DAWN_INVALID_IF(depthClipControl && !device->IsFeatureEnabled(Feature::DepthClipControl),
|
DAWN_INVALID_IF(depthClipControl && !device->IsFeatureEnabled(Feature::DepthClipControl),
|
||||||
|
@ -564,11 +559,12 @@ RenderPipelineBase::RenderPipelineBase(DeviceBase* device,
|
||||||
}
|
}
|
||||||
|
|
||||||
mPrimitive = descriptor->primitive;
|
mPrimitive = descriptor->primitive;
|
||||||
const PrimitiveDepthClampingState* clampInfo = nullptr;
|
const PrimitiveDepthClipControl* depthClipControl = nullptr;
|
||||||
FindInChain(mPrimitive.nextInChain, &clampInfo);
|
FindInChain(mPrimitive.nextInChain, &depthClipControl);
|
||||||
if (clampInfo) {
|
if (depthClipControl) {
|
||||||
mClampDepth = clampInfo->clampDepth;
|
mUnclippedDepth = depthClipControl->unclippedDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
mMultisample = descriptor->multisample;
|
mMultisample = descriptor->multisample;
|
||||||
|
|
||||||
if (mAttachmentState->HasDepthStencilAttachment()) {
|
if (mAttachmentState->HasDepthStencilAttachment()) {
|
||||||
|
@ -763,9 +759,9 @@ float RenderPipelineBase::GetDepthBiasClamp() const {
|
||||||
return mDepthStencil.depthBiasClamp;
|
return mDepthStencil.depthBiasClamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderPipelineBase::ShouldClampDepth() const {
|
bool RenderPipelineBase::HasUnclippedDepth() const {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
return mClampDepth;
|
return mUnclippedDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments>
|
ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments>
|
||||||
|
@ -872,7 +868,7 @@ size_t RenderPipelineBase::ComputeContentHash() {
|
||||||
|
|
||||||
// Record primitive state
|
// Record primitive state
|
||||||
recorder.Record(mPrimitive.topology, mPrimitive.stripIndexFormat, mPrimitive.frontFace,
|
recorder.Record(mPrimitive.topology, mPrimitive.stripIndexFormat, mPrimitive.frontFace,
|
||||||
mPrimitive.cullMode, mClampDepth);
|
mPrimitive.cullMode, mUnclippedDepth);
|
||||||
|
|
||||||
// Record multisample state
|
// Record multisample state
|
||||||
// Sample count hashed as part of the attachment state
|
// Sample count hashed as part of the attachment state
|
||||||
|
@ -989,7 +985,7 @@ bool RenderPipelineBase::EqualityFunc::operator()(const RenderPipelineBase* a,
|
||||||
if (stateA.topology != stateB.topology ||
|
if (stateA.topology != stateB.topology ||
|
||||||
stateA.stripIndexFormat != stateB.stripIndexFormat ||
|
stateA.stripIndexFormat != stateB.stripIndexFormat ||
|
||||||
stateA.frontFace != stateB.frontFace || stateA.cullMode != stateB.cullMode ||
|
stateA.frontFace != stateB.frontFace || stateA.cullMode != stateB.cullMode ||
|
||||||
a->mClampDepth != b->mClampDepth) {
|
a->mUnclippedDepth != b->mUnclippedDepth) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ class RenderPipelineBase : public PipelineBase {
|
||||||
int32_t GetDepthBias() const;
|
int32_t GetDepthBias() const;
|
||||||
float GetDepthBiasSlopeScale() const;
|
float GetDepthBiasSlopeScale() const;
|
||||||
float GetDepthBiasClamp() const;
|
float GetDepthBiasClamp() const;
|
||||||
bool ShouldClampDepth() const;
|
bool HasUnclippedDepth() const;
|
||||||
|
|
||||||
ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments> GetColorAttachmentsMask() const;
|
ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments> GetColorAttachmentsMask() const;
|
||||||
bool HasDepthStencilAttachment() const;
|
bool HasDepthStencilAttachment() const;
|
||||||
|
@ -137,7 +137,7 @@ class RenderPipelineBase : public PipelineBase {
|
||||||
PrimitiveState mPrimitive;
|
PrimitiveState mPrimitive;
|
||||||
DepthStencilState mDepthStencil;
|
DepthStencilState mDepthStencil;
|
||||||
MultisampleState mMultisample;
|
MultisampleState mMultisample;
|
||||||
bool mClampDepth = false;
|
bool mUnclippedDepth = false;
|
||||||
bool mWritesDepth = false;
|
bool mWritesDepth = false;
|
||||||
bool mWritesStencil = false;
|
bool mWritesStencil = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -389,7 +389,7 @@ MaybeError RenderPipeline::Initialize() {
|
||||||
descriptorD3D12.RasterizerState.DepthBias = GetDepthBias();
|
descriptorD3D12.RasterizerState.DepthBias = GetDepthBias();
|
||||||
descriptorD3D12.RasterizerState.DepthBiasClamp = GetDepthBiasClamp();
|
descriptorD3D12.RasterizerState.DepthBiasClamp = GetDepthBiasClamp();
|
||||||
descriptorD3D12.RasterizerState.SlopeScaledDepthBias = GetDepthBiasSlopeScale();
|
descriptorD3D12.RasterizerState.SlopeScaledDepthBias = GetDepthBiasSlopeScale();
|
||||||
descriptorD3D12.RasterizerState.DepthClipEnable = TRUE;
|
descriptorD3D12.RasterizerState.DepthClipEnable = !HasUnclippedDepth();
|
||||||
descriptorD3D12.RasterizerState.MultisampleEnable = (GetSampleCount() > 1) ? TRUE : FALSE;
|
descriptorD3D12.RasterizerState.MultisampleEnable = (GetSampleCount() > 1) ? TRUE : FALSE;
|
||||||
descriptorD3D12.RasterizerState.AntialiasedLineEnable = FALSE;
|
descriptorD3D12.RasterizerState.AntialiasedLineEnable = FALSE;
|
||||||
descriptorD3D12.RasterizerState.ForcedSampleCount = 0;
|
descriptorD3D12.RasterizerState.ForcedSampleCount = 0;
|
||||||
|
|
|
@ -371,7 +371,7 @@ class Adapter : public AdapterBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (@available(macOS 10.11, iOS 11.0, *)) {
|
if (@available(macOS 10.11, iOS 11.0, *)) {
|
||||||
mSupportedFeatures.EnableFeature(Feature::DepthClamping);
|
mSupportedFeatures.EnableFeature(Feature::DepthClipControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (@available(macOS 10.11, iOS 9.0, *)) {
|
if (@available(macOS 10.11, iOS 9.0, *)) {
|
||||||
|
|
|
@ -1242,7 +1242,7 @@ MaybeError CommandBuffer::EncodeRenderPass(id<MTLRenderCommandEncoder> encoder)
|
||||||
slopeScale:newPipeline->GetDepthBiasSlopeScale()
|
slopeScale:newPipeline->GetDepthBiasSlopeScale()
|
||||||
clamp:newPipeline->GetDepthBiasClamp()];
|
clamp:newPipeline->GetDepthBiasClamp()];
|
||||||
if (@available(macOS 10.11, iOS 11.0, *)) {
|
if (@available(macOS 10.11, iOS 11.0, *)) {
|
||||||
MTLDepthClipMode clipMode = newPipeline->ShouldClampDepth()
|
MTLDepthClipMode clipMode = newPipeline->HasUnclippedDepth()
|
||||||
? MTLDepthClipModeClamp
|
? MTLDepthClipModeClamp
|
||||||
: MTLDepthClipModeClip;
|
: MTLDepthClipModeClip;
|
||||||
[encoder setDepthClipMode:clipMode];
|
[encoder setDepthClipMode:clipMode];
|
||||||
|
|
|
@ -147,10 +147,6 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
||||||
mSupportedFeatures.EnableFeature(Feature::PipelineStatisticsQuery);
|
mSupportedFeatures.EnableFeature(Feature::PipelineStatisticsQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDeviceInfo.features.depthClamp == VK_TRUE) {
|
|
||||||
mSupportedFeatures.EnableFeature(Feature::DepthClamping);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mDeviceInfo.properties.limits.timestampComputeAndGraphics == VK_TRUE) {
|
if (mDeviceInfo.properties.limits.timestampComputeAndGraphics == VK_TRUE) {
|
||||||
mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
|
mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
|
||||||
}
|
}
|
||||||
|
@ -171,6 +167,11 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
||||||
mSupportedFeatures.EnableFeature(Feature::ChromiumExperimentalDp4a);
|
mSupportedFeatures.EnableFeature(Feature::ChromiumExperimentalDp4a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mDeviceInfo.HasExt(DeviceExt::DepthClipEnable) &&
|
||||||
|
mDeviceInfo.depthClipEnableFeatures.depthClipEnable == VK_TRUE) {
|
||||||
|
mSupportedFeatures.EnableFeature(Feature::DepthClipControl);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(DAWN_USE_SYNC_FDS)
|
#if defined(DAWN_USE_SYNC_FDS)
|
||||||
// TODO(chromium:1258986): Precisely enable the feature by querying the device's format
|
// TODO(chromium:1258986): Precisely enable the feature by querying the device's format
|
||||||
// features.
|
// features.
|
||||||
|
|
|
@ -57,6 +57,13 @@ void CacheKeySerializer<VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT>:
|
||||||
key->Record(t.requiredSubgroupSize);
|
key->Record(t.requiredSubgroupSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void CacheKeySerializer<VkPipelineRasterizationDepthClipStateCreateInfoEXT>::Serialize(
|
||||||
|
CacheKey* key,
|
||||||
|
const VkPipelineRasterizationDepthClipStateCreateInfoEXT& t) {
|
||||||
|
key->Record(t.depthClipEnable, t.flags);
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void CacheKeySerializer<VkSpecializationMapEntry>::Serialize(CacheKey* key,
|
void CacheKeySerializer<VkSpecializationMapEntry>::Serialize(CacheKey* key,
|
||||||
const VkSpecializationMapEntry& t) {
|
const VkSpecializationMapEntry& t) {
|
||||||
|
@ -170,7 +177,7 @@ void CacheKeySerializer<VkPipelineRasterizationStateCreateInfo>::Serialize(
|
||||||
key->Record(t.flags, t.depthClampEnable, t.rasterizerDiscardEnable, t.polygonMode, t.cullMode,
|
key->Record(t.flags, t.depthClampEnable, t.rasterizerDiscardEnable, t.polygonMode, t.cullMode,
|
||||||
t.frontFace, t.depthBiasEnable, t.depthBiasConstantFactor, t.depthBiasClamp,
|
t.frontFace, t.depthBiasEnable, t.depthBiasConstantFactor, t.depthBiasClamp,
|
||||||
t.depthBiasSlopeFactor, t.lineWidth);
|
t.depthBiasSlopeFactor, t.lineWidth);
|
||||||
vulkan::SerializePnext<>(key, &t);
|
vulkan::SerializePnext<VkPipelineRasterizationDepthClipStateCreateInfoEXT>(key, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
|
|
@ -409,6 +409,16 @@ ResultOrError<VulkanDeviceKnobs> Device::CreateDevice(VkPhysicalDevice physicalD
|
||||||
usedKnobs.features.pipelineStatisticsQuery = VK_TRUE;
|
usedKnobs.features.pipelineStatisticsQuery = VK_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsFeatureEnabled(Feature::DepthClipControl)) {
|
||||||
|
const VulkanDeviceInfo& deviceInfo = ToBackend(GetAdapter())->GetDeviceInfo();
|
||||||
|
ASSERT(deviceInfo.HasExt(DeviceExt::DepthClipEnable) &&
|
||||||
|
deviceInfo.depthClipEnableFeatures.depthClipEnable == VK_TRUE);
|
||||||
|
|
||||||
|
usedKnobs.depthClipEnableFeatures.depthClipEnable = VK_TRUE;
|
||||||
|
featuresChain.Add(&usedKnobs.depthClipEnableFeatures,
|
||||||
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT);
|
||||||
|
}
|
||||||
|
|
||||||
if (IsFeatureEnabled(Feature::ShaderFloat16)) {
|
if (IsFeatureEnabled(Feature::ShaderFloat16)) {
|
||||||
const VulkanDeviceInfo& deviceInfo = ToBackend(GetAdapter())->GetDeviceInfo();
|
const VulkanDeviceInfo& deviceInfo = ToBackend(GetAdapter())->GetDeviceInfo();
|
||||||
ASSERT(deviceInfo.HasExt(DeviceExt::ShaderFloat16Int8) &&
|
ASSERT(deviceInfo.HasExt(DeviceExt::ShaderFloat16Int8) &&
|
||||||
|
@ -427,11 +437,6 @@ ResultOrError<VulkanDeviceKnobs> Device::CreateDevice(VkPhysicalDevice physicalD
|
||||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES);
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsFeatureEnabled(Feature::DepthClamping)) {
|
|
||||||
ASSERT(ToBackend(GetAdapter())->GetDeviceInfo().features.depthClamp == VK_TRUE);
|
|
||||||
usedKnobs.features.depthClamp = VK_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find a universal queue family
|
// Find a universal queue family
|
||||||
{
|
{
|
||||||
// Note that GRAPHICS and COMPUTE imply TRANSFER so we don't need to check for it.
|
// Note that GRAPHICS and COMPUTE imply TRANSFER so we don't need to check for it.
|
||||||
|
|
|
@ -430,7 +430,7 @@ MaybeError RenderPipeline::Initialize() {
|
||||||
rasterization.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
rasterization.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||||
rasterization.pNext = nullptr;
|
rasterization.pNext = nullptr;
|
||||||
rasterization.flags = 0;
|
rasterization.flags = 0;
|
||||||
rasterization.depthClampEnable = ShouldClampDepth() ? VK_TRUE : VK_FALSE;
|
rasterization.depthClampEnable = VK_FALSE;
|
||||||
rasterization.rasterizerDiscardEnable = VK_FALSE;
|
rasterization.rasterizerDiscardEnable = VK_FALSE;
|
||||||
rasterization.polygonMode = VK_POLYGON_MODE_FILL;
|
rasterization.polygonMode = VK_POLYGON_MODE_FILL;
|
||||||
rasterization.cullMode = VulkanCullMode(GetCullMode());
|
rasterization.cullMode = VulkanCullMode(GetCullMode());
|
||||||
|
@ -441,6 +441,18 @@ MaybeError RenderPipeline::Initialize() {
|
||||||
rasterization.depthBiasSlopeFactor = GetDepthBiasSlopeScale();
|
rasterization.depthBiasSlopeFactor = GetDepthBiasSlopeScale();
|
||||||
rasterization.lineWidth = 1.0f;
|
rasterization.lineWidth = 1.0f;
|
||||||
|
|
||||||
|
PNextChainBuilder rasterizationChain(&rasterization);
|
||||||
|
VkPipelineRasterizationDepthClipStateCreateInfoEXT depthClipState;
|
||||||
|
if (HasUnclippedDepth()) {
|
||||||
|
ASSERT(device->IsFeatureEnabled(Feature::DepthClipControl));
|
||||||
|
depthClipState.pNext = nullptr;
|
||||||
|
depthClipState.depthClipEnable = VK_FALSE;
|
||||||
|
depthClipState.flags = 0;
|
||||||
|
rasterizationChain.Add(
|
||||||
|
&depthClipState,
|
||||||
|
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT);
|
||||||
|
}
|
||||||
|
|
||||||
VkPipelineMultisampleStateCreateInfo multisample;
|
VkPipelineMultisampleStateCreateInfo multisample;
|
||||||
multisample.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
multisample.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||||
multisample.pNext = nullptr;
|
multisample.pNext = nullptr;
|
||||||
|
|
|
@ -162,6 +162,7 @@ static constexpr std::array<DeviceExtInfo, kDeviceExtCount> sDeviceExtInfos{{
|
||||||
{DeviceExt::ExternalSemaphoreFD, "VK_KHR_external_semaphore_fd", NeverPromoted},
|
{DeviceExt::ExternalSemaphoreFD, "VK_KHR_external_semaphore_fd", NeverPromoted},
|
||||||
{DeviceExt::ExternalSemaphoreZirconHandle, "VK_FUCHSIA_external_semaphore", NeverPromoted},
|
{DeviceExt::ExternalSemaphoreZirconHandle, "VK_FUCHSIA_external_semaphore", NeverPromoted},
|
||||||
|
|
||||||
|
{DeviceExt::DepthClipEnable, "VK_EXT_depth_clip_enable", NeverPromoted},
|
||||||
{DeviceExt::ImageDrmFormatModifier, "VK_EXT_image_drm_format_modifier", NeverPromoted},
|
{DeviceExt::ImageDrmFormatModifier, "VK_EXT_image_drm_format_modifier", NeverPromoted},
|
||||||
{DeviceExt::Swapchain, "VK_KHR_swapchain", NeverPromoted},
|
{DeviceExt::Swapchain, "VK_KHR_swapchain", NeverPromoted},
|
||||||
{DeviceExt::SubgroupSizeControl, "VK_EXT_subgroup_size_control", NeverPromoted},
|
{DeviceExt::SubgroupSizeControl, "VK_EXT_subgroup_size_control", NeverPromoted},
|
||||||
|
@ -283,6 +284,7 @@ DeviceExtSet EnsureDependencies(const DeviceExtSet& advertisedExts,
|
||||||
hasDependencies = icdVersion >= VulkanVersion_1_1;
|
hasDependencies = icdVersion >= VulkanVersion_1_1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DeviceExt::DepthClipEnable:
|
||||||
case DeviceExt::ShaderIntegerDotProduct:
|
case DeviceExt::ShaderIntegerDotProduct:
|
||||||
case DeviceExt::ZeroInitializeWorkgroupMemory:
|
case DeviceExt::ZeroInitializeWorkgroupMemory:
|
||||||
hasDependencies = HasDep(DeviceExt::GetPhysicalDeviceProperties2);
|
hasDependencies = HasDep(DeviceExt::GetPhysicalDeviceProperties2);
|
||||||
|
|
|
@ -103,6 +103,7 @@ enum class DeviceExt {
|
||||||
ExternalSemaphoreZirconHandle,
|
ExternalSemaphoreZirconHandle,
|
||||||
|
|
||||||
// Others
|
// Others
|
||||||
|
DepthClipEnable,
|
||||||
ImageDrmFormatModifier,
|
ImageDrmFormatModifier,
|
||||||
Swapchain,
|
Swapchain,
|
||||||
SubgroupSizeControl,
|
SubgroupSizeControl,
|
||||||
|
|
|
@ -254,6 +254,11 @@ ResultOrError<VulkanDeviceInfo> GatherDeviceInfo(const Adapter& adapter) {
|
||||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR);
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (info.extensions[DeviceExt::DepthClipEnable]) {
|
||||||
|
featuresChain.Add(&info.depthClipEnableFeatures,
|
||||||
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT);
|
||||||
|
}
|
||||||
|
|
||||||
// If we have DeviceExt::GetPhysicalDeviceProperties2, use features2 and properties2 so
|
// If we have DeviceExt::GetPhysicalDeviceProperties2, use features2 and properties2 so
|
||||||
// that features no covered by VkPhysicalDevice{Features,Properties} can be queried.
|
// that features no covered by VkPhysicalDevice{Features,Properties} can be queried.
|
||||||
//
|
//
|
||||||
|
|
|
@ -53,6 +53,7 @@ struct VulkanDeviceKnobs {
|
||||||
VkPhysicalDeviceSubgroupSizeControlFeaturesEXT subgroupSizeControlFeatures;
|
VkPhysicalDeviceSubgroupSizeControlFeaturesEXT subgroupSizeControlFeatures;
|
||||||
VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR zeroInitializeWorkgroupMemoryFeatures;
|
VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR zeroInitializeWorkgroupMemoryFeatures;
|
||||||
VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR shaderIntegerDotProductFeatures;
|
VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR shaderIntegerDotProductFeatures;
|
||||||
|
VkPhysicalDeviceDepthClipEnableFeaturesEXT depthClipEnableFeatures;
|
||||||
|
|
||||||
bool HasExt(DeviceExt ext) const;
|
bool HasExt(DeviceExt ext) const;
|
||||||
DeviceExtSet extensions;
|
DeviceExtSet extensions;
|
||||||
|
|
|
@ -21,11 +21,11 @@
|
||||||
|
|
||||||
constexpr static unsigned int kRTSize = 1;
|
constexpr static unsigned int kRTSize = 1;
|
||||||
|
|
||||||
class DepthClampingTest : public DawnTest {
|
class DepthClippingTest : public DawnTest {
|
||||||
protected:
|
protected:
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
DawnTest::SetUp();
|
DawnTest::SetUp();
|
||||||
DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::DepthClamping}));
|
DAWN_TEST_UNSUPPORTED_IF(!SupportsFeatures({wgpu::FeatureName::DepthClipControl}));
|
||||||
|
|
||||||
wgpu::TextureDescriptor renderTargetDescriptor;
|
wgpu::TextureDescriptor renderTargetDescriptor;
|
||||||
renderTargetDescriptor.size = {kRTSize, kRTSize};
|
renderTargetDescriptor.size = {kRTSize, kRTSize};
|
||||||
|
@ -70,17 +70,16 @@ class DepthClampingTest : public DawnTest {
|
||||||
|
|
||||||
std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
|
std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
|
||||||
std::vector<wgpu::FeatureName> requiredFeatures = {};
|
std::vector<wgpu::FeatureName> requiredFeatures = {};
|
||||||
if (SupportsFeatures({wgpu::FeatureName::DepthClamping})) {
|
if (SupportsFeatures({wgpu::FeatureName::DepthClipControl})) {
|
||||||
requiredFeatures.push_back(wgpu::FeatureName::DepthClamping);
|
requiredFeatures.push_back(wgpu::FeatureName::DepthClipControl);
|
||||||
}
|
}
|
||||||
return requiredFeatures;
|
return requiredFeatures;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TestSpec {
|
struct TestSpec {
|
||||||
wgpu::PrimitiveDepthClampingState* depthClampingState;
|
wgpu::PrimitiveDepthClipControl* depthClipControl;
|
||||||
RGBA8 color;
|
RGBA8 color;
|
||||||
float depth;
|
float depth;
|
||||||
wgpu::CompareFunction depthCompareFunction;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Each test param represents a pair of triangles with a color, depth, stencil value, and
|
// Each test param represents a pair of triangles with a color, depth, stencil value, and
|
||||||
|
@ -111,13 +110,12 @@ class DepthClampingTest : public DawnTest {
|
||||||
|
|
||||||
// Create a pipeline for the triangles with the test spec's params.
|
// Create a pipeline for the triangles with the test spec's params.
|
||||||
utils::ComboRenderPipelineDescriptor descriptor;
|
utils::ComboRenderPipelineDescriptor descriptor;
|
||||||
descriptor.primitive.nextInChain = test.depthClampingState;
|
descriptor.primitive.nextInChain = test.depthClipControl;
|
||||||
descriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
|
descriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
|
||||||
descriptor.vertex.module = vsModule;
|
descriptor.vertex.module = vsModule;
|
||||||
descriptor.cFragment.module = fsModule;
|
descriptor.cFragment.module = fsModule;
|
||||||
wgpu::DepthStencilState* depthStencil = descriptor.EnableDepthStencil();
|
wgpu::DepthStencilState* depthStencil = descriptor.EnableDepthStencil();
|
||||||
depthStencil->depthWriteEnabled = true;
|
depthStencil->depthWriteEnabled = true;
|
||||||
depthStencil->depthCompare = test.depthCompareFunction;
|
|
||||||
depthStencil->format = wgpu::TextureFormat::Depth24PlusStencil8;
|
depthStencil->format = wgpu::TextureFormat::Depth24PlusStencil8;
|
||||||
|
|
||||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||||
|
@ -146,150 +144,218 @@ class DepthClampingTest : public DawnTest {
|
||||||
wgpu::ShaderModule fsModule;
|
wgpu::ShaderModule fsModule;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test that fragments beyond the far plane are clamped to 1.0 if depth clamping is enabled.
|
// Test that fragments beyond the far plane are not clipped if unclippedDepth is true
|
||||||
TEST_P(DepthClampingTest, ClampOnBeyondFarPlane) {
|
TEST_P(DepthClippingTest, UnclippedBeyondFarPlane) {
|
||||||
wgpu::PrimitiveDepthClampingState clampingState;
|
wgpu::PrimitiveDepthClipControl depthClipControl;
|
||||||
clampingState.clampDepth = true;
|
depthClipControl.unclippedDepth = true;
|
||||||
|
|
||||||
DoTest(
|
DoTest(
|
||||||
{
|
{
|
||||||
// Draw a red triangle at depth 1.
|
// Draw a red triangle at depth 1.
|
||||||
{
|
{
|
||||||
nullptr, /* depthClampingState */
|
nullptr, /* depthClipControl */
|
||||||
RGBA8(255, 0, 0, 255), /* color */
|
RGBA8(255, 0, 0, 255), /* color */
|
||||||
1.f, /* depth */
|
1.f, /* depth */
|
||||||
wgpu::CompareFunction::Always,
|
|
||||||
},
|
},
|
||||||
// Draw a green triangle at depth 2 which should get clamped to 1.
|
// Draw a green triangle at depth 2 which should not be clipped.
|
||||||
{
|
{
|
||||||
&clampingState,
|
&depthClipControl, /* depthClipControl */
|
||||||
RGBA8(0, 255, 0, 255), /* color */
|
RGBA8(0, 255, 0, 255), /* color */
|
||||||
2.f, /* depth */
|
2.f, /* depth */
|
||||||
wgpu::CompareFunction::Equal,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Since we draw the green triangle with an "equal" depth compare function, the resulting
|
// The resulting fragment should be green even though the green triangle is
|
||||||
// fragment should be green.
|
// outside the clip volume.
|
||||||
RGBA8(0, 255, 0, 255));
|
RGBA8(0, 255, 0, 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that fragments beyond the near plane are clamped to 0.0 if depth clamping is enabled.
|
// Test that fragments beyond the far plane are clipped if unclippedDepth is false
|
||||||
TEST_P(DepthClampingTest, ClampOnBeyondNearPlane) {
|
TEST_P(DepthClippingTest, ClippedBeyondFarPlane) {
|
||||||
wgpu::PrimitiveDepthClampingState clampingState;
|
wgpu::PrimitiveDepthClipControl depthClipControl;
|
||||||
clampingState.clampDepth = true;
|
depthClipControl.unclippedDepth = false;
|
||||||
|
|
||||||
|
DoTest(
|
||||||
|
{
|
||||||
|
// Draw a red triangle at depth 1.
|
||||||
|
{
|
||||||
|
nullptr, /* depthClipControl */
|
||||||
|
RGBA8(255, 0, 0, 255), /* color */
|
||||||
|
1.f, /* depth */
|
||||||
|
},
|
||||||
|
// Draw a green triangle at depth 2 which should be clipped.
|
||||||
|
{
|
||||||
|
&depthClipControl, /* depthClipControl */
|
||||||
|
RGBA8(0, 255, 0, 255), /* color */
|
||||||
|
2.f, /* depth */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// The resulting fragment should be red since the green triangle is
|
||||||
|
// outside the clip volume.
|
||||||
|
RGBA8(255, 0, 0, 255));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that fragments beyond the far plane are clipped if unclippedDepth is not specified
|
||||||
|
TEST_P(DepthClippingTest, ClippedBeyondFarPlaneFeatureUnused) {
|
||||||
|
DoTest(
|
||||||
|
{
|
||||||
|
// Draw a red triangle at depth 1.
|
||||||
|
{
|
||||||
|
nullptr, /* depthClipControl */
|
||||||
|
RGBA8(255, 0, 0, 255), /* color */
|
||||||
|
1.f, /* depth */
|
||||||
|
},
|
||||||
|
// Draw a green triangle at depth 2 which should be clipped.
|
||||||
|
{
|
||||||
|
nullptr, /* depthClipControl */
|
||||||
|
RGBA8(0, 255, 0, 255), /* color */
|
||||||
|
2.f, /* depth */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// The resulting fragment should be red since the green triangle is
|
||||||
|
// outside the clip volume.
|
||||||
|
RGBA8(255, 0, 0, 255));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that fragments beyond the near plane are not clipped if unclippedDepth is true
|
||||||
|
TEST_P(DepthClippingTest, UnclippedBeyondNearPlane) {
|
||||||
|
wgpu::PrimitiveDepthClipControl depthClipControl;
|
||||||
|
depthClipControl.unclippedDepth = true;
|
||||||
|
|
||||||
DoTest(
|
DoTest(
|
||||||
{
|
{
|
||||||
// Draw a red triangle at depth 0.
|
// Draw a red triangle at depth 0.
|
||||||
{
|
{
|
||||||
nullptr, /* depthClampingState */
|
nullptr, /* depthClipControl */
|
||||||
RGBA8(255, 0, 0, 255), /* color */
|
RGBA8(255, 0, 0, 255), /* color */
|
||||||
0.f, /* depth */
|
0.f, /* depth */
|
||||||
wgpu::CompareFunction::Always,
|
|
||||||
},
|
},
|
||||||
// Draw a green triangle at depth -1 which should get clamped to 0.
|
// Draw a green triangle at depth -1 which should not be clipped.
|
||||||
{
|
{
|
||||||
&clampingState,
|
&depthClipControl, /* depthClipControl */
|
||||||
RGBA8(0, 255, 0, 255), /* color */
|
RGBA8(0, 255, 0, 255), /* color */
|
||||||
-1.f, /* depth */
|
-1.f, /* depth */
|
||||||
wgpu::CompareFunction::Equal,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Since we draw the green triangle with an "equal" depth compare function, the resulting
|
// The resulting fragment should be green even though the green triangle is
|
||||||
// fragment should be green.
|
// outside the clip volume.
|
||||||
RGBA8(0, 255, 0, 255));
|
RGBA8(0, 255, 0, 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that fragments inside the view frustum are unaffected by depth clamping.
|
// Test that fragments beyond the near plane are clipped if unclippedDepth is false
|
||||||
TEST_P(DepthClampingTest, ClampOnInsideViewFrustum) {
|
TEST_P(DepthClippingTest, ClippedBeyondNearPlane) {
|
||||||
wgpu::PrimitiveDepthClampingState clampingState;
|
wgpu::PrimitiveDepthClipControl depthClipControl;
|
||||||
clampingState.clampDepth = true;
|
depthClipControl.unclippedDepth = false;
|
||||||
|
|
||||||
DoTest(
|
DoTest(
|
||||||
{
|
{
|
||||||
|
// Draw a red triangle at depth 0.
|
||||||
{
|
{
|
||||||
&clampingState,
|
nullptr, /* depthClipControl */
|
||||||
RGBA8(0, 255, 0, 255), /* color */
|
RGBA8(255, 0, 0, 255), /* color */
|
||||||
0.5f, /* depth */
|
0.f, /* depth */
|
||||||
wgpu::CompareFunction::Always,
|
|
||||||
},
|
},
|
||||||
},
|
// Draw a green triangle at depth -1 which should be clipped.
|
||||||
RGBA8(0, 255, 0, 255));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that fragments outside the view frustum are clipped if depth clamping is disabled.
|
|
||||||
TEST_P(DepthClampingTest, ClampOffOutsideViewFrustum) {
|
|
||||||
wgpu::PrimitiveDepthClampingState clampingState;
|
|
||||||
clampingState.clampDepth = false;
|
|
||||||
|
|
||||||
DoTest(
|
|
||||||
{
|
{
|
||||||
{
|
&depthClipControl, /* depthClipControl */
|
||||||
&clampingState,
|
|
||||||
RGBA8(0, 255, 0, 255), /* color */
|
|
||||||
2.f, /* depth */
|
|
||||||
wgpu::CompareFunction::Always,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
&clampingState,
|
|
||||||
RGBA8(0, 255, 0, 255), /* color */
|
RGBA8(0, 255, 0, 255), /* color */
|
||||||
-1.f, /* depth */
|
-1.f, /* depth */
|
||||||
wgpu::CompareFunction::Always,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
RGBA8(0, 0, 0, 0));
|
// The resulting fragment should be red because the green triangle is
|
||||||
|
// outside the clip volume.
|
||||||
|
RGBA8(255, 0, 0, 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that fragments outside the view frustum are clipped if clampDepth is left unspecified.
|
// Test that fragments beyond the near plane are clipped if unclippedDepth is not specified
|
||||||
TEST_P(DepthClampingTest, ClampUnspecifiedOutsideViewFrustum) {
|
TEST_P(DepthClippingTest, ClippedBeyondNearPlaneFeatureUnused) {
|
||||||
DoTest(
|
DoTest(
|
||||||
{
|
{
|
||||||
|
// Draw a red triangle at depth 0.
|
||||||
{
|
{
|
||||||
nullptr, /* depthClampingState */
|
nullptr, /* depthClipControl */
|
||||||
|
RGBA8(255, 0, 0, 255), /* color */
|
||||||
|
0.f, /* depth */
|
||||||
|
},
|
||||||
|
// Draw a green triangle at depth -1 which should be clipped.
|
||||||
|
{
|
||||||
|
nullptr, /* depthClipControl */
|
||||||
RGBA8(0, 255, 0, 255), /* color */
|
RGBA8(0, 255, 0, 255), /* color */
|
||||||
-1.f, /* depth */
|
-1.f, /* depth */
|
||||||
wgpu::CompareFunction::Always,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
nullptr, /* depthClampingState */
|
|
||||||
RGBA8(0, 255, 0, 255), /* color */
|
|
||||||
2.f, /* depth */
|
|
||||||
wgpu::CompareFunction::Always,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
RGBA8(0, 0, 0, 0));
|
// The resulting fragment should be red because the green triangle is
|
||||||
|
// outside the clip volume.
|
||||||
|
RGBA8(255, 0, 0, 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that fragments are properly clipped or clamped if multiple render pipelines are used
|
// Test that fragments are properly clipped or clamped if multiple render pipelines are used
|
||||||
// within the same render pass with differing clampDepth values.
|
// within the same render pass with differing unclippedDepth values.
|
||||||
TEST_P(DepthClampingTest, MultipleRenderPipelines) {
|
TEST_P(DepthClippingTest, MultipleRenderPipelines) {
|
||||||
wgpu::PrimitiveDepthClampingState clampingState;
|
wgpu::PrimitiveDepthClipControl depthClipControl1;
|
||||||
clampingState.clampDepth = true;
|
depthClipControl1.unclippedDepth = true;
|
||||||
|
|
||||||
wgpu::PrimitiveDepthClampingState clippingState;
|
wgpu::PrimitiveDepthClipControl depthClipControl2;
|
||||||
clippingState.clampDepth = false;
|
depthClipControl2.unclippedDepth = false;
|
||||||
|
|
||||||
DoTest(
|
DoTest(
|
||||||
{
|
{
|
||||||
// Draw green with clamping
|
// Draw green with no clipping
|
||||||
{
|
{
|
||||||
&clampingState,
|
&depthClipControl1, RGBA8(0, 255, 0, 255), /* color */
|
||||||
RGBA8(0, 255, 0, 255), /* color */
|
|
||||||
2.f, /* depth */
|
2.f, /* depth */
|
||||||
wgpu::CompareFunction::Always,
|
|
||||||
},
|
},
|
||||||
// Draw red with clipping
|
// Draw red with clipping
|
||||||
{
|
{
|
||||||
&clippingState,
|
&depthClipControl2, RGBA8(255, 0, 0, 255), /* color */
|
||||||
RGBA8(255, 0, 0, 255), /* color */
|
|
||||||
2.f, /* depth */
|
2.f, /* depth */
|
||||||
wgpu::CompareFunction::Always,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
RGBA8(0, 255, 0, 255)); // Result should be green
|
RGBA8(0, 255, 0, 255)); // Result should be green
|
||||||
}
|
}
|
||||||
|
|
||||||
DAWN_INSTANTIATE_TEST(DepthClampingTest,
|
// Test that fragments are not clipped if unclippedDepth is true and that their
|
||||||
|
// depths are not being clamped instead. In the fragment shader, we should see
|
||||||
|
// depth values outside the viewport.
|
||||||
|
TEST_P(DepthClippingTest, UnclippedNotClamped) {
|
||||||
|
wgpu::PrimitiveDepthClipControl depthClipControl;
|
||||||
|
depthClipControl.unclippedDepth = true;
|
||||||
|
|
||||||
|
// Create a pipeline to render a point.
|
||||||
|
utils::ComboRenderPipelineDescriptor descriptor;
|
||||||
|
descriptor.primitive.nextInChain = &depthClipControl;
|
||||||
|
descriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
|
||||||
|
// Draw the point at (0, 0) with depth 2.0.
|
||||||
|
descriptor.vertex.module = utils::CreateShaderModule(device, R"(
|
||||||
|
@vertex fn main() -> @builtin(position) vec4<f32> {
|
||||||
|
return vec4<f32>(0.0, 0.0, 2.0, 1.0);
|
||||||
|
})");
|
||||||
|
// Write frag_pos.z / 4.0 which should be about 0.5 to the red channel.
|
||||||
|
// This is the depth output from the vertex shader which is not clamped to the viewport.
|
||||||
|
descriptor.cFragment.module = utils::CreateShaderModule(device, R"(
|
||||||
|
@fragment fn main(@builtin(position) frag_pos: vec4<f32>) -> @location(0) vec4<f32> {
|
||||||
|
return vec4<f32>(frag_pos.z / 4.0, 0.0, 0.0, 1.0);
|
||||||
|
})");
|
||||||
|
wgpu::DepthStencilState* depthStencil = descriptor.EnableDepthStencil();
|
||||||
|
depthStencil->depthWriteEnabled = true;
|
||||||
|
depthStencil->format = wgpu::TextureFormat::Depth24PlusStencil8;
|
||||||
|
|
||||||
|
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||||
|
|
||||||
|
// Draw the point.
|
||||||
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
|
utils::ComboRenderPassDescriptor renderPass({renderTargetView}, depthTextureView);
|
||||||
|
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
|
||||||
|
pass.SetPipeline(pipeline);
|
||||||
|
pass.Draw(1);
|
||||||
|
pass.End();
|
||||||
|
wgpu::CommandBuffer commands = encoder.Finish();
|
||||||
|
queue.Submit(1, &commands);
|
||||||
|
|
||||||
|
EXPECT_PIXEL_RGBA8_BETWEEN(RGBA8(127, 0, 0, 255), RGBA8(128, 0, 0, 255), renderTarget, 0, 0)
|
||||||
|
<< "Pixel check failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
DAWN_INSTANTIATE_TEST(DepthClippingTest,
|
||||||
D3D12Backend(),
|
D3D12Backend(),
|
||||||
MetalBackend(),
|
MetalBackend(),
|
||||||
OpenGLBackend(),
|
OpenGLBackend(),
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
// Checks that we cannot find any structs in an empty chain
|
// Checks that we cannot find any structs in an empty chain
|
||||||
TEST(ChainUtilsTests, FindEmptyChain) {
|
TEST(ChainUtilsTests, FindEmptyChain) {
|
||||||
const dawn::native::PrimitiveDepthClampingState* info = nullptr;
|
const dawn::native::PrimitiveDepthClipControl* info = nullptr;
|
||||||
dawn::native::FindInChain(nullptr, &info);
|
dawn::native::FindInChain(nullptr, &info);
|
||||||
|
|
||||||
ASSERT_EQ(nullptr, info);
|
ASSERT_EQ(nullptr, info);
|
||||||
|
@ -27,10 +27,10 @@ TEST(ChainUtilsTests, FindEmptyChain) {
|
||||||
|
|
||||||
// Checks that searching a chain for a present struct returns that struct
|
// Checks that searching a chain for a present struct returns that struct
|
||||||
TEST(ChainUtilsTests, FindPresentInChain) {
|
TEST(ChainUtilsTests, FindPresentInChain) {
|
||||||
dawn::native::PrimitiveDepthClampingState chain1;
|
dawn::native::PrimitiveDepthClipControl chain1;
|
||||||
dawn::native::ShaderModuleSPIRVDescriptor chain2;
|
dawn::native::ShaderModuleSPIRVDescriptor chain2;
|
||||||
chain1.nextInChain = &chain2;
|
chain1.nextInChain = &chain2;
|
||||||
const dawn::native::PrimitiveDepthClampingState* info1 = nullptr;
|
const dawn::native::PrimitiveDepthClipControl* info1 = nullptr;
|
||||||
const dawn::native::ShaderModuleSPIRVDescriptor* info2 = nullptr;
|
const dawn::native::ShaderModuleSPIRVDescriptor* info2 = nullptr;
|
||||||
dawn::native::FindInChain(&chain1, &info1);
|
dawn::native::FindInChain(&chain1, &info1);
|
||||||
dawn::native::FindInChain(&chain1, &info2);
|
dawn::native::FindInChain(&chain1, &info2);
|
||||||
|
@ -41,7 +41,7 @@ TEST(ChainUtilsTests, FindPresentInChain) {
|
||||||
|
|
||||||
// Checks that searching a chain for a struct that doesn't exist returns a nullptr
|
// Checks that searching a chain for a struct that doesn't exist returns a nullptr
|
||||||
TEST(ChainUtilsTests, FindMissingInChain) {
|
TEST(ChainUtilsTests, FindMissingInChain) {
|
||||||
dawn::native::PrimitiveDepthClampingState chain1;
|
dawn::native::PrimitiveDepthClipControl chain1;
|
||||||
dawn::native::ShaderModuleSPIRVDescriptor chain2;
|
dawn::native::ShaderModuleSPIRVDescriptor chain2;
|
||||||
chain1.nextInChain = &chain2;
|
chain1.nextInChain = &chain2;
|
||||||
const dawn::native::SurfaceDescriptorFromMetalLayer* info = nullptr;
|
const dawn::native::SurfaceDescriptorFromMetalLayer* info = nullptr;
|
||||||
|
@ -52,9 +52,9 @@ TEST(ChainUtilsTests, FindMissingInChain) {
|
||||||
|
|
||||||
// Checks that validation rejects chains with duplicate STypes
|
// Checks that validation rejects chains with duplicate STypes
|
||||||
TEST(ChainUtilsTests, ValidateDuplicateSTypes) {
|
TEST(ChainUtilsTests, ValidateDuplicateSTypes) {
|
||||||
dawn::native::PrimitiveDepthClampingState chain1;
|
dawn::native::PrimitiveDepthClipControl chain1;
|
||||||
dawn::native::ShaderModuleSPIRVDescriptor chain2;
|
dawn::native::ShaderModuleSPIRVDescriptor chain2;
|
||||||
dawn::native::PrimitiveDepthClampingState chain3;
|
dawn::native::PrimitiveDepthClipControl chain3;
|
||||||
chain1.nextInChain = &chain2;
|
chain1.nextInChain = &chain2;
|
||||||
chain2.nextInChain = &chain3;
|
chain2.nextInChain = &chain3;
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ TEST(ChainUtilsTests, ValidateDuplicateSTypes) {
|
||||||
|
|
||||||
// Checks that validation rejects chains that contain unspecified STypes
|
// Checks that validation rejects chains that contain unspecified STypes
|
||||||
TEST(ChainUtilsTests, ValidateUnspecifiedSTypes) {
|
TEST(ChainUtilsTests, ValidateUnspecifiedSTypes) {
|
||||||
dawn::native::PrimitiveDepthClampingState chain1;
|
dawn::native::PrimitiveDepthClipControl chain1;
|
||||||
dawn::native::ShaderModuleSPIRVDescriptor chain2;
|
dawn::native::ShaderModuleSPIRVDescriptor chain2;
|
||||||
dawn::native::ShaderModuleWGSLDescriptor chain3;
|
dawn::native::ShaderModuleWGSLDescriptor chain3;
|
||||||
chain1.nextInChain = &chain2;
|
chain1.nextInChain = &chain2;
|
||||||
|
@ -73,7 +73,7 @@ TEST(ChainUtilsTests, ValidateUnspecifiedSTypes) {
|
||||||
|
|
||||||
dawn::native::MaybeError result =
|
dawn::native::MaybeError result =
|
||||||
dawn::native::ValidateSTypes(&chain1, {
|
dawn::native::ValidateSTypes(&chain1, {
|
||||||
{wgpu::SType::PrimitiveDepthClampingState},
|
{wgpu::SType::PrimitiveDepthClipControl},
|
||||||
{wgpu::SType::ShaderModuleSPIRVDescriptor},
|
{wgpu::SType::ShaderModuleSPIRVDescriptor},
|
||||||
});
|
});
|
||||||
ASSERT_TRUE(result.IsError());
|
ASSERT_TRUE(result.IsError());
|
||||||
|
@ -83,7 +83,7 @@ TEST(ChainUtilsTests, ValidateUnspecifiedSTypes) {
|
||||||
// Checks that validation rejects chains that contain multiple STypes from the same oneof
|
// Checks that validation rejects chains that contain multiple STypes from the same oneof
|
||||||
// constraint.
|
// constraint.
|
||||||
TEST(ChainUtilsTests, ValidateOneOfFailure) {
|
TEST(ChainUtilsTests, ValidateOneOfFailure) {
|
||||||
dawn::native::PrimitiveDepthClampingState chain1;
|
dawn::native::PrimitiveDepthClipControl chain1;
|
||||||
dawn::native::ShaderModuleSPIRVDescriptor chain2;
|
dawn::native::ShaderModuleSPIRVDescriptor chain2;
|
||||||
dawn::native::ShaderModuleWGSLDescriptor chain3;
|
dawn::native::ShaderModuleWGSLDescriptor chain3;
|
||||||
chain1.nextInChain = &chain2;
|
chain1.nextInChain = &chain2;
|
||||||
|
@ -98,7 +98,7 @@ TEST(ChainUtilsTests, ValidateOneOfFailure) {
|
||||||
|
|
||||||
// Checks that validation accepts chains that match the constraints.
|
// Checks that validation accepts chains that match the constraints.
|
||||||
TEST(ChainUtilsTests, ValidateSuccess) {
|
TEST(ChainUtilsTests, ValidateSuccess) {
|
||||||
dawn::native::PrimitiveDepthClampingState chain1;
|
dawn::native::PrimitiveDepthClipControl chain1;
|
||||||
dawn::native::ShaderModuleSPIRVDescriptor chain2;
|
dawn::native::ShaderModuleSPIRVDescriptor chain2;
|
||||||
chain1.nextInChain = &chain2;
|
chain1.nextInChain = &chain2;
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ TEST(ChainUtilsTests, ValidateSuccess) {
|
||||||
&chain1,
|
&chain1,
|
||||||
{
|
{
|
||||||
{wgpu::SType::ShaderModuleSPIRVDescriptor, wgpu::SType::ShaderModuleWGSLDescriptor},
|
{wgpu::SType::ShaderModuleSPIRVDescriptor, wgpu::SType::ShaderModuleWGSLDescriptor},
|
||||||
{wgpu::SType::PrimitiveDepthClampingState},
|
{wgpu::SType::PrimitiveDepthClipControl},
|
||||||
{wgpu::SType::SurfaceDescriptorFromMetalLayer},
|
{wgpu::SType::SurfaceDescriptorFromMetalLayer},
|
||||||
});
|
});
|
||||||
ASSERT_TRUE(result.IsSuccess());
|
ASSERT_TRUE(result.IsSuccess());
|
||||||
|
@ -117,7 +117,7 @@ TEST(ChainUtilsTests, ValidateEmptyChain) {
|
||||||
dawn::native::MaybeError result =
|
dawn::native::MaybeError result =
|
||||||
dawn::native::ValidateSTypes(nullptr, {
|
dawn::native::ValidateSTypes(nullptr, {
|
||||||
{wgpu::SType::ShaderModuleSPIRVDescriptor},
|
{wgpu::SType::ShaderModuleSPIRVDescriptor},
|
||||||
{wgpu::SType::PrimitiveDepthClampingState},
|
{wgpu::SType::PrimitiveDepthClipControl},
|
||||||
});
|
});
|
||||||
ASSERT_TRUE(result.IsSuccess());
|
ASSERT_TRUE(result.IsSuccess());
|
||||||
|
|
||||||
|
@ -132,22 +132,22 @@ TEST(ChainUtilsTests, ValidateSingleEmptyChain) {
|
||||||
ASSERT_TRUE(result.IsSuccess());
|
ASSERT_TRUE(result.IsSuccess());
|
||||||
|
|
||||||
result = dawn::native::ValidateSingleSType(nullptr, wgpu::SType::ShaderModuleSPIRVDescriptor,
|
result = dawn::native::ValidateSingleSType(nullptr, wgpu::SType::ShaderModuleSPIRVDescriptor,
|
||||||
wgpu::SType::PrimitiveDepthClampingState);
|
wgpu::SType::PrimitiveDepthClipControl);
|
||||||
ASSERT_TRUE(result.IsSuccess());
|
ASSERT_TRUE(result.IsSuccess());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks that singleton validation always fails on chains with multiple children.
|
// Checks that singleton validation always fails on chains with multiple children.
|
||||||
TEST(ChainUtilsTests, ValidateSingleMultiChain) {
|
TEST(ChainUtilsTests, ValidateSingleMultiChain) {
|
||||||
dawn::native::PrimitiveDepthClampingState chain1;
|
dawn::native::PrimitiveDepthClipControl chain1;
|
||||||
dawn::native::ShaderModuleSPIRVDescriptor chain2;
|
dawn::native::ShaderModuleSPIRVDescriptor chain2;
|
||||||
chain1.nextInChain = &chain2;
|
chain1.nextInChain = &chain2;
|
||||||
|
|
||||||
dawn::native::MaybeError result =
|
dawn::native::MaybeError result =
|
||||||
dawn::native::ValidateSingleSType(&chain1, wgpu::SType::PrimitiveDepthClampingState);
|
dawn::native::ValidateSingleSType(&chain1, wgpu::SType::PrimitiveDepthClipControl);
|
||||||
ASSERT_TRUE(result.IsError());
|
ASSERT_TRUE(result.IsError());
|
||||||
result.AcquireError();
|
result.AcquireError();
|
||||||
|
|
||||||
result = dawn::native::ValidateSingleSType(&chain1, wgpu::SType::PrimitiveDepthClampingState,
|
result = dawn::native::ValidateSingleSType(&chain1, wgpu::SType::PrimitiveDepthClipControl,
|
||||||
wgpu::SType::ShaderModuleSPIRVDescriptor);
|
wgpu::SType::ShaderModuleSPIRVDescriptor);
|
||||||
ASSERT_TRUE(result.IsError());
|
ASSERT_TRUE(result.IsError());
|
||||||
result.AcquireError();
|
result.AcquireError();
|
||||||
|
@ -172,7 +172,7 @@ TEST(ChainUtilsTests, ValidateSingleSatisfied) {
|
||||||
|
|
||||||
// Checks that singleton validation passes when the oneof constraint is not met.
|
// Checks that singleton validation passes when the oneof constraint is not met.
|
||||||
TEST(ChainUtilsTests, ValidateSingleUnsatisfied) {
|
TEST(ChainUtilsTests, ValidateSingleUnsatisfied) {
|
||||||
dawn::native::PrimitiveDepthClampingState chain1;
|
dawn::native::PrimitiveDepthClipControl chain1;
|
||||||
|
|
||||||
dawn::native::MaybeError result =
|
dawn::native::MaybeError result =
|
||||||
dawn::native::ValidateSingleSType(&chain1, wgpu::SType::ShaderModuleWGSLDescriptor);
|
dawn::native::ValidateSingleSType(&chain1, wgpu::SType::ShaderModuleWGSLDescriptor);
|
||||||
|
|
|
@ -201,9 +201,9 @@ TEST_F(RequestDeviceValidationTest, LowerIsBetter) {
|
||||||
|
|
||||||
// Test that it is an error to request limits with an invalid chained struct
|
// Test that it is an error to request limits with an invalid chained struct
|
||||||
TEST_F(RequestDeviceValidationTest, InvalidChainedStruct) {
|
TEST_F(RequestDeviceValidationTest, InvalidChainedStruct) {
|
||||||
wgpu::PrimitiveDepthClampingState depthClamp = {};
|
wgpu::PrimitiveDepthClipControl depthClipControl = {};
|
||||||
wgpu::RequiredLimits limits = {};
|
wgpu::RequiredLimits limits = {};
|
||||||
limits.nextInChain = &depthClamp;
|
limits.nextInChain = &depthClipControl;
|
||||||
|
|
||||||
wgpu::DeviceDescriptor descriptor;
|
wgpu::DeviceDescriptor descriptor;
|
||||||
descriptor.requiredLimits = &limits;
|
descriptor.requiredLimits = &limits;
|
||||||
|
|
|
@ -975,15 +975,15 @@ TEST_F(RenderPipelineValidationTest, StripIndexFormatAllowed) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that specifying a clampDepth value is an error if the feature is not enabled.
|
// Test that specifying a unclippedDepth value is an error if the feature is not enabled.
|
||||||
TEST_F(RenderPipelineValidationTest, ClampDepthWithoutFeature) {
|
TEST_F(RenderPipelineValidationTest, UnclippedDepthWithoutFeature) {
|
||||||
{
|
{
|
||||||
utils::ComboRenderPipelineDescriptor descriptor;
|
utils::ComboRenderPipelineDescriptor descriptor;
|
||||||
descriptor.vertex.module = vsModule;
|
descriptor.vertex.module = vsModule;
|
||||||
descriptor.cFragment.module = fsModule;
|
descriptor.cFragment.module = fsModule;
|
||||||
wgpu::PrimitiveDepthClampingState clampingState;
|
wgpu::PrimitiveDepthClipControl depthClipControl;
|
||||||
clampingState.clampDepth = true;
|
depthClipControl.unclippedDepth = true;
|
||||||
descriptor.primitive.nextInChain = &clampingState;
|
descriptor.primitive.nextInChain = &depthClipControl;
|
||||||
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor),
|
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor),
|
||||||
testing::HasSubstr("not supported"));
|
testing::HasSubstr("not supported"));
|
||||||
}
|
}
|
||||||
|
@ -991,9 +991,9 @@ TEST_F(RenderPipelineValidationTest, ClampDepthWithoutFeature) {
|
||||||
utils::ComboRenderPipelineDescriptor descriptor;
|
utils::ComboRenderPipelineDescriptor descriptor;
|
||||||
descriptor.vertex.module = vsModule;
|
descriptor.vertex.module = vsModule;
|
||||||
descriptor.cFragment.module = fsModule;
|
descriptor.cFragment.module = fsModule;
|
||||||
wgpu::PrimitiveDepthClampingState clampingState;
|
wgpu::PrimitiveDepthClipControl depthClipControl;
|
||||||
clampingState.clampDepth = false;
|
depthClipControl.unclippedDepth = false;
|
||||||
descriptor.primitive.nextInChain = &clampingState;
|
descriptor.primitive.nextInChain = &depthClipControl;
|
||||||
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor),
|
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor),
|
||||||
testing::HasSubstr("not supported"));
|
testing::HasSubstr("not supported"));
|
||||||
}
|
}
|
||||||
|
@ -1023,24 +1023,6 @@ TEST_F(RenderPipelineValidationTest, DepthClipControlWithoutFeature) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that using both DepthClipControl and DepthClamp features is invalid.
|
|
||||||
TEST_F(RenderPipelineValidationTest, DepthClipControlAndDepthClampInvalid) {
|
|
||||||
utils::ComboRenderPipelineDescriptor descriptor;
|
|
||||||
descriptor.vertex.module = vsModule;
|
|
||||||
descriptor.cFragment.module = fsModule;
|
|
||||||
|
|
||||||
wgpu::PrimitiveDepthClipControl depthClipControl;
|
|
||||||
depthClipControl.unclippedDepth = false;
|
|
||||||
descriptor.primitive.nextInChain = &depthClipControl;
|
|
||||||
|
|
||||||
wgpu::PrimitiveDepthClampingState clampingState;
|
|
||||||
clampingState.clampDepth = false;
|
|
||||||
depthClipControl.nextInChain = &clampingState;
|
|
||||||
|
|
||||||
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor),
|
|
||||||
testing::HasSubstr("only contain a single chained struct"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that depthStencil.depthCompare must not be undefiend.
|
// Test that depthStencil.depthCompare must not be undefiend.
|
||||||
TEST_F(RenderPipelineValidationTest, DepthCompareUndefinedIsError) {
|
TEST_F(RenderPipelineValidationTest, DepthCompareUndefinedIsError) {
|
||||||
utils::ComboRenderPipelineDescriptor descriptor;
|
utils::ComboRenderPipelineDescriptor descriptor;
|
||||||
|
@ -1359,35 +1341,35 @@ TEST_F(RenderPipelineValidationTest, BindingsFromCorrectEntryPoint) {
|
||||||
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
|
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
class DepthClampingValidationTest : public RenderPipelineValidationTest {
|
class DepthClipControlValidationTest : public RenderPipelineValidationTest {
|
||||||
protected:
|
protected:
|
||||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||||
wgpu::DeviceDescriptor descriptor;
|
wgpu::DeviceDescriptor descriptor;
|
||||||
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::DepthClamping};
|
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::DepthClipControl};
|
||||||
descriptor.requiredFeatures = requiredFeatures;
|
descriptor.requiredFeatures = requiredFeatures;
|
||||||
descriptor.requiredFeaturesCount = 1;
|
descriptor.requiredFeaturesCount = 1;
|
||||||
return dawnAdapter.CreateDevice(&descriptor);
|
return dawnAdapter.CreateDevice(&descriptor);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Tests that specifying a clampDepth value succeeds if the feature is enabled.
|
// Tests that specifying a unclippedDepth value succeeds if the feature is enabled.
|
||||||
TEST_F(DepthClampingValidationTest, Success) {
|
TEST_F(DepthClipControlValidationTest, Success) {
|
||||||
{
|
{
|
||||||
utils::ComboRenderPipelineDescriptor descriptor;
|
utils::ComboRenderPipelineDescriptor descriptor;
|
||||||
descriptor.vertex.module = vsModule;
|
descriptor.vertex.module = vsModule;
|
||||||
descriptor.cFragment.module = fsModule;
|
descriptor.cFragment.module = fsModule;
|
||||||
wgpu::PrimitiveDepthClampingState clampingState;
|
wgpu::PrimitiveDepthClipControl depthClipControl;
|
||||||
clampingState.clampDepth = true;
|
depthClipControl.unclippedDepth = true;
|
||||||
descriptor.primitive.nextInChain = &clampingState;
|
descriptor.primitive.nextInChain = &depthClipControl;
|
||||||
device.CreateRenderPipeline(&descriptor);
|
device.CreateRenderPipeline(&descriptor);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
utils::ComboRenderPipelineDescriptor descriptor;
|
utils::ComboRenderPipelineDescriptor descriptor;
|
||||||
descriptor.vertex.module = vsModule;
|
descriptor.vertex.module = vsModule;
|
||||||
descriptor.cFragment.module = fsModule;
|
descriptor.cFragment.module = fsModule;
|
||||||
wgpu::PrimitiveDepthClampingState clampingState;
|
wgpu::PrimitiveDepthClipControl depthClipControl;
|
||||||
clampingState.clampDepth = false;
|
depthClipControl.unclippedDepth = false;
|
||||||
descriptor.primitive.nextInChain = &clampingState;
|
descriptor.primitive.nextInChain = &depthClipControl;
|
||||||
device.CreateRenderPipeline(&descriptor);
|
device.CreateRenderPipeline(&descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,10 +36,10 @@ TEST_F(WireExtensionTests, ChainedStruct) {
|
||||||
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiShaderModule));
|
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiShaderModule));
|
||||||
FlushClient();
|
FlushClient();
|
||||||
|
|
||||||
WGPUPrimitiveDepthClampingState clientExt = {};
|
WGPUPrimitiveDepthClipControl clientExt = {};
|
||||||
clientExt.chain.sType = WGPUSType_PrimitiveDepthClampingState;
|
clientExt.chain.sType = WGPUSType_PrimitiveDepthClipControl;
|
||||||
clientExt.chain.next = nullptr;
|
clientExt.chain.next = nullptr;
|
||||||
clientExt.clampDepth = true;
|
clientExt.unclippedDepth = true;
|
||||||
|
|
||||||
WGPURenderPipelineDescriptor renderPipelineDesc = {};
|
WGPURenderPipelineDescriptor renderPipelineDesc = {};
|
||||||
renderPipelineDesc.vertex.module = shaderModule;
|
renderPipelineDesc.vertex.module = shaderModule;
|
||||||
|
@ -50,10 +50,10 @@ TEST_F(WireExtensionTests, ChainedStruct) {
|
||||||
EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, NotNull()))
|
EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, NotNull()))
|
||||||
.WillOnce(Invoke(
|
.WillOnce(Invoke(
|
||||||
[&](Unused, const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
|
[&](Unused, const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
|
||||||
const auto* ext = reinterpret_cast<const WGPUPrimitiveDepthClampingState*>(
|
const auto* ext = reinterpret_cast<const WGPUPrimitiveDepthClipControl*>(
|
||||||
serverDesc->primitive.nextInChain);
|
serverDesc->primitive.nextInChain);
|
||||||
EXPECT_EQ(ext->chain.sType, clientExt.chain.sType);
|
EXPECT_EQ(ext->chain.sType, clientExt.chain.sType);
|
||||||
EXPECT_EQ(ext->clampDepth, true);
|
EXPECT_EQ(ext->unclippedDepth, true);
|
||||||
EXPECT_EQ(ext->chain.next, nullptr);
|
EXPECT_EQ(ext->chain.next, nullptr);
|
||||||
|
|
||||||
return api.GetNewRenderPipeline();
|
return api.GetNewRenderPipeline();
|
||||||
|
@ -69,15 +69,15 @@ TEST_F(WireExtensionTests, MutlipleChainedStructs) {
|
||||||
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiShaderModule));
|
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiShaderModule));
|
||||||
FlushClient();
|
FlushClient();
|
||||||
|
|
||||||
WGPUPrimitiveDepthClampingState clientExt2 = {};
|
WGPUPrimitiveDepthClipControl clientExt2 = {};
|
||||||
clientExt2.chain.sType = WGPUSType_PrimitiveDepthClampingState;
|
clientExt2.chain.sType = WGPUSType_PrimitiveDepthClipControl;
|
||||||
clientExt2.chain.next = nullptr;
|
clientExt2.chain.next = nullptr;
|
||||||
clientExt2.clampDepth = false;
|
clientExt2.unclippedDepth = false;
|
||||||
|
|
||||||
WGPUPrimitiveDepthClampingState clientExt1 = {};
|
WGPUPrimitiveDepthClipControl clientExt1 = {};
|
||||||
clientExt1.chain.sType = WGPUSType_PrimitiveDepthClampingState;
|
clientExt1.chain.sType = WGPUSType_PrimitiveDepthClipControl;
|
||||||
clientExt1.chain.next = &clientExt2.chain;
|
clientExt1.chain.next = &clientExt2.chain;
|
||||||
clientExt1.clampDepth = true;
|
clientExt1.unclippedDepth = true;
|
||||||
|
|
||||||
WGPURenderPipelineDescriptor renderPipelineDesc = {};
|
WGPURenderPipelineDescriptor renderPipelineDesc = {};
|
||||||
renderPipelineDesc.vertex.module = shaderModule;
|
renderPipelineDesc.vertex.module = shaderModule;
|
||||||
|
@ -88,15 +88,15 @@ TEST_F(WireExtensionTests, MutlipleChainedStructs) {
|
||||||
EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, NotNull()))
|
EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, NotNull()))
|
||||||
.WillOnce(Invoke(
|
.WillOnce(Invoke(
|
||||||
[&](Unused, const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
|
[&](Unused, const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
|
||||||
const auto* ext1 = reinterpret_cast<const WGPUPrimitiveDepthClampingState*>(
|
const auto* ext1 = reinterpret_cast<const WGPUPrimitiveDepthClipControl*>(
|
||||||
serverDesc->primitive.nextInChain);
|
serverDesc->primitive.nextInChain);
|
||||||
EXPECT_EQ(ext1->chain.sType, clientExt1.chain.sType);
|
EXPECT_EQ(ext1->chain.sType, clientExt1.chain.sType);
|
||||||
EXPECT_EQ(ext1->clampDepth, true);
|
EXPECT_EQ(ext1->unclippedDepth, true);
|
||||||
|
|
||||||
const auto* ext2 =
|
const auto* ext2 =
|
||||||
reinterpret_cast<const WGPUPrimitiveDepthClampingState*>(ext1->chain.next);
|
reinterpret_cast<const WGPUPrimitiveDepthClipControl*>(ext1->chain.next);
|
||||||
EXPECT_EQ(ext2->chain.sType, clientExt2.chain.sType);
|
EXPECT_EQ(ext2->chain.sType, clientExt2.chain.sType);
|
||||||
EXPECT_EQ(ext2->clampDepth, false);
|
EXPECT_EQ(ext2->unclippedDepth, false);
|
||||||
EXPECT_EQ(ext2->chain.next, nullptr);
|
EXPECT_EQ(ext2->chain.next, nullptr);
|
||||||
|
|
||||||
return api.GetNewRenderPipeline();
|
return api.GetNewRenderPipeline();
|
||||||
|
@ -112,15 +112,15 @@ TEST_F(WireExtensionTests, MutlipleChainedStructs) {
|
||||||
EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, NotNull()))
|
EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, NotNull()))
|
||||||
.WillOnce(Invoke(
|
.WillOnce(Invoke(
|
||||||
[&](Unused, const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
|
[&](Unused, const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
|
||||||
const auto* ext2 = reinterpret_cast<const WGPUPrimitiveDepthClampingState*>(
|
const auto* ext2 = reinterpret_cast<const WGPUPrimitiveDepthClipControl*>(
|
||||||
serverDesc->primitive.nextInChain);
|
serverDesc->primitive.nextInChain);
|
||||||
EXPECT_EQ(ext2->chain.sType, clientExt2.chain.sType);
|
EXPECT_EQ(ext2->chain.sType, clientExt2.chain.sType);
|
||||||
EXPECT_EQ(ext2->clampDepth, false);
|
EXPECT_EQ(ext2->unclippedDepth, false);
|
||||||
|
|
||||||
const auto* ext1 =
|
const auto* ext1 =
|
||||||
reinterpret_cast<const WGPUPrimitiveDepthClampingState*>(ext2->chain.next);
|
reinterpret_cast<const WGPUPrimitiveDepthClipControl*>(ext2->chain.next);
|
||||||
EXPECT_EQ(ext1->chain.sType, clientExt1.chain.sType);
|
EXPECT_EQ(ext1->chain.sType, clientExt1.chain.sType);
|
||||||
EXPECT_EQ(ext1->clampDepth, true);
|
EXPECT_EQ(ext1->unclippedDepth, true);
|
||||||
EXPECT_EQ(ext1->chain.next, nullptr);
|
EXPECT_EQ(ext1->chain.next, nullptr);
|
||||||
|
|
||||||
return api.GetNewRenderPipeline();
|
return api.GetNewRenderPipeline();
|
||||||
|
@ -136,7 +136,7 @@ TEST_F(WireExtensionTests, InvalidSType) {
|
||||||
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiShaderModule));
|
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiShaderModule));
|
||||||
FlushClient();
|
FlushClient();
|
||||||
|
|
||||||
WGPUPrimitiveDepthClampingState clientExt = {};
|
WGPUPrimitiveDepthClipControl clientExt = {};
|
||||||
clientExt.chain.sType = WGPUSType_Invalid;
|
clientExt.chain.sType = WGPUSType_Invalid;
|
||||||
clientExt.chain.next = nullptr;
|
clientExt.chain.next = nullptr;
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ TEST_F(WireExtensionTests, UnknownSType) {
|
||||||
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiShaderModule));
|
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiShaderModule));
|
||||||
FlushClient();
|
FlushClient();
|
||||||
|
|
||||||
WGPUPrimitiveDepthClampingState clientExt = {};
|
WGPUPrimitiveDepthClipControl clientExt = {};
|
||||||
clientExt.chain.sType = static_cast<WGPUSType>(-1);
|
clientExt.chain.sType = static_cast<WGPUSType>(-1);
|
||||||
clientExt.chain.next = nullptr;
|
clientExt.chain.next = nullptr;
|
||||||
|
|
||||||
|
@ -193,14 +193,14 @@ TEST_F(WireExtensionTests, ValidAndInvalidSTypeInChain) {
|
||||||
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiShaderModule));
|
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiShaderModule));
|
||||||
FlushClient();
|
FlushClient();
|
||||||
|
|
||||||
WGPUPrimitiveDepthClampingState clientExt2 = {};
|
WGPUPrimitiveDepthClipControl clientExt2 = {};
|
||||||
clientExt2.chain.sType = WGPUSType_Invalid;
|
clientExt2.chain.sType = WGPUSType_Invalid;
|
||||||
clientExt2.chain.next = nullptr;
|
clientExt2.chain.next = nullptr;
|
||||||
|
|
||||||
WGPUPrimitiveDepthClampingState clientExt1 = {};
|
WGPUPrimitiveDepthClipControl clientExt1 = {};
|
||||||
clientExt1.chain.sType = WGPUSType_PrimitiveDepthClampingState;
|
clientExt1.chain.sType = WGPUSType_PrimitiveDepthClipControl;
|
||||||
clientExt1.chain.next = &clientExt2.chain;
|
clientExt1.chain.next = &clientExt2.chain;
|
||||||
clientExt1.clampDepth = true;
|
clientExt1.unclippedDepth = true;
|
||||||
|
|
||||||
WGPURenderPipelineDescriptor renderPipelineDesc = {};
|
WGPURenderPipelineDescriptor renderPipelineDesc = {};
|
||||||
renderPipelineDesc.vertex.module = shaderModule;
|
renderPipelineDesc.vertex.module = shaderModule;
|
||||||
|
@ -211,10 +211,10 @@ TEST_F(WireExtensionTests, ValidAndInvalidSTypeInChain) {
|
||||||
EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, NotNull()))
|
EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, NotNull()))
|
||||||
.WillOnce(Invoke(
|
.WillOnce(Invoke(
|
||||||
[&](Unused, const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
|
[&](Unused, const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
|
||||||
const auto* ext = reinterpret_cast<const WGPUPrimitiveDepthClampingState*>(
|
const auto* ext = reinterpret_cast<const WGPUPrimitiveDepthClipControl*>(
|
||||||
serverDesc->primitive.nextInChain);
|
serverDesc->primitive.nextInChain);
|
||||||
EXPECT_EQ(ext->chain.sType, clientExt1.chain.sType);
|
EXPECT_EQ(ext->chain.sType, clientExt1.chain.sType);
|
||||||
EXPECT_EQ(ext->clampDepth, true);
|
EXPECT_EQ(ext->unclippedDepth, true);
|
||||||
|
|
||||||
EXPECT_EQ(ext->chain.next->sType, WGPUSType_Invalid);
|
EXPECT_EQ(ext->chain.next->sType, WGPUSType_Invalid);
|
||||||
EXPECT_EQ(ext->chain.next->next, nullptr);
|
EXPECT_EQ(ext->chain.next->next, nullptr);
|
||||||
|
@ -233,10 +233,10 @@ TEST_F(WireExtensionTests, ValidAndInvalidSTypeInChain) {
|
||||||
[&](Unused, const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
|
[&](Unused, const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
|
||||||
EXPECT_EQ(serverDesc->primitive.nextInChain->sType, WGPUSType_Invalid);
|
EXPECT_EQ(serverDesc->primitive.nextInChain->sType, WGPUSType_Invalid);
|
||||||
|
|
||||||
const auto* ext = reinterpret_cast<const WGPUPrimitiveDepthClampingState*>(
|
const auto* ext = reinterpret_cast<const WGPUPrimitiveDepthClipControl*>(
|
||||||
serverDesc->primitive.nextInChain->next);
|
serverDesc->primitive.nextInChain->next);
|
||||||
EXPECT_EQ(ext->chain.sType, clientExt1.chain.sType);
|
EXPECT_EQ(ext->chain.sType, clientExt1.chain.sType);
|
||||||
EXPECT_EQ(ext->clampDepth, true);
|
EXPECT_EQ(ext->unclippedDepth, true);
|
||||||
EXPECT_EQ(ext->chain.next, nullptr);
|
EXPECT_EQ(ext->chain.next, nullptr);
|
||||||
|
|
||||||
return api.GetNewRenderPipeline();
|
return api.GetNewRenderPipeline();
|
||||||
|
|
|
@ -32,7 +32,6 @@ bool IsFeatureSupported(WGPUFeatureName feature) {
|
||||||
case WGPUFeatureName_TextureCompressionASTC:
|
case WGPUFeatureName_TextureCompressionASTC:
|
||||||
case WGPUFeatureName_IndirectFirstInstance:
|
case WGPUFeatureName_IndirectFirstInstance:
|
||||||
case WGPUFeatureName_DepthClipControl:
|
case WGPUFeatureName_DepthClipControl:
|
||||||
case WGPUFeatureName_DepthClamping:
|
|
||||||
case WGPUFeatureName_DawnShaderFloat16:
|
case WGPUFeatureName_DawnShaderFloat16:
|
||||||
case WGPUFeatureName_DawnInternalUsages:
|
case WGPUFeatureName_DawnInternalUsages:
|
||||||
case WGPUFeatureName_DawnMultiPlanarFormats:
|
case WGPUFeatureName_DawnMultiPlanarFormats:
|
||||||
|
|
|
@ -246,10 +246,9 @@ crbug.com/dawn/0000 webgpu:util,texture,texel_data:unorm_texel_data_in_shader:fo
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# depth_clip_clamp failures
|
# depth_clip_clamp failures
|
||||||
# KEEP
|
|
||||||
################################################################################
|
################################################################################
|
||||||
crbug.com/dawn/0000 webgpu:api,operation,rendering,depth_clip_clamp:depth_clamp_and_clip:* [ Failure ]
|
crbug.com/dawn/1125 [ linux ] webgpu:api,operation,rendering,depth_clip_clamp:depth_clamp_and_clip:* [ Failure ]
|
||||||
crbug.com/dawn/0000 webgpu:api,operation,rendering,depth_clip_clamp:depth_test_input_clamped:* [ Failure ]
|
crbug.com/dawn/1125 [ linux ] webgpu:api,operation,rendering,depth_clip_clamp:depth_test_input_clamped:* [ Failure ]
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# compilation_info failures
|
# compilation_info failures
|
||||||
|
|
Loading…
Reference in New Issue