mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-19 01:46:35 +00:00
Handle DeviceLost error
Handle DeviceLostCallback once DeviceLost error occurs. Disallow any other commands or actions on device to happen after device has been lost. Bug: dawn:68 Change-Id: Icbbbadf278cae5e6213050d00439118789c863dc Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/12801 Commit-Queue: Natasha Lee <natlee@microsoft.com> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
0c66bcd13a
commit
0ecc48ecb7
@@ -582,6 +582,7 @@ void DawnTestBase::SetUp() {
|
||||
queue = device.CreateQueue();
|
||||
|
||||
device.SetUncapturedErrorCallback(OnDeviceError, this);
|
||||
device.SetDeviceLostCallback(OnDeviceLost, this);
|
||||
}
|
||||
|
||||
void DawnTestBase::TearDown() {
|
||||
@@ -618,6 +619,10 @@ void DawnTestBase::OnDeviceError(WGPUErrorType type, const char* message, void*
|
||||
self->mError = true;
|
||||
}
|
||||
|
||||
void DawnTestBase::OnDeviceLost(const char* message, void* userdata) {
|
||||
FAIL() << "Device Lost during test: " << message;
|
||||
}
|
||||
|
||||
std::ostringstream& DawnTestBase::AddBufferExpectation(const char* file,
|
||||
int line,
|
||||
const wgpu::Buffer& buffer,
|
||||
|
||||
@@ -249,6 +249,7 @@ class DawnTestBase {
|
||||
|
||||
// Tracking for validation errors
|
||||
static void OnDeviceError(WGPUErrorType type, const char* message, void* userdata);
|
||||
static void OnDeviceLost(const char* message, void* userdata);
|
||||
bool mExpectError = false;
|
||||
bool mError = false;
|
||||
|
||||
|
||||
192
src/tests/end2end/DeviceLostTests.cpp
Normal file
192
src/tests/end2end/DeviceLostTests.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
// Copyright 2019 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "tests/DawnTest.h"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/WGPUHelpers.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace testing;
|
||||
|
||||
class MockDeviceLostCallback {
|
||||
public:
|
||||
MOCK_METHOD2(Call, void(const char* message, void* userdata));
|
||||
};
|
||||
|
||||
static std::unique_ptr<MockDeviceLostCallback> mockDeviceLostCallback;
|
||||
static void ToMockDeviceLostCallback(const char* message, void* userdata) {
|
||||
mockDeviceLostCallback->Call(message, userdata);
|
||||
DawnTestBase* self = static_cast<DawnTestBase*>(userdata);
|
||||
self->StartExpectDeviceError();
|
||||
}
|
||||
|
||||
class DeviceLostTest : public DawnTest {
|
||||
protected:
|
||||
void TestSetUp() override {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
DawnTest::TestSetUp();
|
||||
mockDeviceLostCallback = std::make_unique<MockDeviceLostCallback>();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
DawnTest::TearDown();
|
||||
mockDeviceLostCallback = nullptr;
|
||||
}
|
||||
|
||||
void SetCallbackAndLoseForTesting() {
|
||||
device.SetDeviceLostCallback(ToMockDeviceLostCallback, this);
|
||||
EXPECT_CALL(*mockDeviceLostCallback, Call(_, this)).Times(1);
|
||||
device.LoseForTesting();
|
||||
}
|
||||
};
|
||||
|
||||
// Test that DeviceLostCallback is invoked when LostForTestimg is called
|
||||
TEST_P(DeviceLostTest, DeviceLostCallbackIsCalled) {
|
||||
SetCallbackAndLoseForTesting();
|
||||
}
|
||||
|
||||
// Test that submit fails when device is lost
|
||||
TEST_P(DeviceLostTest, SubmitFails) {
|
||||
wgpu::CommandBuffer commands;
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
commands = encoder.Finish();
|
||||
|
||||
SetCallbackAndLoseForTesting();
|
||||
ASSERT_DEVICE_ERROR(queue.Submit(0, &commands));
|
||||
}
|
||||
|
||||
// Test that CreateBindGroupLayout fails when device is lost
|
||||
TEST_P(DeviceLostTest, CreateBindGroupLayoutFails) {
|
||||
SetCallbackAndLoseForTesting();
|
||||
|
||||
wgpu::BindGroupLayoutBinding binding = {0, wgpu::ShaderStage::None,
|
||||
wgpu::BindingType::UniformBuffer};
|
||||
wgpu::BindGroupLayoutDescriptor descriptor;
|
||||
descriptor.bindingCount = 1;
|
||||
descriptor.bindings = &binding;
|
||||
ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&descriptor));
|
||||
}
|
||||
|
||||
// Test that CreateBindGroup fails when device is lost
|
||||
TEST_P(DeviceLostTest, CreateBindGroupFails) {
|
||||
SetCallbackAndLoseForTesting();
|
||||
|
||||
wgpu::BindGroupBinding binding;
|
||||
binding.binding = 0;
|
||||
binding.sampler = nullptr;
|
||||
binding.textureView = nullptr;
|
||||
binding.buffer = nullptr;
|
||||
binding.offset = 0;
|
||||
binding.size = 0;
|
||||
|
||||
wgpu::BindGroupDescriptor descriptor;
|
||||
descriptor.layout = nullptr;
|
||||
descriptor.bindingCount = 1;
|
||||
descriptor.bindings = &binding;
|
||||
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||
}
|
||||
|
||||
// Test that CreatePipelineLayout fails when device is lost
|
||||
TEST_P(DeviceLostTest, CreatePipelineLayoutFails) {
|
||||
SetCallbackAndLoseForTesting();
|
||||
|
||||
wgpu::PipelineLayoutDescriptor descriptor;
|
||||
descriptor.bindGroupLayoutCount = 0;
|
||||
descriptor.bindGroupLayouts = nullptr;
|
||||
ASSERT_DEVICE_ERROR(device.CreatePipelineLayout(&descriptor));
|
||||
}
|
||||
|
||||
// Tests that CreateRenderBundleEncoder fails when device is lost
|
||||
TEST_P(DeviceLostTest, CreateRenderBundleEncoderFails) {
|
||||
SetCallbackAndLoseForTesting();
|
||||
|
||||
wgpu::RenderBundleEncoderDescriptor descriptor;
|
||||
descriptor.colorFormatsCount = 0;
|
||||
descriptor.colorFormats = nullptr;
|
||||
ASSERT_DEVICE_ERROR(device.CreateRenderBundleEncoder(&descriptor));
|
||||
}
|
||||
|
||||
// Tests that CreateComputePipeline fails when device is lost
|
||||
TEST_P(DeviceLostTest, CreateComputePipelineFails) {
|
||||
SetCallbackAndLoseForTesting();
|
||||
|
||||
wgpu::ComputePipelineDescriptor descriptor;
|
||||
descriptor.layout = nullptr;
|
||||
descriptor.computeStage.module = nullptr;
|
||||
descriptor.nextInChain = nullptr;
|
||||
ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&descriptor));
|
||||
}
|
||||
|
||||
// Tests that CreateRenderPipeline fails when device is lost
|
||||
TEST_P(DeviceLostTest, CreateRenderPipelineFails) {
|
||||
SetCallbackAndLoseForTesting();
|
||||
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
|
||||
}
|
||||
|
||||
// Tests that CreateSampler fails when device is lost
|
||||
TEST_P(DeviceLostTest, CreateSamplerFails) {
|
||||
SetCallbackAndLoseForTesting();
|
||||
|
||||
wgpu::SamplerDescriptor descriptor = utils::GetDefaultSamplerDescriptor();
|
||||
ASSERT_DEVICE_ERROR(device.CreateSampler(&descriptor));
|
||||
}
|
||||
|
||||
// Tests that CreateShaderModule fails when device is lost
|
||||
TEST_P(DeviceLostTest, CreateShaderModuleFails) {
|
||||
SetCallbackAndLoseForTesting();
|
||||
|
||||
ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
|
||||
#version 450
|
||||
layout(location = 0) in vec4 color;
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
fragColor = color;
|
||||
})"));
|
||||
}
|
||||
|
||||
// Tests that CreateSwapChain fails when device is lost
|
||||
TEST_P(DeviceLostTest, CreateSwapChainFails) {
|
||||
SetCallbackAndLoseForTesting();
|
||||
|
||||
wgpu::SwapChainDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
ASSERT_DEVICE_ERROR(device.CreateSwapChain(&descriptor));
|
||||
}
|
||||
|
||||
// Tests that CreateTexture fails when device is lost
|
||||
TEST_P(DeviceLostTest, CreateTextureFails) {
|
||||
SetCallbackAndLoseForTesting();
|
||||
|
||||
wgpu::TextureDescriptor descriptor;
|
||||
descriptor.size.width = 4;
|
||||
descriptor.size.height = 4;
|
||||
descriptor.size.depth = 1;
|
||||
descriptor.arrayLayerCount = 1;
|
||||
descriptor.mipLevelCount = 1;
|
||||
descriptor.dimension = wgpu::TextureDimension::e2D;
|
||||
descriptor.usage = wgpu::TextureUsage::OutputAttachment;
|
||||
|
||||
ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
|
||||
}
|
||||
|
||||
TEST_P(DeviceLostTest, TickFails) {
|
||||
SetCallbackAndLoseForTesting();
|
||||
ASSERT_DEVICE_ERROR(device.Tick());
|
||||
}
|
||||
DAWN_INSTANTIATE_TEST(DeviceLostTest, D3D12Backend, VulkanBackend);
|
||||
Reference in New Issue
Block a user