From 4d15609d269eb551fc73d27e75a498c1ab8f999d Mon Sep 17 00:00:00 2001 From: Austin Eng Date: Thu, 21 Nov 2019 00:48:39 +0000 Subject: [PATCH] Add a toggle to disable Dawn validation Trusted users of Dawn should be able to use it without the overhead of command validation. This patch adds the toggle and skips validation for object creation. Bug: dawn:271 Change-Id: Ica9a1988177685d73e2c36e05c4d525ad1ab0fdb Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/13802 Commit-Queue: Austin Eng Reviewed-by: Jiawei Shao --- src/dawn_native/Device.cpp | 52 ++++++++++++++++++------ src/dawn_native/Device.h | 1 + src/dawn_native/Toggles.cpp | 4 +- src/dawn_native/Toggles.h | 1 + src/tests/DawnTest.cpp | 24 +++++++++++ src/tests/DawnTest.h | 3 ++ src/tests/end2end/DestroyTests.cpp | 1 + src/tests/end2end/ObjectCachingTests.cpp | 2 + 8 files changed, 75 insertions(+), 13 deletions(-) diff --git a/src/dawn_native/Device.cpp b/src/dawn_native/Device.cpp index bfe8d09427..cade9001ef 100644 --- a/src/dawn_native/Device.cpp +++ b/src/dawn_native/Device.cpp @@ -617,6 +617,10 @@ namespace dawn_native { return mTogglesSet.IsEnabled(toggle); } + bool DeviceBase::IsValidationEnabled() const { + return !IsToggleEnabled(Toggle::SkipValidation); + } + size_t DeviceBase::GetLazyClearCountForTesting() { return mLazyClearCountForTesting; } @@ -634,7 +638,9 @@ namespace dawn_native { MaybeError DeviceBase::CreateBindGroupInternal(BindGroupBase** result, const BindGroupDescriptor* descriptor) { - DAWN_TRY(ValidateBindGroupDescriptor(this, descriptor)); + if (IsValidationEnabled()) { + DAWN_TRY(ValidateBindGroupDescriptor(this, descriptor)); + } DAWN_TRY_ASSIGN(*result, CreateBindGroupImpl(descriptor)); return {}; } @@ -642,14 +648,18 @@ namespace dawn_native { MaybeError DeviceBase::CreateBindGroupLayoutInternal( BindGroupLayoutBase** result, const BindGroupLayoutDescriptor* descriptor) { - DAWN_TRY(ValidateBindGroupLayoutDescriptor(this, descriptor)); + if (IsValidationEnabled()) { + DAWN_TRY(ValidateBindGroupLayoutDescriptor(this, descriptor)); + } DAWN_TRY_ASSIGN(*result, GetOrCreateBindGroupLayout(descriptor)); return {}; } MaybeError DeviceBase::CreateBufferInternal(BufferBase** result, const BufferDescriptor* descriptor) { - DAWN_TRY(ValidateBufferDescriptor(this, descriptor)); + if (IsValidationEnabled()) { + DAWN_TRY(ValidateBufferDescriptor(this, descriptor)); + } DAWN_TRY_ASSIGN(*result, CreateBufferImpl(descriptor)); return {}; } @@ -657,7 +667,9 @@ namespace dawn_native { MaybeError DeviceBase::CreateComputePipelineInternal( ComputePipelineBase** result, const ComputePipelineDescriptor* descriptor) { - DAWN_TRY(ValidateComputePipelineDescriptor(this, descriptor)); + if (IsValidationEnabled()) { + DAWN_TRY(ValidateComputePipelineDescriptor(this, descriptor)); + } DAWN_TRY_ASSIGN(*result, GetOrCreateComputePipeline(descriptor)); return {}; } @@ -665,7 +677,9 @@ namespace dawn_native { MaybeError DeviceBase::CreatePipelineLayoutInternal( PipelineLayoutBase** result, const PipelineLayoutDescriptor* descriptor) { - DAWN_TRY(ValidatePipelineLayoutDescriptor(this, descriptor)); + if (IsValidationEnabled()) { + DAWN_TRY(ValidatePipelineLayoutDescriptor(this, descriptor)); + } DAWN_TRY_ASSIGN(*result, GetOrCreatePipelineLayout(descriptor)); return {}; } @@ -678,7 +692,9 @@ namespace dawn_native { MaybeError DeviceBase::CreateRenderBundleEncoderInternal( RenderBundleEncoder** result, const RenderBundleEncoderDescriptor* descriptor) { - DAWN_TRY(ValidateRenderBundleEncoderDescriptor(this, descriptor)); + if (IsValidationEnabled()) { + DAWN_TRY(ValidateRenderBundleEncoderDescriptor(this, descriptor)); + } *result = new RenderBundleEncoder(this, descriptor); return {}; } @@ -686,35 +702,45 @@ namespace dawn_native { MaybeError DeviceBase::CreateRenderPipelineInternal( RenderPipelineBase** result, const RenderPipelineDescriptor* descriptor) { - DAWN_TRY(ValidateRenderPipelineDescriptor(this, descriptor)); + if (IsValidationEnabled()) { + DAWN_TRY(ValidateRenderPipelineDescriptor(this, descriptor)); + } DAWN_TRY_ASSIGN(*result, GetOrCreateRenderPipeline(descriptor)); return {}; } MaybeError DeviceBase::CreateSamplerInternal(SamplerBase** result, const SamplerDescriptor* descriptor) { - DAWN_TRY(ValidateSamplerDescriptor(this, descriptor)); + if (IsValidationEnabled()) { + DAWN_TRY(ValidateSamplerDescriptor(this, descriptor)); + } DAWN_TRY_ASSIGN(*result, GetOrCreateSampler(descriptor)); return {}; } MaybeError DeviceBase::CreateShaderModuleInternal(ShaderModuleBase** result, const ShaderModuleDescriptor* descriptor) { - DAWN_TRY(ValidateShaderModuleDescriptor(this, descriptor)); + if (IsValidationEnabled()) { + DAWN_TRY(ValidateShaderModuleDescriptor(this, descriptor)); + } DAWN_TRY_ASSIGN(*result, GetOrCreateShaderModule(descriptor)); return {}; } MaybeError DeviceBase::CreateSwapChainInternal(SwapChainBase** result, const SwapChainDescriptor* descriptor) { - DAWN_TRY(ValidateSwapChainDescriptor(this, descriptor)); + if (IsValidationEnabled()) { + DAWN_TRY(ValidateSwapChainDescriptor(this, descriptor)); + } DAWN_TRY_ASSIGN(*result, CreateSwapChainImpl(descriptor)); return {}; } MaybeError DeviceBase::CreateTextureInternal(TextureBase** result, const TextureDescriptor* descriptor) { - DAWN_TRY(ValidateTextureDescriptor(this, descriptor)); + if (IsValidationEnabled()) { + DAWN_TRY(ValidateTextureDescriptor(this, descriptor)); + } DAWN_TRY_ASSIGN(*result, CreateTextureImpl(descriptor)); return {}; } @@ -724,7 +750,9 @@ namespace dawn_native { const TextureViewDescriptor* descriptor) { DAWN_TRY(ValidateObject(texture)); TextureViewDescriptor desc = GetTextureViewDescriptorWithDefaults(texture, descriptor); - DAWN_TRY(ValidateTextureViewDescriptor(texture, &desc)); + if (IsValidationEnabled()) { + DAWN_TRY(ValidateTextureViewDescriptor(texture, &desc)); + } DAWN_TRY_ASSIGN(*result, CreateTextureViewImpl(texture, &desc)); return {}; } diff --git a/src/dawn_native/Device.h b/src/dawn_native/Device.h index a1e09e65a6..e887fa7c1a 100644 --- a/src/dawn_native/Device.h +++ b/src/dawn_native/Device.h @@ -185,6 +185,7 @@ namespace dawn_native { std::vector GetTogglesUsed() const; bool IsExtensionEnabled(Extension extension) const; bool IsToggleEnabled(Toggle toggle) const; + bool IsValidationEnabled() const; size_t GetLazyClearCountForTesting(); void IncrementLazyClearCountForTesting(); diff --git a/src/dawn_native/Toggles.cpp b/src/dawn_native/Toggles.cpp index f69ccd1a75..cfe825340a 100644 --- a/src/dawn_native/Toggles.cpp +++ b/src/dawn_native/Toggles.cpp @@ -80,7 +80,9 @@ namespace dawn_native { {"use_d3d12_render_pass", "Use the D3D12 render pass API introduced in Windows build 1809 by default. On " "versions of Windows prior to build 1809, or when this toggle is turned off, Dawn " - "will emulate a render pass."}}}}; + "will emulate a render pass."}}, + {Toggle::SkipValidation, + {"skip_validation", "Skip expensive validation of Dawn commands."}}}}; } // anonymous namespace void TogglesSet::SetToggle(Toggle toggle, bool enabled) { diff --git a/src/dawn_native/Toggles.h b/src/dawn_native/Toggles.h index 73db7f9d02..0d5aa7fbac 100644 --- a/src/dawn_native/Toggles.h +++ b/src/dawn_native/Toggles.h @@ -32,6 +32,7 @@ namespace dawn_native { UseTemporaryBufferInCompressedTextureToTextureCopy, UseD3D12ResourceHeapTier2, UseD3D12RenderPass, + SkipValidation, EnumCount, InvalidEnum = EnumCount, diff --git a/src/tests/DawnTest.cpp b/src/tests/DawnTest.cpp index 92b0224080..25654bab84 100644 --- a/src/tests/DawnTest.cpp +++ b/src/tests/DawnTest.cpp @@ -137,6 +137,11 @@ DawnTestEnvironment::DawnTestEnvironment(int argc, char** argv) { continue; } + if (strcmp("--skip-validation", argv[i]) == 0) { + mSkipDawnValidation = true; + continue; + } + constexpr const char kVendorIdFilterArg[] = "--adapter-vendor-id="; if (strstr(argv[i], kVendorIdFilterArg) == argv[i]) { const char* vendorIdFilter = argv[i] + strlen(kVendorIdFilterArg); @@ -156,6 +161,7 @@ DawnTestEnvironment::DawnTestEnvironment(int argc, char** argv) { " to disabled)\n" " -c, --begin-capture-on-startup: Begin debug capture on startup " "(defaults to no capture)\n" + " --skip-validation: Skip Dawn validation\n" " --adapter-vendor-id: Select adapter by vendor id to run end2end tests" "on multi-GPU systems \n" << std::endl; @@ -184,6 +190,9 @@ void DawnTestEnvironment::SetUp() { << "\n" "EnableBackendValidation: " << (mEnableBackendValidation ? "true" : "false") + << "\n" + "SkipDawnValidation: " + << (mSkipDawnValidation ? "true" : "false") << "\n" "BeginCaptureOnStartup: " << (mBeginCaptureOnStartup ? "true" : "false") @@ -228,6 +237,10 @@ bool DawnTestEnvironment::IsBackendValidationEnabled() const { return mEnableBackendValidation; } +bool DawnTestEnvironment::IsDawnValidationSkipped() const { + return mSkipDawnValidation; +} + dawn_native::Instance* DawnTestEnvironment::GetInstance() const { return mInstance.get(); } @@ -353,6 +366,10 @@ bool DawnTestBase::IsBackendValidationEnabled() const { return gTestEnv->IsBackendValidationEnabled(); } +bool DawnTestBase::IsDawnValidationSkipped() const { + return gTestEnv->IsDawnValidationSkipped(); +} + bool DawnTestBase::HasVendorIdFilter() const { return gTestEnv->HasVendorIdFilter(); } @@ -431,6 +448,13 @@ void DawnTestBase::SetUp() { deviceDescriptor.forceEnabledToggles = mParam.forceEnabledWorkarounds; deviceDescriptor.forceDisabledToggles = mParam.forceDisabledWorkarounds; deviceDescriptor.requiredExtensions = GetRequiredExtensions(); + + static constexpr char kSkipValidationToggle[] = "skip_validation"; + if (gTestEnv->IsDawnValidationSkipped()) { + ASSERT(gTestEnv->GetInstance()->GetToggleInfo(kSkipValidationToggle) != nullptr); + deviceDescriptor.forceEnabledToggles.push_back(kSkipValidationToggle); + } + backendDevice = mBackendAdapter.CreateDevice(&deviceDescriptor); ASSERT_NE(nullptr, backendDevice); diff --git a/src/tests/DawnTest.h b/src/tests/DawnTest.h index c271bb0d45..96ff946d80 100644 --- a/src/tests/DawnTest.h +++ b/src/tests/DawnTest.h @@ -134,6 +134,7 @@ class DawnTestEnvironment : public testing::Environment { bool UsesWire() const; bool IsBackendValidationEnabled() const; + bool IsDawnValidationSkipped() const; dawn_native::Instance* GetInstance() const; bool HasVendorIdFilter() const; uint32_t GetVendorIdFilter() const; @@ -146,6 +147,7 @@ class DawnTestEnvironment : public testing::Environment { bool mUseWire = false; bool mEnableBackendValidation = false; + bool mSkipDawnValidation = false; bool mBeginCaptureOnStartup = false; bool mHasVendorIdFilter = false; uint32_t mVendorIdFilter = 0; @@ -179,6 +181,7 @@ class DawnTestBase { bool UsesWire() const; bool IsBackendValidationEnabled() const; + bool IsDawnValidationSkipped() const; void StartExpectDeviceError(); bool EndExpectDeviceError(); diff --git a/src/tests/end2end/DestroyTests.cpp b/src/tests/end2end/DestroyTests.cpp index 916fb5599e..50f36fec37 100644 --- a/src/tests/end2end/DestroyTests.cpp +++ b/src/tests/end2end/DestroyTests.cpp @@ -23,6 +23,7 @@ class DestroyTest : public DawnTest { protected: void TestSetUp() override { DawnTest::TestSetUp(); + DAWN_SKIP_TEST_IF(IsDawnValidationSkipped()); renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize); diff --git a/src/tests/end2end/ObjectCachingTests.cpp b/src/tests/end2end/ObjectCachingTests.cpp index 4bd1910663..27aab13375 100644 --- a/src/tests/end2end/ObjectCachingTests.cpp +++ b/src/tests/end2end/ObjectCachingTests.cpp @@ -81,6 +81,8 @@ TEST_P(ObjectCachingTest, BindGroupLayoutTextureDimension) { // Test that an error object doesn't try to uncache itself TEST_P(ObjectCachingTest, ErrorObjectDoesntUncache) { + DAWN_SKIP_TEST_IF(IsDawnValidationSkipped()); + ASSERT_DEVICE_ERROR( wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout( device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::UniformBuffer},