Allow device lost callback to be passed at creation

This change updates the Device descriptor to allow a device lost
callback to be passed in at device creation time. This will be
important for allowing the API to return devices which have
already been lost in a future CL, which is the behavior required
by the spec.

This change does not yet deprecate the old method for setting the
callback, as there's still some tricky scenarios that will need to
be worked around to enable that and this CL is already fairly
large. (The uses in question pass the device or a value created
from the device as the userdata.)

Bug: chromium:1234617
Change-Id: I1adea5ceffdfdcfedff9fff4960f12303abba29c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/121041
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Brandon Jones <bajones@chromium.org>
This commit is contained in:
Brandon Jones 2023-05-17 01:52:30 +00:00 committed by Dawn LUCI CQ
parent 0e6534e44d
commit 112b7fd856
24 changed files with 150 additions and 94 deletions

View File

@ -163,7 +163,9 @@
{"name": "required features count", "type": "uint32_t", "default": 0},
{"name": "required features", "type": "feature name", "annotation": "const*", "length": "required features count", "default": "nullptr"},
{"name": "required limits", "type": "required limits", "annotation": "const*", "optional": true},
{"name": "default queue", "type": "queue descriptor"}
{"name": "default queue", "type": "queue descriptor"},
{"name": "device lost callback", "type": "device lost callback", "default": "nullptr"},
{"name": "device lost userdata", "type": "void *", "default": "nullptr"}
]
},
"dawn toggles descriptor": {
@ -1191,6 +1193,7 @@
{
"name": "set device lost callback",
"no autolock": true,
"tags": ["deprecated"],
"args": [
{"name": "callback", "type": "device lost callback"},
{"name": "userdata", "type": "void", "annotation": "*"}

View File

@ -65,6 +65,11 @@ typedef uint32_t {{c_prefix}}Flags;
typedef struct {{as_cType(type.name)}}Impl* {{as_cType(type.name)}};
{% endfor %}
// Structure forward declarations
{% for type in by_category["structure"] %}
struct {{as_cType(type.name)}};
{% endfor %}
{% for type in by_category["enum"] + by_category["bitmask"] %}
typedef enum {{as_cType(type.name)}} {
{% for value in type.values %}
@ -78,6 +83,18 @@ typedef uint32_t {{c_prefix}}Flags;
{% endfor -%}
{% for type in by_category["function pointer"] %}
typedef {{as_cType(type.return_type.name)}} (*{{as_cType(type.name)}})(
{%- if type.arguments == [] -%}
void
{%- else -%}
{%- for arg in type.arguments -%}
{% if not loop.first %}, {% endif %}{% if arg.type.category == "structure" %}struct {% endif %}{{as_annotated_cType(arg)}}
{%- endfor -%}
{%- endif -%}
);
{% endfor %}
typedef struct {{c_prefix}}ChainedStruct {
struct {{c_prefix}}ChainedStruct const * next;
{{c_prefix}}SType sType;

View File

@ -176,6 +176,9 @@ DeviceBase::DeviceBase(AdapterBase* adapter,
: mAdapter(adapter), mToggles(deviceToggles), mNextPipelineCompatibilityToken(1) {
ASSERT(descriptor != nullptr);
mDeviceLostCallback = descriptor->deviceLostCallback;
mDeviceLostUserdata = descriptor->deviceLostUserdata;
AdapterProperties adapterProperties;
adapter->APIGetProperties(&adapterProperties);
@ -234,15 +237,17 @@ MaybeError DeviceBase::Initialize(Ref<QueueBase> defaultQueue) {
}
};
mDeviceLostCallback = [](WGPUDeviceLostReason, char const*, void*) {
static bool calledOnce = false;
if (!calledOnce) {
calledOnce = true;
dawn::WarningLog() << "No Dawn device lost callback was set. This is probably not "
"intended. If you really want to ignore device lost "
"and suppress this message, set the callback to null.";
}
};
if (!mDeviceLostCallback) {
mDeviceLostCallback = [](WGPUDeviceLostReason, char const*, void*) {
static bool calledOnce = false;
if (!calledOnce) {
calledOnce = true;
dawn::WarningLog() << "No Dawn device lost callback was set. This is probably not "
"intended. If you really want to ignore device lost "
"and suppress this message, set the callback to null.";
}
};
}
#endif // DAWN_ENABLE_ASSERTS
mCaches = std::make_unique<DeviceBase::Caches>();
@ -611,6 +616,8 @@ void DeviceBase::APISetUncapturedErrorCallback(wgpu::ErrorCallback callback, voi
}
void DeviceBase::APISetDeviceLostCallback(wgpu::DeviceLostCallback callback, void* userdata) {
// TODO(chromium:1234617): Add a deprecation warning.
// The registered callback function and userdata pointer are stored and used by deferred
// callback tasks, and after setting a different callback (especially in the case of
// resetting) the resources pointed by such pointer may be freed. Flush all deferred

View File

@ -699,7 +699,7 @@ DawnTestBase::DawnTestBase(const AdapterTestParam& param) : mParam(param) {
callback(WGPURequestAdapterStatus_Success, cAdapter, nullptr, userdata);
};
procs.adapterRequestDevice = [](WGPUAdapter adapter, const WGPUDeviceDescriptor*,
procs.adapterRequestDevice = [](WGPUAdapter adapter, const WGPUDeviceDescriptor* descriptor,
WGPURequestDeviceCallback callback, void* userdata) {
ASSERT(gCurrentTest);
@ -711,7 +711,7 @@ DawnTestBase::DawnTestBase(const AdapterTestParam& param) : mParam(param) {
isolationKey = std::move(gCurrentTest->mNextIsolationKeyQueue.front());
gCurrentTest->mNextIsolationKeyQueue.pop();
}
WGPUDevice cDevice = gCurrentTest->CreateDeviceImpl(std::move(isolationKey));
WGPUDevice cDevice = gCurrentTest->CreateDeviceImpl(std::move(isolationKey), descriptor);
ASSERT(cDevice != nullptr);
gCurrentTest->mLastCreatedBackendDevice = cDevice;
@ -978,7 +978,12 @@ bool DawnTestBase::SupportsFeatures(const std::vector<wgpu::FeatureName>& featur
return true;
}
WGPUDevice DawnTestBase::CreateDeviceImpl(std::string isolationKey) {
void* DawnTestBase::GetUniqueUserdata() {
return reinterpret_cast<void*>(++mNextUniqueUserdata);
}
WGPUDevice DawnTestBase::CreateDeviceImpl(std::string isolationKey,
const WGPUDeviceDescriptor* descriptor) {
// Create the device from the adapter
std::vector<wgpu::FeatureName> requiredFeatures = GetRequiredFeatures();
if (IsImplicitDeviceSyncEnabled()) {
@ -989,7 +994,8 @@ WGPUDevice DawnTestBase::CreateDeviceImpl(std::string isolationKey) {
mBackendAdapter.GetLimits(reinterpret_cast<WGPUSupportedLimits*>(&supportedLimits));
wgpu::RequiredLimits requiredLimits = GetRequiredLimits(supportedLimits);
wgpu::DeviceDescriptor deviceDescriptor = {};
wgpu::DeviceDescriptor deviceDescriptor =
*reinterpret_cast<const wgpu::DeviceDescriptor*>(descriptor);
deviceDescriptor.requiredLimits = &requiredLimits;
deviceDescriptor.requiredFeatures = requiredFeatures.data();
deviceDescriptor.requiredFeaturesCount = requiredFeatures.size();
@ -1017,6 +1023,12 @@ wgpu::Device DawnTestBase::CreateDevice(std::string isolationKey) {
// Give an empty descriptor.
// TODO(dawn:1684): Replace empty DeviceDescriptor with nullptr after Dawn wire support it.
wgpu::DeviceDescriptor deviceDesc = {};
// Set up the mocks for device loss.
void* deviceUserdata = GetUniqueUserdata();
deviceDesc.deviceLostCallback = mDeviceLostCallback.Callback();
deviceDesc.deviceLostUserdata = mDeviceLostCallback.MakeUserdata(deviceUserdata);
mAdapter.RequestDevice(
&deviceDesc,
[](WGPURequestDeviceStatus, WGPUDevice cDevice, const char*, void* userdata) {
@ -1026,14 +1038,13 @@ wgpu::Device DawnTestBase::CreateDevice(std::string isolationKey) {
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.
// Set up the mocks for uncaptured errors.
apiDevice.SetUncapturedErrorCallback(mDeviceErrorCallback.Callback(),
mDeviceErrorCallback.MakeUserdata(apiDevice.Get()));
apiDevice.SetDeviceLostCallback(mDeviceLostCallback.Callback(),
mDeviceLostCallback.MakeUserdata(apiDevice.Get()));
// The loss of the device is expected to happen at the end of the test so at it directly.
EXPECT_CALL(mDeviceLostCallback,
Call(WGPUDeviceLostReason_Destroyed, testing::_, apiDevice.Get()))
Call(WGPUDeviceLostReason_Destroyed, testing::_, deviceUserdata))
.Times(testing::AtMost(1));
apiDevice.SetLoggingCallback(
@ -1123,8 +1134,7 @@ void DawnTestBase::LoseDeviceForTesting(wgpu::Device device) {
resolvedDevice = this->device;
}
EXPECT_CALL(mDeviceLostCallback,
Call(WGPUDeviceLostReason_Undefined, testing::_, resolvedDevice.Get()))
EXPECT_CALL(mDeviceLostCallback, Call(WGPUDeviceLostReason_Undefined, testing::_, testing::_))
.Times(1);
resolvedDevice.ForceLoss(wgpu::DeviceLostReason::Undefined, "Device lost for testing");
resolvedDevice.Tick();

View File

@ -580,6 +580,8 @@ class DawnTestBase {
wgpu::SupportedLimits GetAdapterLimits();
wgpu::SupportedLimits GetSupportedLimits();
void* GetUniqueUserdata();
private:
utils::ScopedAutoreleasePool mObjCAutoreleasePool;
AdapterTestParam mParam;
@ -587,12 +589,15 @@ class DawnTestBase {
wgpu::Instance mInstance;
wgpu::Adapter mAdapter;
// Helps generate unique userdata values passed to deviceLostUserdata.
std::atomic<uintptr_t> mNextUniqueUserdata = 0;
// 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.
WGPUDevice CreateDeviceImpl(std::string isolationKey);
WGPUDevice CreateDeviceImpl(std::string isolationKey, const WGPUDeviceDescriptor* descriptor);
std::ostringstream& AddTextureExpectationImpl(const char* file,
int line,

View File

@ -79,8 +79,8 @@ class BindGroupValidationTest : public ValidationTest {
return desc;
}
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth32FloatStencil8};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;

View File

@ -420,8 +420,8 @@ TEST_F(CopyCommandTest_B2B, CopyWithinSameBuffer) {
class CopyCommandTest_B2T : public CopyCommandTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth32FloatStencil8};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;
@ -1028,8 +1028,8 @@ TEST_F(CopyCommandTest_B2T, RequiredBytesInCopyOverflow) {
class CopyCommandTest_T2B : public CopyCommandTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth32FloatStencil8};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;
@ -1665,8 +1665,8 @@ TEST_F(CopyCommandTest_T2B, RequiredBytesInCopyOverflow) {
class CopyCommandTest_T2T : public CopyCommandTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth32FloatStencil8};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;
@ -2144,8 +2144,8 @@ TEST_F(CopyCommandTest_T2T, CopyWithinSameTexture) {
class CopyCommandTest_CompressedTextureFormats : public CopyCommandTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[3] = {wgpu::FeatureName::TextureCompressionBC,
wgpu::FeatureName::TextureCompressionETC2,
wgpu::FeatureName::TextureCompressionASTC};

View File

@ -101,8 +101,8 @@ class CopyTextureForBrowserTest : public ValidationTest {
class CopyTextureForBrowserInternalUsageTest : public CopyTextureForBrowserTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName feature = wgpu::FeatureName::DawnInternalUsages;
descriptor.requiredFeatures = &feature;
descriptor.requiredFeaturesCount = 1;
@ -142,8 +142,8 @@ class CopyExternalTextureForBrowserTest : public ValidationTest {
class CopyExternalTextureForBrowserInternalUsageTest : public CopyExternalTextureForBrowserTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName feature = wgpu::FeatureName::DawnInternalUsages;
descriptor.requiredFeatures = &feature;
descriptor.requiredFeaturesCount = 1;

View File

@ -64,8 +64,8 @@ TEST_F(InternalUsageValidationDisabledTest, CommandEncoderDescriptorRequiresFeat
}
class TextureInternalUsageValidationTest : public ValidationTest {
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::DawnInternalUsages};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;

View File

@ -21,7 +21,8 @@
class ComputePipelineOverridableConstantsValidationTest : public ValidationTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor deviceDescriptor) override {
std::vector<const char*> enabledToggles;
std::vector<const char*> disabledToggles;
@ -35,7 +36,6 @@ class ComputePipelineOverridableConstantsValidationTest : public ValidationTest
const wgpu::FeatureName requiredFeatures[] = {wgpu::FeatureName::ShaderF16};
wgpu::DeviceDescriptor deviceDescriptor;
deviceDescriptor.nextInChain = &deviceTogglesDesc;
deviceDescriptor.requiredFeatures = requiredFeatures;
deviceDescriptor.requiredFeaturesCount = 1;

View File

@ -273,8 +273,8 @@ TEST_F(OcclusionQueryValidationTest, InvalidBeginAndEnd) {
class TimestampQueryValidationTest : public QuerySetValidationTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::TimestampQuery};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;
@ -566,8 +566,8 @@ TEST_F(TimestampQueryValidationTest, WriteTimestampOnCommandEncoder) {
class TimestampQueryInsidePassesValidationTest : public QuerySetValidationTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
// The timestamp query feature must be supported if the timestamp query inside passes
// feature is supported. Enable timestamp query for validating queries overwrite inside and
// outside of the passes.
@ -709,11 +709,11 @@ TEST_F(TimestampQueryInsidePassesValidationTest, WriteTimestampOnRenderPassEncod
class PipelineStatisticsQueryValidationTest : public QuerySetValidationTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
// Create a device with pipeline statistic query feature required. Note that Pipeline
// statistic query is an unsafe API, while AllowUnsafeApis instance toggle is enabled
// when ValidationTest creating testing instance, so we can test it.
wgpu::DeviceDescriptor descriptor;
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::PipelineStatisticsQuery};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;

View File

@ -536,8 +536,8 @@ TEST_F(QueueWriteTextureValidationTest, WriteToStencilAspect) {
class WriteTextureTest_CompressedTextureFormats : public QueueWriteTextureValidationTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[3] = {wgpu::FeatureName::TextureCompressionBC,
wgpu::FeatureName::TextureCompressionETC2,
wgpu::FeatureName::TextureCompressionASTC};

View File

@ -24,8 +24,8 @@
class RenderPipelineValidationTest : public ValidationTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::ShaderF16};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;
@ -1595,8 +1595,8 @@ TEST_F(RenderPipelineValidationTest, RenderPipelineColorAttachmentBytesPerSample
class DepthClipControlValidationTest : public RenderPipelineValidationTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::DepthClipControl};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;
@ -1894,8 +1894,8 @@ TEST_F(InterStageVariableMatchingValidationTest, DifferentInterpolationAttribute
class RenderPipelineTransientAttachmentValidationTest : public RenderPipelineValidationTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[2] = {wgpu::FeatureName::ShaderF16,
wgpu::FeatureName::TransientAttachments};
descriptor.requiredFeatures = requiredFeatures;

View File

@ -269,8 +269,8 @@ TEST_F(StorageTextureValidationTests, StorageTextureFormatInShaders) {
class BGRA8UnormStorageTextureInShaderValidationTests : public StorageTextureValidationTests {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::BGRA8UnormStorage};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;
@ -427,8 +427,8 @@ TEST_F(StorageTextureValidationTests, StorageTextureFormatInBindGroupLayout) {
class BGRA8UnormStorageBindGroupLayoutTest : public StorageTextureValidationTests {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::BGRA8UnormStorage};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;

View File

@ -699,8 +699,8 @@ TEST_F(TextureValidationTest, UseASTCFormatWithoutEnablingFeature) {
class D32S8TextureFormatsValidationTests : public TextureValidationTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth32FloatStencil8};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;
@ -721,8 +721,8 @@ TEST_F(D32S8TextureFormatsValidationTests, DepthStencilFormatsFor3D) {
class CompressedTextureFormatsValidationTests : public TextureValidationTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[3] = {wgpu::FeatureName::TextureCompressionBC,
wgpu::FeatureName::TextureCompressionETC2,
wgpu::FeatureName::TextureCompressionASTC};
@ -879,8 +879,8 @@ TEST_F(CompressedTextureFormatsValidationTests, TextureSize) {
class RG11B10UfloatTextureFormatsValidationTests : public TextureValidationTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::RG11B10UfloatRenderable};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;
@ -902,8 +902,8 @@ TEST_F(RG11B10UfloatTextureFormatsValidationTests, RenderableFeature) {
class BGRA8UnormTextureFormatsValidationTests : public TextureValidationTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::BGRA8UnormStorage};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;
@ -1038,8 +1038,8 @@ TEST_F(TextureValidationTest, TransientAttachmentOnUnsupportedDevice) {
class TransientAttachmentValidationTest : public TextureValidationTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::TransientAttachments};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;

View File

@ -916,8 +916,8 @@ TEST_F(TextureViewValidationTest, AspectMustExist) {
class D32S8TextureViewValidationTests : public ValidationTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::Depth32FloatStencil8};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;

View File

@ -28,10 +28,10 @@ class UnsafeAPIValidationTest : public ValidationTest {
protected:
// UnsafeAPIValidationTest create the device with the AllowUnsafeAPIs toggle explicitly
// disabled, which overrides the inheritance.
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
// Disable the AllowUnsafeAPIs toggles in device toggles descriptor to override the
// inheritance and create a device disallowing unsafe apis.
wgpu::DeviceDescriptor descriptor;
wgpu::DawnTogglesDescriptor deviceTogglesDesc;
descriptor.nextInChain = &deviceTogglesDesc;
const char* toggle = "allow_unsafe_apis";

View File

@ -111,11 +111,14 @@ ValidationTest::ValidationTest() {
UNREACHABLE();
};
procs.adapterRequestDevice = [](WGPUAdapter adapter, const WGPUDeviceDescriptor*,
procs.adapterRequestDevice = [](WGPUAdapter adapter, const WGPUDeviceDescriptor* descriptor,
WGPURequestDeviceCallback callback, void* userdata) {
ASSERT(gCurrentTest);
wgpu::DeviceDescriptor deviceDesc =
*(reinterpret_cast<const wgpu::DeviceDescriptor*>(descriptor));
WGPUDevice cDevice = gCurrentTest->CreateTestDevice(
dawn::native::Adapter(reinterpret_cast<dawn::native::AdapterBase*>(adapter)));
dawn::native::Adapter(reinterpret_cast<dawn::native::AdapterBase*>(adapter)),
deviceDesc);
ASSERT(cDevice != nullptr);
gCurrentTest->mLastCreatedBackendDevice = cDevice;
callback(WGPURequestDeviceStatus_Success, cDevice, nullptr, userdata);
@ -160,11 +163,14 @@ void ValidationTest::SetUp() {
FlushWire();
ASSERT(adapter);
device = RequestDeviceSync(wgpu::DeviceDescriptor{});
wgpu::DeviceDescriptor deviceDescriptor = {};
deviceDescriptor.deviceLostCallback = ValidationTest::OnDeviceLost;
deviceDescriptor.deviceLostUserdata = this;
device = RequestDeviceSync(deviceDescriptor);
backendDevice = mLastCreatedBackendDevice;
device.SetUncapturedErrorCallback(ValidationTest::OnDeviceError, this);
device.SetDeviceLostCallback(ValidationTest::OnDeviceLost, this);
}
ValidationTest::~ValidationTest() {
@ -281,7 +287,8 @@ dawn::native::Adapter& ValidationTest::GetBackendAdapter() {
return mBackendAdapter;
}
WGPUDevice ValidationTest::CreateTestDevice(dawn::native::Adapter dawnAdapter) {
WGPUDevice ValidationTest::CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor deviceDescriptor) {
std::vector<const char*> enabledToggles;
std::vector<const char*> disabledToggles;
@ -293,7 +300,6 @@ WGPUDevice ValidationTest::CreateTestDevice(dawn::native::Adapter dawnAdapter) {
disabledToggles.push_back(toggle.c_str());
}
wgpu::DeviceDescriptor deviceDescriptor;
wgpu::DawnTogglesDescriptor deviceTogglesDesc;
deviceDescriptor.nextInChain = &deviceTogglesDesc;

View File

@ -135,7 +135,8 @@ class ValidationTest : public testing::Test {
protected:
dawn::native::Adapter& GetBackendAdapter();
virtual WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter);
virtual WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor);
wgpu::Device RequestDeviceSync(const wgpu::DeviceDescriptor& deviceDesc);

View File

@ -21,8 +21,8 @@ namespace {
class VideoViewsValidation : public ValidationTest {
protected:
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
wgpu::DeviceDescriptor descriptor;
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter,
wgpu::DeviceDescriptor descriptor) override {
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::DawnMultiPlanarFormats};
descriptor.requiredFeatures = requiredFeatures;
descriptor.requiredFeaturesCount = 1;

View File

@ -71,7 +71,7 @@ void Adapter::RequestDevice(const WGPUDeviceDescriptor* descriptor,
return;
}
Device* device = client->Make<Device>();
Device* device = client->Make<Device>(descriptor);
uint64_t serial = mRequestDeviceRequests.Add({callback, device->GetWireId(), userdata});
AdapterRequestDeviceCmd cmd;

View File

@ -106,7 +106,7 @@ ReservedSwapChain Client::ReserveSwapChain(WGPUDevice device) {
}
ReservedDevice Client::ReserveDevice() {
Device* device = Make<Device>();
Device* device = Make<Device>(nullptr);
ReservedDevice result;
result.device = ToAPI(device);

View File

@ -23,8 +23,13 @@
namespace dawn::wire::client {
Device::Device(const ObjectBaseParams& params)
Device::Device(const ObjectBaseParams& params, const WGPUDeviceDescriptor* descriptor)
: ObjectBase(params), mIsAlive(std::make_shared<bool>()) {
if (descriptor && descriptor->deviceLostCallback) {
mDeviceLostCallback = descriptor->deviceLostCallback;
mDeviceLostUserdata = descriptor->deviceLostUserdata;
}
#if defined(DAWN_ENABLE_ASSERTS)
mErrorCallback = [](WGPUErrorType, char const*, void*) {
static bool calledOnce = false;
@ -36,15 +41,17 @@ Device::Device(const ObjectBaseParams& params)
}
};
mDeviceLostCallback = [](WGPUDeviceLostReason, char const*, void*) {
static bool calledOnce = false;
if (!calledOnce) {
calledOnce = true;
dawn::WarningLog() << "No Dawn device lost callback was set. This is probably not "
"intended. If you really want to ignore device lost "
"and suppress this message, set the callback to null.";
}
};
if (!mDeviceLostCallback) {
mDeviceLostCallback = [](WGPUDeviceLostReason, char const*, void*) {
static bool calledOnce = false;
if (!calledOnce) {
calledOnce = true;
dawn::WarningLog() << "No Dawn device lost callback was set. This is probably not "
"intended. If you really want to ignore device lost "
"and suppress this message, set the callback to null.";
}
};
}
#endif // DAWN_ENABLE_ASSERTS
}

View File

@ -32,7 +32,7 @@ class Queue;
class Device final : public ObjectBase {
public:
explicit Device(const ObjectBaseParams& params);
explicit Device(const ObjectBaseParams& params, const WGPUDeviceDescriptor* descriptor);
~Device() override;
void SetUncapturedErrorCallback(WGPUErrorCallback errorCallback, void* errorUserdata);