Update Dawn tests and fuzzers to create adapters/devices on the wire
Previously, the device/adapter were all created on the service-side of a test, and then injected into the client side. Injected devices and adapters do not support querying limits and features. This CL changes setup so that adapter and device creation is always initiated by the client - and the implementation on the service side may be overridden for test fixture-specific behavior. It also adds more fuzzing coverage since the fuzzers can now also create adapters and devices. Bug: dawn:689 Change-Id: Ief7faa1908ceae973dcb2f600bf4dd1cf5417704 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/91680 Reviewed-by: Loko Kung <lokokung@google.com> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
8fa07c6470
commit
81b97656bc
|
@ -25,21 +25,11 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
|
|||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
return DawnWireServerFuzzer::Run(
|
||||
data, size,
|
||||
[](dawn::native::Instance* instance) {
|
||||
std::vector<dawn::native::Adapter> adapters = instance->GetAdapters();
|
||||
|
||||
wgpu::Device device;
|
||||
for (dawn::native::Adapter adapter : adapters) {
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
|
||||
if (properties.backendType == wgpu::BackendType::D3D12 &&
|
||||
properties.adapterType == wgpu::AdapterType::CPU) {
|
||||
device = wgpu::Device::Acquire(adapter.CreateDevice());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return device;
|
||||
[](const dawn::native::Adapter& adapter) {
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
return properties.backendType == wgpu::BackendType::D3D12 &&
|
||||
properties.adapterType == wgpu::AdapterType::CPU;
|
||||
},
|
||||
true /* supportsErrorInjection */);
|
||||
}
|
||||
|
|
|
@ -26,22 +26,10 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
|
|||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
return DawnWireServerFuzzer::Run(
|
||||
data, size,
|
||||
[](dawn::native::Instance* instance) {
|
||||
std::vector<dawn::native::Adapter> adapters = instance->GetAdapters();
|
||||
|
||||
wgpu::Device nullDevice;
|
||||
for (dawn::native::Adapter adapter : adapters) {
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
|
||||
if (properties.backendType == wgpu::BackendType::Null) {
|
||||
nullDevice = wgpu::Device::Acquire(adapter.CreateDevice());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(nullDevice.Get() != nullptr);
|
||||
return nullDevice;
|
||||
[](const dawn::native::Adapter& adapter) {
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
return properties.backendType == wgpu::BackendType::Null;
|
||||
},
|
||||
false /* supportsErrorInjection */);
|
||||
}
|
||||
|
|
|
@ -25,21 +25,12 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
|
|||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
return DawnWireServerFuzzer::Run(
|
||||
data, size,
|
||||
[](dawn::native::Instance* instance) {
|
||||
std::vector<dawn::native::Adapter> adapters = instance->GetAdapters();
|
||||
[](const dawn::native::Adapter& adapter) {
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
|
||||
wgpu::Device device;
|
||||
for (dawn::native::Adapter adapter : adapters) {
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
|
||||
if (properties.backendType == wgpu::BackendType::Vulkan &&
|
||||
properties.adapterType == wgpu::AdapterType::CPU) {
|
||||
device = wgpu::Device::Acquire(adapter.CreateDevice());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return device;
|
||||
return properties.backendType == wgpu::BackendType::Vulkan &&
|
||||
properties.adapterType == wgpu::AdapterType::CPU;
|
||||
},
|
||||
true /* supportsErrorInjection */);
|
||||
}
|
||||
|
|
|
@ -49,8 +49,7 @@ class DevNull : public dawn::wire::CommandSerializer {
|
|||
|
||||
std::unique_ptr<dawn::native::Instance> sInstance;
|
||||
WGPUProcDeviceCreateSwapChain sOriginalDeviceCreateSwapChain = nullptr;
|
||||
|
||||
bool sCommandsComplete = false;
|
||||
static bool (*sAdapterSupported)(const dawn::native::Adapter&) = nullptr;
|
||||
|
||||
WGPUSwapChain ErrorDeviceCreateSwapChain(WGPUDevice device,
|
||||
WGPUSurface surface,
|
||||
|
@ -75,7 +74,7 @@ int DawnWireServerFuzzer::Initialize(int* argc, char*** argv) {
|
|||
|
||||
int DawnWireServerFuzzer::Run(const uint8_t* data,
|
||||
size_t size,
|
||||
MakeDeviceFn MakeDevice,
|
||||
bool (*AdapterSupported)(const dawn::native::Adapter&),
|
||||
bool supportsErrorInjection) {
|
||||
// We require at least the injected error index.
|
||||
if (size < sizeof(uint64_t)) {
|
||||
|
@ -96,6 +95,8 @@ int DawnWireServerFuzzer::Run(const uint8_t* data,
|
|||
dawn::native::InjectErrorAt(injectedErrorIndex);
|
||||
}
|
||||
|
||||
sAdapterSupported = AdapterSupported;
|
||||
|
||||
DawnProcTable procs = dawn::native::GetProcs();
|
||||
|
||||
// Swapchains receive a pointer to an implementation. The fuzzer will pass garbage in so we
|
||||
|
@ -105,14 +106,23 @@ int DawnWireServerFuzzer::Run(const uint8_t* data,
|
|||
sOriginalDeviceCreateSwapChain = procs.deviceCreateSwapChain;
|
||||
procs.deviceCreateSwapChain = ErrorDeviceCreateSwapChain;
|
||||
|
||||
dawnProcSetProcs(&procs);
|
||||
// Override requestAdapter to find an adapter that the fuzzer supports.
|
||||
procs.instanceRequestAdapter = [](WGPUInstance cInstance,
|
||||
const WGPURequestAdapterOptions* options,
|
||||
WGPURequestAdapterCallback callback, void* userdata) {
|
||||
std::vector<dawn::native::Adapter> adapters = sInstance->GetAdapters();
|
||||
for (dawn::native::Adapter adapter : adapters) {
|
||||
if (sAdapterSupported(adapter)) {
|
||||
WGPUAdapter cAdapter = adapter.Get();
|
||||
dawn::native::GetProcs().adapterReference(cAdapter);
|
||||
callback(WGPURequestAdapterStatus_Success, cAdapter, nullptr, userdata);
|
||||
return;
|
||||
}
|
||||
}
|
||||
callback(WGPURequestAdapterStatus_Unavailable, nullptr, "No supported adapter.", userdata);
|
||||
};
|
||||
|
||||
wgpu::Device device = MakeDevice(sInstance.get());
|
||||
if (!device) {
|
||||
// We should only ever fail device creation if an error was injected.
|
||||
ASSERT(supportsErrorInjection);
|
||||
return 0;
|
||||
}
|
||||
dawnProcSetProcs(&procs);
|
||||
|
||||
DevNull devNull;
|
||||
dawn::wire::WireServerDescriptor serverDesc = {};
|
||||
|
@ -120,21 +130,11 @@ int DawnWireServerFuzzer::Run(const uint8_t* data,
|
|||
serverDesc.serializer = &devNull;
|
||||
|
||||
std::unique_ptr<dawn::wire::WireServer> wireServer(new dawn_wire::WireServer(serverDesc));
|
||||
wireServer->InjectDevice(device.Get(), 1, 0);
|
||||
|
||||
wireServer->InjectInstance(sInstance->Get(), 1, 0);
|
||||
wireServer->HandleCommands(reinterpret_cast<const char*>(data), size);
|
||||
|
||||
// Wait for all previous commands before destroying the server.
|
||||
// TODO(enga): Improve this when we improve/finalize how processing events happens.
|
||||
{
|
||||
device.GetQueue().OnSubmittedWorkDone(
|
||||
0u, [](WGPUQueueWorkDoneStatus, void*) { sCommandsComplete = true; }, nullptr);
|
||||
while (!sCommandsComplete) {
|
||||
device.Tick();
|
||||
utils::USleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
// Note: Deleting the server will release all created objects.
|
||||
// Deleted devices will wait for idle on destruction.
|
||||
wireServer = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -22,17 +22,18 @@
|
|||
|
||||
namespace dawn::native {
|
||||
|
||||
class Instance;
|
||||
class Adapter;
|
||||
|
||||
} // namespace dawn::native
|
||||
|
||||
namespace DawnWireServerFuzzer {
|
||||
|
||||
using MakeDeviceFn = std::function<wgpu::Device(dawn::native::Instance*)>;
|
||||
|
||||
int Initialize(int* argc, char*** argv);
|
||||
|
||||
int Run(const uint8_t* data, size_t size, MakeDeviceFn MakeDevice, bool supportsErrorInjection);
|
||||
int Run(const uint8_t* data,
|
||||
size_t size,
|
||||
bool (*AdapterSupported)(const dawn::native::Adapter&),
|
||||
bool supportsErrorInjection);
|
||||
|
||||
} // namespace DawnWireServerFuzzer
|
||||
|
||||
|
|
|
@ -90,6 +90,7 @@ struct MapReadUserdata {
|
|||
};
|
||||
|
||||
DawnTestEnvironment* gTestEnv = nullptr;
|
||||
DawnTestBase* gCurrentTest = nullptr;
|
||||
|
||||
template <typename T>
|
||||
void printBuffer(testing::AssertionResult& result, const T* buffer, const size_t count) {
|
||||
|
@ -711,14 +712,68 @@ const std::vector<std::string>& DawnTestEnvironment::GetDisabledToggles() const
|
|||
|
||||
// Implementation of DawnTest
|
||||
|
||||
DawnTestBase::DawnTestBase(const AdapterTestParam& param)
|
||||
: mParam(param),
|
||||
mWireHelper(utils::CreateWireHelper(gTestEnv->UsesWire(), gTestEnv->GetWireTraceDir())) {}
|
||||
DawnTestBase::DawnTestBase(const AdapterTestParam& param) : mParam(param) {
|
||||
gCurrentTest = this;
|
||||
|
||||
DawnProcTable procs = dawn::native::GetProcs();
|
||||
// Override procs to provide harness-specific behavior to always select the null adapter,
|
||||
// and to allow fixture-specific overriding of the test device with CreateDeviceImpl.
|
||||
procs.instanceRequestAdapter = [](WGPUInstance instance, const WGPURequestAdapterOptions*,
|
||||
WGPURequestAdapterCallback callback, void* userdata) {
|
||||
ASSERT(gCurrentTest);
|
||||
|
||||
// Find the adapter that exactly matches our adapter properties.
|
||||
const auto& adapters = gTestEnv->GetInstance()->GetAdapters();
|
||||
const auto& it = std::find_if(
|
||||
adapters.begin(), adapters.end(), [&](const dawn::native::Adapter& adapter) {
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
|
||||
const auto& param = gCurrentTest->mParam;
|
||||
return (param.adapterProperties.selected &&
|
||||
properties.deviceID == param.adapterProperties.deviceID &&
|
||||
properties.vendorID == param.adapterProperties.vendorID &&
|
||||
properties.adapterType == param.adapterProperties.adapterType &&
|
||||
properties.backendType == param.adapterProperties.backendType &&
|
||||
strcmp(properties.name, param.adapterProperties.adapterName.c_str()) == 0);
|
||||
});
|
||||
ASSERT(it != adapters.end());
|
||||
gCurrentTest->mBackendAdapter = *it;
|
||||
|
||||
WGPUAdapter cAdapter = it->Get();
|
||||
ASSERT(cAdapter);
|
||||
dawn::native::GetProcs().adapterReference(cAdapter);
|
||||
callback(WGPURequestAdapterStatus_Success, cAdapter, nullptr, userdata);
|
||||
};
|
||||
|
||||
procs.adapterRequestDevice = [](WGPUAdapter adapter, const WGPUDeviceDescriptor*,
|
||||
WGPURequestDeviceCallback callback, void* userdata) {
|
||||
ASSERT(gCurrentTest);
|
||||
|
||||
// Isolation keys may be enqueued by CreateDevice(std::string isolationKey).
|
||||
// CreateDevice calls requestAdapter, so consume them there and forward them
|
||||
// to CreateDeviceImpl.
|
||||
std::string isolationKey;
|
||||
if (!gCurrentTest->mNextIsolationKeyQueue.empty()) {
|
||||
isolationKey = std::move(gCurrentTest->mNextIsolationKeyQueue.front());
|
||||
gCurrentTest->mNextIsolationKeyQueue.pop();
|
||||
}
|
||||
WGPUDevice cDevice = gCurrentTest->CreateDeviceImpl(std::move(isolationKey));
|
||||
ASSERT(cDevice != nullptr);
|
||||
|
||||
gCurrentTest->mLastCreatedBackendDevice = cDevice;
|
||||
callback(WGPURequestDeviceStatus_Success, cDevice, nullptr, userdata);
|
||||
};
|
||||
|
||||
mWireHelper = utils::CreateWireHelper(procs, gTestEnv->UsesWire(), gTestEnv->GetWireTraceDir());
|
||||
}
|
||||
|
||||
DawnTestBase::~DawnTestBase() {
|
||||
mReadbackSlots.clear();
|
||||
queue = wgpu::Queue();
|
||||
device = wgpu::Device();
|
||||
queue = nullptr;
|
||||
device = nullptr;
|
||||
mAdapter = nullptr;
|
||||
mInstance = nullptr;
|
||||
|
||||
// D3D12's GPU-based validation will accumulate objects over time if the backend device is not
|
||||
// destroyed and recreated, so we reset it here.
|
||||
|
@ -729,6 +784,8 @@ DawnTestBase::~DawnTestBase() {
|
|||
|
||||
// Check that all devices were destructed.
|
||||
EXPECT_EQ(gTestEnv->GetInstance()->GetDeviceCountForTesting(), 0u);
|
||||
|
||||
gCurrentTest = nullptr;
|
||||
}
|
||||
|
||||
bool DawnTestBase::IsD3D12() const {
|
||||
|
@ -895,10 +952,9 @@ const wgpu::AdapterProperties& DawnTestBase::GetAdapterProperties() const {
|
|||
}
|
||||
|
||||
wgpu::SupportedLimits DawnTestBase::GetSupportedLimits() {
|
||||
WGPUSupportedLimits supportedLimits;
|
||||
supportedLimits.nextInChain = nullptr;
|
||||
dawn::native::GetProcs().deviceGetLimits(backendDevice, &supportedLimits);
|
||||
return *reinterpret_cast<wgpu::SupportedLimits*>(&supportedLimits);
|
||||
wgpu::SupportedLimits supportedLimits = {};
|
||||
device.GetLimits(&supportedLimits);
|
||||
return supportedLimits;
|
||||
}
|
||||
|
||||
bool DawnTestBase::SupportsFeatures(const std::vector<wgpu::FeatureName>& features) {
|
||||
|
@ -923,10 +979,7 @@ bool DawnTestBase::SupportsFeatures(const std::vector<wgpu::FeatureName>& featur
|
|||
return true;
|
||||
}
|
||||
|
||||
std::pair<wgpu::Device, WGPUDevice> DawnTestBase::CreateDeviceImpl(std::string isolationKey) {
|
||||
// TODO(dawn:1399) Always flush wire before creating to avoid reuse of the same handle.
|
||||
FlushWire();
|
||||
|
||||
WGPUDevice DawnTestBase::CreateDeviceImpl(std::string isolationKey) {
|
||||
// Create the device from the adapter
|
||||
for (const char* forceEnabledWorkaround : mParam.forceEnabledWorkarounds) {
|
||||
ASSERT(gTestEnv->GetInstance()->GetToggleInfo(forceEnabledWorkaround) != nullptr);
|
||||
|
@ -977,19 +1030,38 @@ std::pair<wgpu::Device, WGPUDevice> DawnTestBase::CreateDeviceImpl(std::string i
|
|||
togglesDesc.nextInChain = &cacheDesc;
|
||||
cacheDesc.isolationKey = isolationKey.c_str();
|
||||
|
||||
auto devices = mWireHelper->RegisterDevice(mBackendAdapter.CreateDevice(&deviceDescriptor));
|
||||
wgpu::Device device = devices.first;
|
||||
return mBackendAdapter.CreateDevice(&deviceDescriptor);
|
||||
}
|
||||
|
||||
wgpu::Device DawnTestBase::CreateDevice(std::string isolationKey) {
|
||||
wgpu::Device apiDevice;
|
||||
|
||||
// The isolation key will be consumed inside adapterRequestDevice and passed
|
||||
// to CreateDeviceImpl.
|
||||
mNextIsolationKeyQueue.push(std::move(isolationKey));
|
||||
|
||||
// This descriptor doesn't matter since device selection is overriden by CreateDeviceImpl.
|
||||
wgpu::DeviceDescriptor deviceDesc = {};
|
||||
mAdapter.RequestDevice(
|
||||
&deviceDesc,
|
||||
[](WGPURequestDeviceStatus, WGPUDevice cDevice, const char*, void* userdata) {
|
||||
*static_cast<wgpu::Device*>(userdata) = wgpu::Device::Acquire(cDevice);
|
||||
},
|
||||
&apiDevice);
|
||||
FlushWire();
|
||||
ASSERT(apiDevice);
|
||||
|
||||
// Set up the mocks for uncaptured errors and device loss. The loss of the device is expected
|
||||
// to happen at the end of the test so at it directly.
|
||||
device.SetUncapturedErrorCallback(mDeviceErrorCallback.Callback(),
|
||||
mDeviceErrorCallback.MakeUserdata(device.Get()));
|
||||
device.SetDeviceLostCallback(mDeviceLostCallback.Callback(),
|
||||
mDeviceLostCallback.MakeUserdata(device.Get()));
|
||||
EXPECT_CALL(mDeviceLostCallback, Call(WGPUDeviceLostReason_Destroyed, testing::_, device.Get()))
|
||||
apiDevice.SetUncapturedErrorCallback(mDeviceErrorCallback.Callback(),
|
||||
mDeviceErrorCallback.MakeUserdata(apiDevice.Get()));
|
||||
apiDevice.SetDeviceLostCallback(mDeviceLostCallback.Callback(),
|
||||
mDeviceLostCallback.MakeUserdata(apiDevice.Get()));
|
||||
EXPECT_CALL(mDeviceLostCallback,
|
||||
Call(WGPUDeviceLostReason_Destroyed, testing::_, apiDevice.Get()))
|
||||
.Times(testing::AtMost(1));
|
||||
|
||||
device.SetLoggingCallback(
|
||||
apiDevice.SetLoggingCallback(
|
||||
[](WGPULoggingType type, char const* message, void*) {
|
||||
switch (type) {
|
||||
case WGPULoggingType_Verbose:
|
||||
|
@ -1008,47 +1080,38 @@ std::pair<wgpu::Device, WGPUDevice> DawnTestBase::CreateDeviceImpl(std::string i
|
|||
},
|
||||
nullptr);
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
wgpu::Device DawnTestBase::CreateDevice(std::string isolationKey) {
|
||||
return CreateDeviceImpl(isolationKey).first;
|
||||
return apiDevice;
|
||||
}
|
||||
|
||||
void DawnTestBase::SetUp() {
|
||||
{
|
||||
// Find the adapter that exactly matches our adapter properties.
|
||||
const auto& adapters = gTestEnv->GetInstance()->GetAdapters();
|
||||
const auto& it = std::find_if(
|
||||
adapters.begin(), adapters.end(), [&](const dawn::native::Adapter& adapter) {
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
|
||||
return (mParam.adapterProperties.selected &&
|
||||
properties.deviceID == mParam.adapterProperties.deviceID &&
|
||||
properties.vendorID == mParam.adapterProperties.vendorID &&
|
||||
properties.adapterType == mParam.adapterProperties.adapterType &&
|
||||
properties.backendType == mParam.adapterProperties.backendType &&
|
||||
strcmp(properties.name, mParam.adapterProperties.adapterName.c_str()) == 0);
|
||||
});
|
||||
ASSERT(it != adapters.end());
|
||||
mBackendAdapter = *it;
|
||||
}
|
||||
|
||||
// Setup the per-test platform. Tests can provide one by overloading CreateTestPlatform. This is
|
||||
// NOT a thread-safe operation and is allowed here for testing only.
|
||||
mTestPlatform = CreateTestPlatform();
|
||||
dawn::native::FromAPI(gTestEnv->GetInstance()->Get())
|
||||
->SetPlatformForTesting(mTestPlatform.get());
|
||||
|
||||
mInstance = mWireHelper->RegisterInstance(gTestEnv->GetInstance()->Get());
|
||||
|
||||
std::string traceName =
|
||||
std::string(::testing::UnitTest::GetInstance()->current_test_info()->test_suite_name()) +
|
||||
"_" + ::testing::UnitTest::GetInstance()->current_test_info()->name();
|
||||
mWireHelper->BeginWireTrace(traceName.c_str());
|
||||
|
||||
// Create the device from the adapter
|
||||
std::tie(device, backendDevice) = CreateDeviceImpl();
|
||||
ASSERT_NE(nullptr, backendDevice);
|
||||
// These options are unused since adapter selection is overriden to use the test params
|
||||
wgpu::RequestAdapterOptions options = {};
|
||||
mInstance.RequestAdapter(
|
||||
&options,
|
||||
[](WGPURequestAdapterStatus, WGPUAdapter cAdapter, const char*, void* userdata) {
|
||||
*static_cast<wgpu::Adapter*>(userdata) = wgpu::Adapter::Acquire(cAdapter);
|
||||
},
|
||||
&mAdapter);
|
||||
FlushWire();
|
||||
ASSERT(mAdapter);
|
||||
|
||||
device = CreateDevice();
|
||||
backendDevice = mLastCreatedBackendDevice;
|
||||
ASSERT(backendDevice);
|
||||
ASSERT(device);
|
||||
|
||||
queue = device.GetQueue();
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#define SRC_DAWN_TESTS_DAWNTEST_H_
|
||||
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
@ -536,18 +537,21 @@ class DawnTestBase {
|
|||
|
||||
const wgpu::AdapterProperties& GetAdapterProperties() const;
|
||||
|
||||
// TODO(crbug.com/dawn/689): Use limits returned from the wire
|
||||
// This is implemented here because tests need to always query
|
||||
// the |backendDevice| since limits are not implemented in the wire.
|
||||
wgpu::SupportedLimits GetSupportedLimits();
|
||||
|
||||
private:
|
||||
utils::ScopedAutoreleasePool mObjCAutoreleasePool;
|
||||
AdapterTestParam mParam;
|
||||
std::unique_ptr<utils::WireHelper> mWireHelper;
|
||||
wgpu::Instance mInstance;
|
||||
wgpu::Adapter mAdapter;
|
||||
|
||||
// Isolation keys are not exposed to the wire client. Device creation in the tests from
|
||||
// the client first push the key into this queue, which is then consumed by the server.
|
||||
std::queue<std::string> mNextIsolationKeyQueue;
|
||||
|
||||
// Internal device creation function for default device creation with some optional overrides.
|
||||
std::pair<wgpu::Device, WGPUDevice> CreateDeviceImpl(std::string isolationKey = "");
|
||||
WGPUDevice CreateDeviceImpl(std::string isolationKey);
|
||||
|
||||
std::ostringstream& AddTextureExpectationImpl(const char* file,
|
||||
int line,
|
||||
|
@ -608,6 +612,7 @@ class DawnTestBase {
|
|||
void ResolveExpectations();
|
||||
|
||||
dawn::native::Adapter mBackendAdapter;
|
||||
WGPUDevice mLastCreatedBackendDevice;
|
||||
|
||||
std::unique_ptr<dawn::platform::Platform> mTestPlatform;
|
||||
};
|
||||
|
|
|
@ -420,13 +420,13 @@ TEST_F(CopyCommandTest_B2B, CopyWithinSameBuffer) {
|
|||
|
||||
class CopyCommandTest_B2T : public CopyCommandTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[2] = {wgpu::FeatureName::Depth24UnormStencil8,
|
||||
wgpu::FeatureName::Depth32FloatStencil8};
|
||||
descriptor.requiredFeatures = requiredFeatures;
|
||||
descriptor.requiredFeaturesCount = 2;
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1029,13 +1029,13 @@ TEST_F(CopyCommandTest_B2T, RequiredBytesInCopyOverflow) {
|
|||
|
||||
class CopyCommandTest_T2B : public CopyCommandTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[2] = {wgpu::FeatureName::Depth24UnormStencil8,
|
||||
wgpu::FeatureName::Depth32FloatStencil8};
|
||||
descriptor.requiredFeatures = requiredFeatures;
|
||||
descriptor.requiredFeaturesCount = 2;
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1667,13 +1667,13 @@ TEST_F(CopyCommandTest_T2B, RequiredBytesInCopyOverflow) {
|
|||
|
||||
class CopyCommandTest_T2T : public CopyCommandTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[2] = {wgpu::FeatureName::Depth24UnormStencil8,
|
||||
wgpu::FeatureName::Depth32FloatStencil8};
|
||||
descriptor.requiredFeatures = requiredFeatures;
|
||||
descriptor.requiredFeaturesCount = 2;
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
|
||||
wgpu::TextureFormat GetCopyCompatibleFormat(wgpu::TextureFormat format) {
|
||||
|
@ -2145,14 +2145,14 @@ TEST_F(CopyCommandTest_T2T, CopyWithinSameTexture) {
|
|||
|
||||
class CopyCommandTest_CompressedTextureFormats : public CopyCommandTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[3] = {wgpu::FeatureName::TextureCompressionBC,
|
||||
wgpu::FeatureName::TextureCompressionETC2,
|
||||
wgpu::FeatureName::TextureCompressionASTC};
|
||||
descriptor.requiredFeatures = requiredFeatures;
|
||||
descriptor.requiredFeaturesCount = 3;
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
|
||||
wgpu::Texture Create2DTexture(wgpu::TextureFormat format,
|
||||
|
|
|
@ -65,13 +65,13 @@ class RequestDeviceValidationTest : public ValidationTest {
|
|||
// Test that requesting a device without specifying limits is valid.
|
||||
TEST_F(RequestDeviceValidationTest, NoRequiredLimits) {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
adapter.RequestDevice(&descriptor, ExpectRequestDeviceSuccess,
|
||||
CheckDevice([](wgpu::Device device) {
|
||||
// Check one of the default limits.
|
||||
wgpu::SupportedLimits limits;
|
||||
device.GetLimits(&limits);
|
||||
EXPECT_EQ(limits.limits.maxBindGroups, 4u);
|
||||
}));
|
||||
GetBackendAdapter().RequestDevice(&descriptor, ExpectRequestDeviceSuccess,
|
||||
CheckDevice([](wgpu::Device device) {
|
||||
// Check one of the default limits.
|
||||
wgpu::SupportedLimits limits;
|
||||
device.GetLimits(&limits);
|
||||
EXPECT_EQ(limits.limits.maxBindGroups, 4u);
|
||||
}));
|
||||
}
|
||||
|
||||
// Test that requesting a device with the default limits is valid.
|
||||
|
@ -79,13 +79,13 @@ TEST_F(RequestDeviceValidationTest, DefaultLimits) {
|
|||
wgpu::RequiredLimits limits = {};
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
descriptor.requiredLimits = &limits;
|
||||
adapter.RequestDevice(&descriptor, ExpectRequestDeviceSuccess,
|
||||
CheckDevice([](wgpu::Device device) {
|
||||
// Check one of the default limits.
|
||||
wgpu::SupportedLimits limits;
|
||||
device.GetLimits(&limits);
|
||||
EXPECT_EQ(limits.limits.maxTextureArrayLayers, 256u);
|
||||
}));
|
||||
GetBackendAdapter().RequestDevice(&descriptor, ExpectRequestDeviceSuccess,
|
||||
CheckDevice([](wgpu::Device device) {
|
||||
// Check one of the default limits.
|
||||
wgpu::SupportedLimits limits;
|
||||
device.GetLimits(&limits);
|
||||
EXPECT_EQ(limits.limits.maxTextureArrayLayers, 256u);
|
||||
}));
|
||||
}
|
||||
|
||||
// Test that requesting a device where a required limit is above the maximum value.
|
||||
|
@ -95,12 +95,12 @@ TEST_F(RequestDeviceValidationTest, HigherIsBetter) {
|
|||
descriptor.requiredLimits = &limits;
|
||||
|
||||
wgpu::SupportedLimits supportedLimits;
|
||||
EXPECT_TRUE(adapter.GetLimits(reinterpret_cast<WGPUSupportedLimits*>(&supportedLimits)));
|
||||
EXPECT_TRUE(adapter.GetLimits(&supportedLimits));
|
||||
|
||||
// If we can support better than the default, test below the max.
|
||||
if (supportedLimits.limits.maxBindGroups > 4u) {
|
||||
limits.limits.maxBindGroups = supportedLimits.limits.maxBindGroups - 1;
|
||||
adapter.RequestDevice(
|
||||
GetBackendAdapter().RequestDevice(
|
||||
&descriptor, ExpectRequestDeviceSuccess, CheckDevice([&](wgpu::Device device) {
|
||||
wgpu::SupportedLimits limits;
|
||||
device.GetLimits(&limits);
|
||||
|
@ -114,7 +114,7 @@ TEST_F(RequestDeviceValidationTest, HigherIsBetter) {
|
|||
|
||||
// Test the max.
|
||||
limits.limits.maxBindGroups = supportedLimits.limits.maxBindGroups;
|
||||
adapter.RequestDevice(
|
||||
GetBackendAdapter().RequestDevice(
|
||||
&descriptor, ExpectRequestDeviceSuccess, CheckDevice([&](wgpu::Device device) {
|
||||
wgpu::SupportedLimits limits;
|
||||
device.GetLimits(&limits);
|
||||
|
@ -127,18 +127,18 @@ TEST_F(RequestDeviceValidationTest, HigherIsBetter) {
|
|||
|
||||
// Test above the max.
|
||||
limits.limits.maxBindGroups = supportedLimits.limits.maxBindGroups + 1;
|
||||
adapter.RequestDevice(&descriptor, ExpectRequestDeviceError, nullptr);
|
||||
GetBackendAdapter().RequestDevice(&descriptor, ExpectRequestDeviceError, nullptr);
|
||||
|
||||
// Test worse than the default
|
||||
limits.limits.maxBindGroups = 3u;
|
||||
adapter.RequestDevice(&descriptor, ExpectRequestDeviceSuccess,
|
||||
CheckDevice([&](wgpu::Device device) {
|
||||
wgpu::SupportedLimits limits;
|
||||
device.GetLimits(&limits);
|
||||
GetBackendAdapter().RequestDevice(&descriptor, ExpectRequestDeviceSuccess,
|
||||
CheckDevice([&](wgpu::Device device) {
|
||||
wgpu::SupportedLimits limits;
|
||||
device.GetLimits(&limits);
|
||||
|
||||
// Check we got the default.
|
||||
EXPECT_EQ(limits.limits.maxBindGroups, 4u);
|
||||
}));
|
||||
// Check we got the default.
|
||||
EXPECT_EQ(limits.limits.maxBindGroups, 4u);
|
||||
}));
|
||||
}
|
||||
|
||||
// Test that requesting a device where a required limit is below the minimum value.
|
||||
|
@ -148,33 +148,33 @@ TEST_F(RequestDeviceValidationTest, LowerIsBetter) {
|
|||
descriptor.requiredLimits = &limits;
|
||||
|
||||
wgpu::SupportedLimits supportedLimits;
|
||||
EXPECT_TRUE(adapter.GetLimits(reinterpret_cast<WGPUSupportedLimits*>(&supportedLimits)));
|
||||
EXPECT_TRUE(adapter.GetLimits(&supportedLimits));
|
||||
|
||||
// Test below the min.
|
||||
limits.limits.minUniformBufferOffsetAlignment =
|
||||
supportedLimits.limits.minUniformBufferOffsetAlignment / 2;
|
||||
adapter.RequestDevice(&descriptor, ExpectRequestDeviceError, nullptr);
|
||||
GetBackendAdapter().RequestDevice(&descriptor, ExpectRequestDeviceError, nullptr);
|
||||
|
||||
// Test the min.
|
||||
limits.limits.minUniformBufferOffsetAlignment =
|
||||
supportedLimits.limits.minUniformBufferOffsetAlignment;
|
||||
adapter.RequestDevice(&descriptor, ExpectRequestDeviceSuccess,
|
||||
CheckDevice([&](wgpu::Device device) {
|
||||
wgpu::SupportedLimits limits;
|
||||
device.GetLimits(&limits);
|
||||
GetBackendAdapter().RequestDevice(
|
||||
&descriptor, ExpectRequestDeviceSuccess, CheckDevice([&](wgpu::Device device) {
|
||||
wgpu::SupportedLimits limits;
|
||||
device.GetLimits(&limits);
|
||||
|
||||
// Check we got exactly the request.
|
||||
EXPECT_EQ(limits.limits.minUniformBufferOffsetAlignment,
|
||||
supportedLimits.limits.minUniformBufferOffsetAlignment);
|
||||
// Check another default limit.
|
||||
EXPECT_EQ(limits.limits.maxTextureArrayLayers, 256u);
|
||||
}));
|
||||
// Check we got exactly the request.
|
||||
EXPECT_EQ(limits.limits.minUniformBufferOffsetAlignment,
|
||||
supportedLimits.limits.minUniformBufferOffsetAlignment);
|
||||
// Check another default limit.
|
||||
EXPECT_EQ(limits.limits.maxTextureArrayLayers, 256u);
|
||||
}));
|
||||
|
||||
// IF we can support better than the default, test above the min.
|
||||
if (supportedLimits.limits.minUniformBufferOffsetAlignment > 256u) {
|
||||
limits.limits.minUniformBufferOffsetAlignment =
|
||||
supportedLimits.limits.minUniformBufferOffsetAlignment * 2;
|
||||
adapter.RequestDevice(
|
||||
GetBackendAdapter().RequestDevice(
|
||||
&descriptor, ExpectRequestDeviceSuccess, CheckDevice([&](wgpu::Device device) {
|
||||
wgpu::SupportedLimits limits;
|
||||
device.GetLimits(&limits);
|
||||
|
@ -189,14 +189,14 @@ TEST_F(RequestDeviceValidationTest, LowerIsBetter) {
|
|||
|
||||
// Test worse than the default
|
||||
limits.limits.minUniformBufferOffsetAlignment = 2u * 256u;
|
||||
adapter.RequestDevice(&descriptor, ExpectRequestDeviceSuccess,
|
||||
CheckDevice([&](wgpu::Device device) {
|
||||
wgpu::SupportedLimits limits;
|
||||
device.GetLimits(&limits);
|
||||
GetBackendAdapter().RequestDevice(
|
||||
&descriptor, ExpectRequestDeviceSuccess, CheckDevice([&](wgpu::Device device) {
|
||||
wgpu::SupportedLimits limits;
|
||||
device.GetLimits(&limits);
|
||||
|
||||
// Check we got the default.
|
||||
EXPECT_EQ(limits.limits.minUniformBufferOffsetAlignment, 256u);
|
||||
}));
|
||||
// Check we got the default.
|
||||
EXPECT_EQ(limits.limits.minUniformBufferOffsetAlignment, 256u);
|
||||
}));
|
||||
}
|
||||
|
||||
// Test that it is an error to request limits with an invalid chained struct
|
||||
|
@ -207,7 +207,7 @@ TEST_F(RequestDeviceValidationTest, InvalidChainedStruct) {
|
|||
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
descriptor.requiredLimits = &limits;
|
||||
adapter.RequestDevice(&descriptor, ExpectRequestDeviceError, nullptr);
|
||||
GetBackendAdapter().RequestDevice(&descriptor, ExpectRequestDeviceError, nullptr);
|
||||
}
|
||||
|
||||
class DeviceTickValidationTest : public ValidationTest {};
|
||||
|
|
|
@ -64,12 +64,12 @@ TEST_F(InternalUsageValidationDisabledTest, CommandEncoderDescriptorRequiresFeat
|
|||
}
|
||||
|
||||
class TextureInternalUsageValidationTest : public ValidationTest {
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::DawnInternalUsages};
|
||||
descriptor.requiredFeatures = requiredFeatures;
|
||||
descriptor.requiredFeaturesCount = 1;
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -18,10 +18,14 @@
|
|||
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "dawn/utils/WGPUHelpers.h"
|
||||
|
||||
class LabelTest : public ValidationTest {};
|
||||
class LabelTest : public ValidationTest {
|
||||
void SetUp() override {
|
||||
ValidationTest::SetUp();
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(LabelTest, BindGroup) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {});
|
||||
|
||||
|
@ -55,7 +59,6 @@ TEST_F(LabelTest, BindGroup) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, BindGroupLayout) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
|
||||
wgpu::BindGroupLayoutDescriptor descriptor = {};
|
||||
|
@ -87,7 +90,6 @@ TEST_F(LabelTest, BindGroupLayout) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, Buffer) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
wgpu::BufferDescriptor descriptor;
|
||||
descriptor.size = 4;
|
||||
|
@ -118,7 +120,6 @@ TEST_F(LabelTest, Buffer) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, CommandBuffer) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
wgpu::CommandBufferDescriptor descriptor;
|
||||
|
||||
|
@ -150,7 +151,6 @@ TEST_F(LabelTest, CommandBuffer) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, CommandEncoder) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
wgpu::CommandEncoderDescriptor descriptor;
|
||||
|
||||
|
@ -179,7 +179,6 @@ TEST_F(LabelTest, CommandEncoder) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, ComputePassEncoder) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
|
||||
|
||||
|
@ -213,7 +212,6 @@ TEST_F(LabelTest, ComputePassEncoder) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, ExternalTexture) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
wgpu::TextureDescriptor textureDescriptor;
|
||||
textureDescriptor.size.width = 1;
|
||||
|
@ -260,7 +258,6 @@ TEST_F(LabelTest, ExternalTexture) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, PipelineLayout) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {});
|
||||
|
||||
|
@ -324,13 +321,13 @@ TEST_F(LabelTest, QuerySet) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, Queue) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
|
||||
// The label should be empty if one was not set.
|
||||
{
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::Device labelDevice = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor));
|
||||
wgpu::Device labelDevice =
|
||||
wgpu::Device::Acquire(GetBackendAdapter().CreateDevice(&descriptor));
|
||||
std::string readbackLabel =
|
||||
dawn::native::GetObjectLabelForTesting(labelDevice.GetQueue().Get());
|
||||
ASSERT_TRUE(readbackLabel.empty());
|
||||
|
@ -339,7 +336,8 @@ TEST_F(LabelTest, Queue) {
|
|||
// Test setting a label through API
|
||||
{
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::Device labelDevice = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor));
|
||||
wgpu::Device labelDevice =
|
||||
wgpu::Device::Acquire(GetBackendAdapter().CreateDevice(&descriptor));
|
||||
labelDevice.GetQueue().SetLabel(label.c_str());
|
||||
std::string readbackLabel =
|
||||
dawn::native::GetObjectLabelForTesting(labelDevice.GetQueue().Get());
|
||||
|
@ -350,7 +348,8 @@ TEST_F(LabelTest, Queue) {
|
|||
{
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
descriptor.defaultQueue.label = label.c_str();
|
||||
wgpu::Device labelDevice = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor));
|
||||
wgpu::Device labelDevice =
|
||||
wgpu::Device::Acquire(GetBackendAdapter().CreateDevice(&descriptor));
|
||||
std::string readbackLabel =
|
||||
dawn::native::GetObjectLabelForTesting(labelDevice.GetQueue().Get());
|
||||
ASSERT_EQ(label, readbackLabel);
|
||||
|
@ -358,7 +357,6 @@ TEST_F(LabelTest, Queue) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, RenderBundleEncoder) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
|
||||
utils::ComboRenderBundleEncoderDescriptor descriptor = {};
|
||||
|
@ -390,7 +388,6 @@ TEST_F(LabelTest, RenderBundleEncoder) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, RenderPassEncoder) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
|
||||
|
||||
|
@ -430,7 +427,6 @@ TEST_F(LabelTest, RenderPassEncoder) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, Sampler) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
wgpu::SamplerDescriptor descriptor;
|
||||
|
||||
|
@ -459,7 +455,6 @@ TEST_F(LabelTest, Sampler) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, Texture) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
wgpu::TextureDescriptor descriptor;
|
||||
descriptor.size.width = 1;
|
||||
|
@ -496,7 +491,6 @@ TEST_F(LabelTest, Texture) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, TextureView) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
wgpu::TextureDescriptor descriptor;
|
||||
descriptor.size.width = 1;
|
||||
|
@ -536,7 +530,6 @@ TEST_F(LabelTest, TextureView) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, RenderPipeline) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
|
||||
wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
|
||||
|
@ -578,7 +571,6 @@ TEST_F(LabelTest, RenderPipeline) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, ComputePipeline) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
|
||||
wgpu::ShaderModule computeModule = utils::CreateShaderModule(device, R"(
|
||||
|
@ -615,7 +607,6 @@ TEST_F(LabelTest, ComputePipeline) {
|
|||
}
|
||||
|
||||
TEST_F(LabelTest, ShaderModule) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire());
|
||||
std::string label = "test";
|
||||
|
||||
const char* source = R"(
|
||||
|
|
|
@ -27,7 +27,7 @@ class MultipleDeviceTest : public ValidationTest {};
|
|||
|
||||
// Test that it is invalid to submit a command buffer created on a different device.
|
||||
TEST_F(MultipleDeviceTest, ValidatesSameDevice) {
|
||||
wgpu::Device device2 = RegisterDevice(CreateTestDevice());
|
||||
wgpu::Device device2 = RequestDeviceSync(wgpu::DeviceDescriptor{});
|
||||
wgpu::CommandBuffer commandBuffer = device2.CreateCommandEncoder().Finish();
|
||||
|
||||
ASSERT_DEVICE_ERROR(device.GetQueue().Submit(1, &commandBuffer));
|
||||
|
@ -66,7 +66,7 @@ TEST_F(MultipleDeviceTest, ValidatesSameDeviceCreatePipelineAsync) {
|
|||
|
||||
// CreateComputePipelineAsync errors if the shader module is created on a different device.
|
||||
{
|
||||
wgpu::Device device2 = RegisterDevice(CreateTestDevice());
|
||||
wgpu::Device device2 = RequestDeviceSync(wgpu::DeviceDescriptor{});
|
||||
wgpu::ShaderModule shaderModule = device2.CreateShaderModule(&shaderModuleDesc);
|
||||
|
||||
wgpu::ComputePipelineDescriptor pipelineDesc = {};
|
||||
|
|
|
@ -111,7 +111,7 @@ TEST_F(OcclusionQueryValidationTest, InvalidOcclusionQuerySet) {
|
|||
|
||||
// Fail to begin render pass if the occlusionQuerySet is created from other device
|
||||
{
|
||||
wgpu::Device otherDevice = RegisterDevice(adapter.CreateDevice());
|
||||
wgpu::Device otherDevice = RequestDeviceSync(wgpu::DeviceDescriptor{});
|
||||
wgpu::QuerySet occlusionQuerySetOnOther =
|
||||
CreateQuerySet(otherDevice, wgpu::QueryType::Occlusion, 2);
|
||||
renderPass.occlusionQuerySet = occlusionQuerySetOnOther;
|
||||
|
@ -225,7 +225,7 @@ TEST_F(OcclusionQueryValidationTest, InvalidBeginAndEnd) {
|
|||
|
||||
class TimestampQueryValidationTest : public QuerySetValidationTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::TimestampQuery};
|
||||
descriptor.requiredFeatures = requiredFeatures;
|
||||
|
@ -237,7 +237,7 @@ class TimestampQueryValidationTest : public QuerySetValidationTest {
|
|||
togglesDesc.forceDisabledToggles = forceDisabledToggles;
|
||||
togglesDesc.forceDisabledTogglesCount = 1;
|
||||
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
|
||||
void EncodeRenderPassWithTimestampWrites(
|
||||
|
@ -324,7 +324,7 @@ TEST_F(TimestampQueryValidationTest, TimestampWritesOnComputePass) {
|
|||
|
||||
// Fail to write timestamps to a query set created from another device
|
||||
{
|
||||
wgpu::Device otherDevice = RegisterDevice(adapter.CreateDevice());
|
||||
wgpu::Device otherDevice = RequestDeviceSync(wgpu::DeviceDescriptor{});
|
||||
wgpu::QuerySet querySetFromOtherDevice =
|
||||
CreateQuerySet(otherDevice, wgpu::QueryType::Timestamp, 2);
|
||||
|
||||
|
@ -408,7 +408,7 @@ TEST_F(TimestampQueryValidationTest, TimestampWritesOnRenderPass) {
|
|||
|
||||
// Fail to write timestamps to a query set created from another device
|
||||
{
|
||||
wgpu::Device otherDevice = RegisterDevice(adapter.CreateDevice());
|
||||
wgpu::Device otherDevice = RequestDeviceSync(wgpu::DeviceDescriptor{});
|
||||
wgpu::QuerySet querySetFromOtherDevice =
|
||||
CreateQuerySet(otherDevice, wgpu::QueryType::Timestamp, 2);
|
||||
|
||||
|
@ -640,7 +640,7 @@ TEST_F(TimestampQueryValidationTest, WriteTimestampOnRenderPassEncoder) {
|
|||
|
||||
class PipelineStatisticsQueryValidationTest : public QuerySetValidationTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::PipelineStatisticsQuery};
|
||||
descriptor.requiredFeatures = requiredFeatures;
|
||||
|
@ -654,7 +654,7 @@ class PipelineStatisticsQueryValidationTest : public QuerySetValidationTest {
|
|||
togglesDesc.forceDisabledToggles = forceDisabledToggles;
|
||||
togglesDesc.forceDisabledTogglesCount = 1;
|
||||
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -793,7 +793,7 @@ TEST_F(ResolveQuerySetValidationTest, ResolveToInvalidBufferAndOffset) {
|
|||
|
||||
// Fail to resolve query set to a buffer created from another device
|
||||
{
|
||||
wgpu::Device otherDevice = RegisterDevice(adapter.CreateDevice());
|
||||
wgpu::Device otherDevice = RequestDeviceSync(wgpu::DeviceDescriptor{});
|
||||
wgpu::Buffer bufferOnOther =
|
||||
CreateBuffer(otherDevice, kBufferSize, wgpu::BufferUsage::QueryResolve);
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
|
|
|
@ -535,14 +535,14 @@ TEST_F(QueueWriteTextureValidationTest, WriteToStencilAspect) {
|
|||
|
||||
class WriteTextureTest_CompressedTextureFormats : public QueueWriteTextureValidationTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[3] = {wgpu::FeatureName::TextureCompressionBC,
|
||||
wgpu::FeatureName::TextureCompressionETC2,
|
||||
wgpu::FeatureName::TextureCompressionASTC};
|
||||
descriptor.requiredFeatures = requiredFeatures;
|
||||
descriptor.requiredFeaturesCount = 3;
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
|
||||
wgpu::Texture Create2DTexture(wgpu::TextureFormat format,
|
||||
|
|
|
@ -1267,12 +1267,12 @@ TEST_F(RenderPipelineValidationTest, BindingsFromCorrectEntryPoint) {
|
|||
|
||||
class DepthClampingValidationTest : public RenderPipelineValidationTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::DepthClamping};
|
||||
descriptor.requiredFeatures = requiredFeatures;
|
||||
descriptor.requiredFeaturesCount = 1;
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -698,12 +698,12 @@ TEST_F(TextureValidationTest, UseASTCFormatWithoutEnablingFeature) {
|
|||
|
||||
class D24S8TextureFormatsValidationTests : public TextureValidationTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth24UnormStencil8};
|
||||
descriptor.requiredFeatures = requiredFeatures;
|
||||
descriptor.requiredFeaturesCount = 1;
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -720,12 +720,12 @@ TEST_F(D24S8TextureFormatsValidationTests, DepthStencilFormatsFor3D) {
|
|||
|
||||
class D32S8TextureFormatsValidationTests : public TextureValidationTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth32FloatStencil8};
|
||||
descriptor.requiredFeatures = requiredFeatures;
|
||||
descriptor.requiredFeaturesCount = 1;
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -742,7 +742,7 @@ TEST_F(D32S8TextureFormatsValidationTests, DepthStencilFormatsFor3D) {
|
|||
|
||||
class CompressedTextureFormatsValidationTests : public TextureValidationTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[3] = {wgpu::FeatureName::TextureCompressionBC,
|
||||
wgpu::FeatureName::TextureCompressionETC2,
|
||||
|
@ -758,7 +758,7 @@ class CompressedTextureFormatsValidationTests : public TextureValidationTest {
|
|||
|
||||
descriptor.nextInChain = &togglesDesc;
|
||||
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
|
||||
wgpu::TextureDescriptor CreateDefaultTextureDescriptor() {
|
||||
|
|
|
@ -925,12 +925,12 @@ TEST_F(TextureViewValidationTest, AspectMustExist) {
|
|||
|
||||
class D24S8TextureViewValidationTests : public ValidationTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth24UnormStencil8};
|
||||
descriptor.requiredFeatures = requiredFeatures;
|
||||
descriptor.requiredFeaturesCount = 1;
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -971,12 +971,12 @@ TEST_F(D24S8TextureViewValidationTests, TextureViewFormatCompatibility) {
|
|||
|
||||
class D32S8TextureViewValidationTests : public ValidationTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth32FloatStencil8};
|
||||
descriptor.requiredFeatures = requiredFeatures;
|
||||
descriptor.requiredFeaturesCount = 1;
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ TEST_F(ToggleValidationTest, QueryToggleInfo) {
|
|||
// Query with a valid toggle name
|
||||
{
|
||||
const char* kValidToggleName = "emulate_store_and_msaa_resolve";
|
||||
const dawn::native::ToggleInfo* toggleInfo = instance->GetToggleInfo(kValidToggleName);
|
||||
const dawn::native::ToggleInfo* toggleInfo = GetToggleInfo(kValidToggleName);
|
||||
ASSERT_NE(nullptr, toggleInfo);
|
||||
ASSERT_NE(nullptr, toggleInfo->name);
|
||||
ASSERT_NE(nullptr, toggleInfo->description);
|
||||
|
@ -40,7 +40,7 @@ TEST_F(ToggleValidationTest, QueryToggleInfo) {
|
|||
// Query with an invalid toggle name
|
||||
{
|
||||
const char* kInvalidToggleName = "!@#$%^&*";
|
||||
const dawn::native::ToggleInfo* toggleInfo = instance->GetToggleInfo(kInvalidToggleName);
|
||||
const dawn::native::ToggleInfo* toggleInfo = GetToggleInfo(kInvalidToggleName);
|
||||
ASSERT_EQ(nullptr, toggleInfo);
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,8 @@ TEST_F(ToggleValidationTest, OverrideToggleUsage) {
|
|||
togglesDesc.forceEnabledToggles = &kValidToggleName;
|
||||
togglesDesc.forceEnabledTogglesCount = 1;
|
||||
|
||||
wgpu::Device deviceWithToggle = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor));
|
||||
wgpu::Device deviceWithToggle =
|
||||
wgpu::Device::Acquire(GetBackendAdapter().CreateDevice(&descriptor));
|
||||
std::vector<const char*> toggleNames = dawn::native::GetTogglesUsed(deviceWithToggle.Get());
|
||||
bool validToggleExists = false;
|
||||
for (const char* toggle : toggleNames) {
|
||||
|
@ -76,7 +77,8 @@ TEST_F(ToggleValidationTest, OverrideToggleUsage) {
|
|||
togglesDesc.forceEnabledToggles = &kInvalidToggleName;
|
||||
togglesDesc.forceEnabledTogglesCount = 1;
|
||||
|
||||
wgpu::Device deviceWithToggle = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor));
|
||||
wgpu::Device deviceWithToggle =
|
||||
wgpu::Device::Acquire(GetBackendAdapter().CreateDevice(&descriptor));
|
||||
std::vector<const char*> toggleNames = dawn::native::GetTogglesUsed(deviceWithToggle.Get());
|
||||
bool InvalidToggleExists = false;
|
||||
for (const char* toggle : toggleNames) {
|
||||
|
@ -96,7 +98,8 @@ TEST_F(ToggleValidationTest, TurnOffVsyncWithToggle) {
|
|||
togglesDesc.forceEnabledToggles = &kValidToggleName;
|
||||
togglesDesc.forceEnabledTogglesCount = 1;
|
||||
|
||||
wgpu::Device deviceWithToggle = wgpu::Device::Acquire(adapter.CreateDevice(&descriptor));
|
||||
wgpu::Device deviceWithToggle =
|
||||
wgpu::Device::Acquire(GetBackendAdapter().CreateDevice(&descriptor));
|
||||
std::vector<const char*> toggleNames = dawn::native::GetTogglesUsed(deviceWithToggle.Get());
|
||||
bool validToggleExists = false;
|
||||
for (const char* toggle : toggleNames) {
|
||||
|
|
|
@ -26,14 +26,14 @@ using testing::HasSubstr;
|
|||
|
||||
class UnsafeAPIValidationTest : public ValidationTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::DawnTogglesDeviceDescriptor togglesDesc;
|
||||
descriptor.nextInChain = &togglesDesc;
|
||||
const char* toggle = "disallow_unsafe_apis";
|
||||
togglesDesc.forceEnabledToggles = &toggle;
|
||||
togglesDesc.forceEnabledTogglesCount = 1;
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -79,7 +79,7 @@ TEST_F(UnsafeAPIValidationTest, PipelineOverridableConstants) {
|
|||
|
||||
class UnsafeQueryAPIValidationTest : public ValidationTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[2] = {wgpu::FeatureName::PipelineStatisticsQuery,
|
||||
wgpu::FeatureName::TimestampQuery};
|
||||
|
@ -92,7 +92,7 @@ class UnsafeQueryAPIValidationTest : public ValidationTest {
|
|||
togglesDesc.forceEnabledToggles = &toggle;
|
||||
togglesDesc.forceEnabledTogglesCount = 1;
|
||||
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ bool gUseWire = false;
|
|||
// NOLINTNEXTLINE(runtime/string)
|
||||
std::string gWireTraceDir = "";
|
||||
std::unique_ptr<ToggleParser> gToggleParser = nullptr;
|
||||
static ValidationTest* gCurrentTest = nullptr;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -79,48 +80,86 @@ void InitDawnValidationTestEnvironment(int argc, char** argv) {
|
|||
}
|
||||
}
|
||||
|
||||
ValidationTest::ValidationTest()
|
||||
: mWireHelper(utils::CreateWireHelper(gUseWire, gWireTraceDir.c_str())) {}
|
||||
ValidationTest::ValidationTest() {
|
||||
gCurrentTest = this;
|
||||
|
||||
DawnProcTable procs = dawn::native::GetProcs();
|
||||
// Override procs to provide harness-specific behavior to always select the null adapter,
|
||||
// and to allow fixture-specific overriding of the test device with CreateTestDevice.
|
||||
procs.instanceRequestAdapter = [](WGPUInstance instance, const WGPURequestAdapterOptions*,
|
||||
WGPURequestAdapterCallback callback, void* userdata) {
|
||||
ASSERT(gCurrentTest);
|
||||
std::vector<dawn::native::Adapter> adapters = gCurrentTest->mDawnInstance->GetAdapters();
|
||||
// Validation tests run against the null backend, find the corresponding adapter
|
||||
for (auto& adapter : adapters) {
|
||||
wgpu::AdapterProperties adapterProperties;
|
||||
adapter.GetProperties(&adapterProperties);
|
||||
|
||||
if (adapterProperties.backendType == wgpu::BackendType::Null) {
|
||||
gCurrentTest->mBackendAdapter = adapter;
|
||||
WGPUAdapter cAdapter = adapter.Get();
|
||||
ASSERT(cAdapter);
|
||||
dawn::native::GetProcs().adapterReference(cAdapter);
|
||||
callback(WGPURequestAdapterStatus_Success, cAdapter, nullptr, userdata);
|
||||
return;
|
||||
}
|
||||
}
|
||||
UNREACHABLE();
|
||||
};
|
||||
|
||||
procs.adapterRequestDevice = [](WGPUAdapter adapter, const WGPUDeviceDescriptor*,
|
||||
WGPURequestDeviceCallback callback, void* userdata) {
|
||||
ASSERT(gCurrentTest);
|
||||
WGPUDevice cDevice = gCurrentTest->CreateTestDevice(
|
||||
dawn::native::Adapter(reinterpret_cast<dawn::native::AdapterBase*>(adapter)));
|
||||
ASSERT(cDevice != nullptr);
|
||||
gCurrentTest->mLastCreatedBackendDevice = cDevice;
|
||||
callback(WGPURequestDeviceStatus_Success, cDevice, nullptr, userdata);
|
||||
};
|
||||
|
||||
mWireHelper = utils::CreateWireHelper(procs, gUseWire, gWireTraceDir.c_str());
|
||||
}
|
||||
|
||||
void ValidationTest::SetUp() {
|
||||
instance = std::make_unique<dawn::native::Instance>();
|
||||
instance->DiscoverDefaultAdapters();
|
||||
|
||||
std::vector<dawn::native::Adapter> adapters = instance->GetAdapters();
|
||||
|
||||
// Validation tests run against the null backend, find the corresponding adapter
|
||||
bool foundNullAdapter = false;
|
||||
for (auto& currentAdapter : adapters) {
|
||||
wgpu::AdapterProperties adapterProperties;
|
||||
currentAdapter.GetProperties(&adapterProperties);
|
||||
|
||||
if (adapterProperties.backendType == wgpu::BackendType::Null) {
|
||||
adapter = currentAdapter;
|
||||
foundNullAdapter = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(foundNullAdapter);
|
||||
|
||||
std::tie(device, backendDevice) = mWireHelper->RegisterDevice(CreateTestDevice());
|
||||
device.SetUncapturedErrorCallback(ValidationTest::OnDeviceError, this);
|
||||
device.SetDeviceLostCallback(ValidationTest::OnDeviceLost, this);
|
||||
mDawnInstance = std::make_unique<dawn::native::Instance>();
|
||||
mDawnInstance->DiscoverDefaultAdapters();
|
||||
mInstance = mWireHelper->RegisterInstance(mDawnInstance->Get());
|
||||
|
||||
std::string traceName =
|
||||
std::string(::testing::UnitTest::GetInstance()->current_test_info()->test_suite_name()) +
|
||||
"_" + ::testing::UnitTest::GetInstance()->current_test_info()->name();
|
||||
mWireHelper->BeginWireTrace(traceName.c_str());
|
||||
|
||||
// These options are unused since validation tests always select the null adapter
|
||||
wgpu::RequestAdapterOptions options = {};
|
||||
mInstance.RequestAdapter(
|
||||
&options,
|
||||
[](WGPURequestAdapterStatus, WGPUAdapter cAdapter, const char*, void* userdata) {
|
||||
*static_cast<wgpu::Adapter*>(userdata) = wgpu::Adapter::Acquire(cAdapter);
|
||||
},
|
||||
&adapter);
|
||||
FlushWire();
|
||||
ASSERT(adapter);
|
||||
|
||||
device = RequestDeviceSync(wgpu::DeviceDescriptor{});
|
||||
backendDevice = mLastCreatedBackendDevice;
|
||||
|
||||
device.SetUncapturedErrorCallback(ValidationTest::OnDeviceError, this);
|
||||
device.SetDeviceLostCallback(ValidationTest::OnDeviceLost, this);
|
||||
}
|
||||
|
||||
ValidationTest::~ValidationTest() {
|
||||
// We need to destroy Dawn objects before setting the procs to null otherwise the dawn*Release
|
||||
// will call a nullptr
|
||||
device = wgpu::Device();
|
||||
// We need to destroy Dawn objects before the wire helper which sets procs to null otherwise the
|
||||
// dawn*Release will call a nullptr
|
||||
device = nullptr;
|
||||
adapter = nullptr;
|
||||
mInstance = nullptr;
|
||||
mWireHelper.reset();
|
||||
|
||||
// Check that all devices were destructed.
|
||||
EXPECT_EQ(instance->GetDeviceCountForTesting(), 0u);
|
||||
EXPECT_EQ(mDawnInstance->GetDeviceCountForTesting(), 0u);
|
||||
|
||||
gCurrentTest = nullptr;
|
||||
}
|
||||
|
||||
void ValidationTest::TearDown() {
|
||||
|
@ -159,10 +198,6 @@ void ValidationTest::ExpectDeviceDestruction() {
|
|||
mExpectDestruction = true;
|
||||
}
|
||||
|
||||
wgpu::Device ValidationTest::RegisterDevice(WGPUDevice backendDevice) {
|
||||
return mWireHelper->RegisterDevice(backendDevice).first;
|
||||
}
|
||||
|
||||
bool ValidationTest::UsesWire() const {
|
||||
return gUseWire;
|
||||
}
|
||||
|
@ -190,6 +225,10 @@ void ValidationTest::WaitForAllOperations(const wgpu::Device& device) {
|
|||
FlushWire();
|
||||
}
|
||||
|
||||
const dawn::native::ToggleInfo* ValidationTest::GetToggleInfo(const char* name) const {
|
||||
return mDawnInstance->GetToggleInfo(name);
|
||||
}
|
||||
|
||||
bool ValidationTest::HasToggleEnabled(const char* toggle) const {
|
||||
auto toggles = dawn::native::GetTogglesUsed(backendDevice);
|
||||
return std::find_if(toggles.begin(), toggles.end(), [toggle](const char* name) {
|
||||
|
@ -197,14 +236,33 @@ bool ValidationTest::HasToggleEnabled(const char* toggle) const {
|
|||
}) != toggles.end();
|
||||
}
|
||||
|
||||
wgpu::SupportedLimits ValidationTest::GetSupportedLimits() {
|
||||
WGPUSupportedLimits supportedLimits;
|
||||
supportedLimits.nextInChain = nullptr;
|
||||
dawn::native::GetProcs().deviceGetLimits(backendDevice, &supportedLimits);
|
||||
return *reinterpret_cast<wgpu::SupportedLimits*>(&supportedLimits);
|
||||
wgpu::SupportedLimits ValidationTest::GetSupportedLimits() const {
|
||||
wgpu::SupportedLimits supportedLimits = {};
|
||||
device.GetLimits(&supportedLimits);
|
||||
return supportedLimits;
|
||||
}
|
||||
|
||||
WGPUDevice ValidationTest::CreateTestDevice() {
|
||||
wgpu::Device ValidationTest::RequestDeviceSync(const wgpu::DeviceDescriptor& deviceDesc) {
|
||||
ASSERT(adapter);
|
||||
|
||||
wgpu::Device apiDevice;
|
||||
adapter.RequestDevice(
|
||||
&deviceDesc,
|
||||
[](WGPURequestDeviceStatus, WGPUDevice cDevice, const char*, void* userdata) {
|
||||
*static_cast<wgpu::Device*>(userdata) = wgpu::Device::Acquire(cDevice);
|
||||
},
|
||||
&apiDevice);
|
||||
FlushWire();
|
||||
|
||||
ASSERT(apiDevice);
|
||||
return apiDevice;
|
||||
}
|
||||
|
||||
dawn::native::Adapter& ValidationTest::GetBackendAdapter() {
|
||||
return mBackendAdapter;
|
||||
}
|
||||
|
||||
WGPUDevice ValidationTest::CreateTestDevice(dawn::native::Adapter dawnAdapter) {
|
||||
// Disabled disallowing unsafe APIs so we can test them.
|
||||
std::vector<const char*> forceEnabledToggles;
|
||||
std::vector<const char*> forceDisabledToggles = {"disallow_unsafe_apis"};
|
||||
|
@ -226,7 +284,7 @@ WGPUDevice ValidationTest::CreateTestDevice() {
|
|||
togglesDesc.forceDisabledToggles = forceDisabledToggles.data();
|
||||
togglesDesc.forceDisabledTogglesCount = forceDisabledToggles.size();
|
||||
|
||||
return adapter.CreateDevice(&deviceDescriptor);
|
||||
return dawnAdapter.CreateDevice(&deviceDescriptor);
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -108,8 +108,6 @@ class ValidationTest : public testing::Test {
|
|||
|
||||
void ExpectDeviceDestruction();
|
||||
|
||||
wgpu::Device RegisterDevice(WGPUDevice backendDevice);
|
||||
|
||||
bool UsesWire() const;
|
||||
|
||||
void FlushWire();
|
||||
|
@ -129,25 +127,28 @@ class ValidationTest : public testing::Test {
|
|||
wgpu::RenderPassColorAttachment mColorAttachment;
|
||||
};
|
||||
|
||||
const dawn::native::ToggleInfo* GetToggleInfo(const char* name) const;
|
||||
bool HasToggleEnabled(const char* toggle) const;
|
||||
|
||||
// TODO(crbug.com/dawn/689): Use limits returned from the wire
|
||||
// This is implemented here because tests need to always query
|
||||
// the |backendDevice| since limits are not implemented in the wire.
|
||||
wgpu::SupportedLimits GetSupportedLimits();
|
||||
wgpu::SupportedLimits GetSupportedLimits() const;
|
||||
|
||||
protected:
|
||||
virtual WGPUDevice CreateTestDevice();
|
||||
dawn::native::Adapter& GetBackendAdapter();
|
||||
virtual WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter);
|
||||
|
||||
wgpu::Device RequestDeviceSync(const wgpu::DeviceDescriptor& deviceDesc);
|
||||
|
||||
std::unique_ptr<dawn::native::Instance> instance;
|
||||
dawn::native::Adapter adapter;
|
||||
wgpu::Device device;
|
||||
wgpu::Adapter adapter;
|
||||
WGPUDevice backendDevice;
|
||||
|
||||
size_t mLastWarningCount = 0;
|
||||
|
||||
private:
|
||||
std::unique_ptr<dawn::native::Instance> mDawnInstance;
|
||||
wgpu::Instance mInstance;
|
||||
dawn::native::Adapter mBackendAdapter;
|
||||
std::unique_ptr<utils::WireHelper> mWireHelper;
|
||||
WGPUDevice mLastCreatedBackendDevice;
|
||||
|
||||
static void OnDeviceError(WGPUErrorType type, const char* message, void* userdata);
|
||||
static void OnDeviceLost(WGPUDeviceLostReason reason, const char* message, void* userdata);
|
||||
|
|
|
@ -21,12 +21,12 @@ namespace {
|
|||
|
||||
class VideoViewsValidation : public ValidationTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::DawnMultiPlanarFormats};
|
||||
descriptor.requiredFeatures = requiredFeatures;
|
||||
descriptor.requiredFeaturesCount = 1;
|
||||
return adapter.CreateDevice(&descriptor);
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
|
||||
wgpu::Texture CreateVideoTextureForTest(wgpu::TextureFormat format, wgpu::TextureUsage usage) {
|
||||
|
|
|
@ -78,11 +78,11 @@ class WireServerTraceLayer : public dawn::wire::CommandHandler {
|
|||
|
||||
class WireHelperDirect : public WireHelper {
|
||||
public:
|
||||
WireHelperDirect() { dawnProcSetProcs(&dawn::native::GetProcs()); }
|
||||
explicit WireHelperDirect(const DawnProcTable& procs) { dawnProcSetProcs(&procs); }
|
||||
|
||||
std::pair<wgpu::Device, WGPUDevice> RegisterDevice(WGPUDevice backendDevice) override {
|
||||
ASSERT(backendDevice != nullptr);
|
||||
return std::make_pair(wgpu::Device::Acquire(backendDevice), backendDevice);
|
||||
wgpu::Instance RegisterInstance(WGPUInstance backendInstance) override {
|
||||
ASSERT(backendInstance != nullptr);
|
||||
return wgpu::Instance(backendInstance);
|
||||
}
|
||||
|
||||
void BeginWireTrace(const char* name) override {}
|
||||
|
@ -94,12 +94,12 @@ class WireHelperDirect : public WireHelper {
|
|||
|
||||
class WireHelperProxy : public WireHelper {
|
||||
public:
|
||||
explicit WireHelperProxy(const char* wireTraceDir) {
|
||||
explicit WireHelperProxy(const char* wireTraceDir, const DawnProcTable& procs) {
|
||||
mC2sBuf = std::make_unique<utils::TerribleCommandBuffer>();
|
||||
mS2cBuf = std::make_unique<utils::TerribleCommandBuffer>();
|
||||
|
||||
dawn::wire::WireServerDescriptor serverDesc = {};
|
||||
serverDesc.procs = &dawn::native::GetProcs();
|
||||
serverDesc.procs = &procs;
|
||||
serverDesc.serializer = mS2cBuf.get();
|
||||
|
||||
mWireServer.reset(new dawn::wire::WireServer(serverDesc));
|
||||
|
@ -118,14 +118,13 @@ class WireHelperProxy : public WireHelper {
|
|||
dawnProcSetProcs(&dawn::wire::client::GetProcs());
|
||||
}
|
||||
|
||||
std::pair<wgpu::Device, WGPUDevice> RegisterDevice(WGPUDevice backendDevice) override {
|
||||
ASSERT(backendDevice != nullptr);
|
||||
wgpu::Instance RegisterInstance(WGPUInstance backendInstance) override {
|
||||
ASSERT(backendInstance != nullptr);
|
||||
|
||||
auto reservation = mWireClient->ReserveDevice();
|
||||
mWireServer->InjectDevice(backendDevice, reservation.id, reservation.generation);
|
||||
dawn::native::GetProcs().deviceRelease(backendDevice);
|
||||
auto reservation = mWireClient->ReserveInstance();
|
||||
mWireServer->InjectInstance(backendInstance, reservation.id, reservation.generation);
|
||||
|
||||
return std::make_pair(wgpu::Device::Acquire(reservation.device), backendDevice);
|
||||
return wgpu::Instance::Acquire(reservation.instance);
|
||||
}
|
||||
|
||||
void BeginWireTrace(const char* name) override {
|
||||
|
@ -148,11 +147,13 @@ class WireHelperProxy : public WireHelper {
|
|||
|
||||
} // anonymous namespace
|
||||
|
||||
std::unique_ptr<WireHelper> CreateWireHelper(bool useWire, const char* wireTraceDir) {
|
||||
std::unique_ptr<WireHelper> CreateWireHelper(const DawnProcTable& procs,
|
||||
bool useWire,
|
||||
const char* wireTraceDir) {
|
||||
if (useWire) {
|
||||
return std::unique_ptr<WireHelper>(new WireHelperProxy(wireTraceDir));
|
||||
return std::unique_ptr<WireHelper>(new WireHelperProxy(wireTraceDir, procs));
|
||||
} else {
|
||||
return std::unique_ptr<WireHelper>(new WireHelperDirect());
|
||||
return std::unique_ptr<WireHelper>(new WireHelperDirect(procs));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,10 +27,11 @@ class WireHelper {
|
|||
public:
|
||||
virtual ~WireHelper();
|
||||
|
||||
// Registers the device on the wire, if present.
|
||||
// Returns a pair of the client device and backend device.
|
||||
// The function should take ownership of |backendDevice|.
|
||||
virtual std::pair<wgpu::Device, WGPUDevice> RegisterDevice(WGPUDevice backendDevice) = 0;
|
||||
// Registers the instance on the wire, if present.
|
||||
// Returns the wgpu::Instance which is the client instance on the wire, and
|
||||
// the backend instance without the wire.
|
||||
// The function should not take ownership of |backendInstance|.
|
||||
virtual wgpu::Instance RegisterInstance(WGPUInstance backendInstance) = 0;
|
||||
|
||||
virtual void BeginWireTrace(const char* name) = 0;
|
||||
|
||||
|
@ -38,7 +39,9 @@ class WireHelper {
|
|||
virtual bool FlushServer() = 0;
|
||||
};
|
||||
|
||||
std::unique_ptr<WireHelper> CreateWireHelper(bool useWire, const char* wireTraceDir = nullptr);
|
||||
std::unique_ptr<WireHelper> CreateWireHelper(const DawnProcTable& procs,
|
||||
bool useWire,
|
||||
const char* wireTraceDir = nullptr);
|
||||
|
||||
} // namespace utils
|
||||
|
||||
|
|
Loading…
Reference in New Issue