diff --git a/src/dawn_native/Device.cpp b/src/dawn_native/Device.cpp index 7e33e3f710..e97a4bd030 100644 --- a/src/dawn_native/Device.cpp +++ b/src/dawn_native/Device.cpp @@ -709,6 +709,14 @@ namespace dawn_native { WGPUCreateComputePipelineAsyncCallback callback, void* userdata) { ComputePipelineBase* result = nullptr; + + if (IsToggleEnabled(Toggle::DisallowUnsafeAPIs)) { + ConsumedError( + DAWN_VALIDATION_ERROR("CreateComputePipelineAsync is disallowed because it isn't " + "completely implemented yet.")); + return; + } + MaybeError maybeError = CreateComputePipelineInternal(&result, descriptor); if (maybeError.IsError()) { std::unique_ptr error = maybeError.AcquireError(); @@ -753,6 +761,14 @@ namespace dawn_native { WGPUCreateRenderPipelineAsyncCallback callback, void* userdata) { RenderPipelineBase* result = nullptr; + + if (IsToggleEnabled(Toggle::DisallowUnsafeAPIs)) { + ConsumedError( + DAWN_VALIDATION_ERROR("CreateRenderPipelineAsync is disallowed because it isn't " + "completely implemented yet.")); + return; + } + MaybeError maybeError = CreateRenderPipelineInternal(&result, descriptor); if (maybeError.IsError()) { std::unique_ptr error = maybeError.AcquireError(); diff --git a/src/tests/unittests/validation/UnsafeAPIValidationTests.cpp b/src/tests/unittests/validation/UnsafeAPIValidationTests.cpp index 4ba2194e9e..bb07e48ad5 100644 --- a/src/tests/unittests/validation/UnsafeAPIValidationTests.cpp +++ b/src/tests/unittests/validation/UnsafeAPIValidationTests.cpp @@ -211,3 +211,54 @@ TEST_F(UnsafeAPIValidationTest, OcclusionQueryDisallowed) { ASSERT_DEVICE_ERROR(encoder.Finish()); } } + +// Check that CreateComputePipelineAsync is disallowed as part of unsafe APIs +TEST_F(UnsafeAPIValidationTest, CreateComputePipelineAsyncDisallowed) { + wgpu::ComputePipelineDescriptor desc; + desc.computeStage.module = utils::CreateShaderModuleFromWGSL(device, R"( + [[stage(compute)]] fn main() -> void { + })"); + desc.computeStage.entryPoint = "main"; + + // Control case: CreateComputePipeline is allowed. + device.CreateComputePipeline(&desc); + + // Error case: CreateComputePipelineAsync is disallowed. + ASSERT_DEVICE_ERROR(device.CreateComputePipelineAsync( + &desc, + [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline returnPipeline, + const char* message, void* userdata) { + // Status can be Error or Unkown (when using the wire). + EXPECT_NE(WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_Success, status); + }, + nullptr)); +} + +// Check that CreateRenderPipelineAsync is disallowed as part of unsafe APIs +TEST_F(UnsafeAPIValidationTest, CreateRenderPipelineAsyncDisallowed) { + utils::ComboRenderPipelineDescriptor desc(device); + desc.vertexStage.module = utils::CreateShaderModuleFromWGSL(device, R"( + [[builtin(position)]] var Position : vec4; + [[stage(vertex)]] fn main() -> void { + Position = vec4(0.0, 0.0, 0.0, 1.0); + })"); + desc.cFragmentStage.module = utils::CreateShaderModuleFromWGSL(device, R"( + [[location(0)]] var o_color : vec4; + [[stage(fragment)]] fn main() -> void { + o_color = vec4(0.0, 1.0, 0.0, 1.0); + })"); + desc.cColorStates[0].format = wgpu::TextureFormat::RGBA8Unorm; + + // Control case: CreateRenderPipeline is allowed. + device.CreateRenderPipeline(&desc); + + // Error case: CreateRenderPipelineAsync is disallowed. + ASSERT_DEVICE_ERROR(device.CreateRenderPipelineAsync( + &desc, + [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline returnPipeline, + const char* message, void* userdata) { + // Status can be Error or Unkown (when using the wire). + EXPECT_NE(WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_Success, status); + }, + nullptr)); +}