Rename DeviceErrorCallback to ErrorCallback and add ErrorType arg

This same callback will be used for push/pop error scope.

Bug: dawn:153
Change-Id: I2771539e13f8a4e6a59f13c8082689d25ba44905
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/10460
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Austin Eng 2019-08-27 21:41:56 +00:00 committed by Commit Bot service account
parent 5603dc9044
commit cb0cb658d4
36 changed files with 173 additions and 90 deletions

View File

@ -524,7 +524,7 @@
{
"name": "set error callback",
"args": [
{"name": "callback", "type": "device error callback"},
{"name": "callback", "type": "error callback"},
{"name": "userdata", "type": "void", "annotation": "*"}
]
}
@ -543,9 +543,19 @@
{"name": "stencil write mask", "type": "uint32_t", "default": "0xFFFFFFFF"}
]
},
"device error callback": {
"error callback": {
"category": "natively defined"
},
"error type": {
"category": "enum",
"values": [
{"value": 0, "name": "no error"},
{"value": 1, "name": "validation"},
{"value": 2, "name": "out of memory"},
{"value": 3, "name": "unknown"},
{"value": 4, "name": "device lost"}
]
},
"extent 3D": {
"category": "structure",
"members": [

View File

@ -67,6 +67,7 @@
{ "name": "status", "type": "uint32_t" }
],
"device error callback": [
{ "name": "type", "type": "error type"},
{ "name": "message", "type": "char", "annotation": "const*", "length": "strlen" }
],
"fence update completed value": [

View File

@ -31,8 +31,25 @@
#include <cstring>
#include <iostream>
void PrintDeviceError(const char* message, void*) {
std::cout << "Device error: " << message << std::endl;
void PrintDeviceError(DawnErrorType errorType, const char* message, void*) {
switch (errorType) {
case DAWN_ERROR_TYPE_VALIDATION:
std::cout << "Validation ";
break;
case DAWN_ERROR_TYPE_OUT_OF_MEMORY:
std::cout << "Out of memory ";
break;
case DAWN_ERROR_TYPE_UNKNOWN:
std::cout << "Unknown ";
break;
case DAWN_ERROR_TYPE_DEVICE_LOST:
std::cout << "Device lost ";
break;
default:
UNREACHABLE();
return;
}
std::cout << "error: " << message << std::endl;
}
void PrintGLFWError(int code, const char* message) {

View File

@ -430,6 +430,14 @@ def as_frontendType(typ):
else:
return as_cType(typ.name)
def as_wireType(typ):
if typ.category == 'object':
return typ.name.CamelCase() + '*'
elif typ.category in ['bitmask', 'enum']:
return 'Dawn' + typ.name.CamelCase()
else:
return as_cppType(typ.name)
def cpp_native_methods(types, typ):
return typ.methods + typ.native_methods
@ -522,7 +530,8 @@ class MultiGeneratorFromDawnJSON(Generator):
api_params,
c_params,
{
'as_wireType': lambda typ: typ.name.CamelCase() + '*' if typ.category == 'object' else as_cppType(typ.name)
'as_wireType': as_wireType,
'as_annotated_wireType': lambda arg: annotated(as_wireType(arg.type), arg),
},
additional_params
]

View File

@ -50,7 +50,7 @@ const uint64_t DAWN_WHOLE_SIZE = 0xffffffffffffffffULL; // UINT64_MAX
{% endfor %}
// Custom types depending on the target language
typedef void (*DawnDeviceErrorCallback)(const char* message, void* userdata);
typedef void (*DawnErrorCallback)(DawnErrorType type, const char* message, void* userdata);
typedef void (*DawnBufferCreateMappedCallback)(DawnBufferMapAsyncStatus status,
DawnCreateBufferMappedResult result,
void* userdata);

View File

@ -22,9 +22,9 @@
bool Do{{command.name.CamelCase()}}(
{%- for member in command.members -%}
{%- if member.handle_type -%}
{{as_cppType(member.handle_type.name)}}* {{as_varName(member.name)}}
{{as_wireType(member.handle_type)}} {{as_varName(member.name)}}
{%- else -%}
{{as_annotated_cppType(member)}}
{{as_annotated_wireType(member)}}
{%- endif -%}
{%- if not loop.last -%}, {% endif %}
{%- endfor -%}

View File

@ -51,7 +51,7 @@ void ProcTableAsClass::GetProcTableAndDevice(DawnProcTable* table, DawnDevice* d
}
void ProcTableAsClass::DeviceSetErrorCallback(DawnDevice self,
DawnDeviceErrorCallback callback,
DawnErrorCallback callback,
void* userdata) {
auto object = reinterpret_cast<ProcTableAsClass::Object*>(self);
object->deviceErrorCallback = callback;
@ -102,9 +102,9 @@ void ProcTableAsClass::FenceOnCompletion(DawnFence self,
OnFenceOnCompletionCallback(self, value, callback, userdata);
}
void ProcTableAsClass::CallDeviceErrorCallback(DawnDevice device, const char* message) {
void ProcTableAsClass::CallDeviceErrorCallback(DawnDevice device, DawnErrorType type, const char* message) {
auto object = reinterpret_cast<ProcTableAsClass::Object*>(device);
object->deviceErrorCallback(message, object->userdata1);
object->deviceErrorCallback(type, message, object->userdata1);
}
void ProcTableAsClass::CallCreateBufferMappedCallback(DawnDevice device, DawnBufferMapAsyncStatus status, DawnCreateBufferMappedResult result) {
auto object = reinterpret_cast<ProcTableAsClass::Object*>(device);

View File

@ -52,7 +52,7 @@ class ProcTableAsClass {
// Stores callback and userdata and calls the On* methods
void DeviceSetErrorCallback(DawnDevice self,
DawnDeviceErrorCallback callback,
DawnErrorCallback callback,
void* userdata);
void DeviceCreateBufferMappedAsync(DawnDevice self,
const DawnBufferDescriptor* descriptor,
@ -71,7 +71,7 @@ class ProcTableAsClass {
// Special cased mockable methods
virtual void OnDeviceSetErrorCallback(DawnDevice device,
DawnDeviceErrorCallback callback,
DawnErrorCallback callback,
void* userdata) = 0;
virtual void OnDeviceCreateBufferMappedAsyncCallback(DawnDevice self,
const DawnBufferDescriptor* descriptor,
@ -89,7 +89,7 @@ class ProcTableAsClass {
void* userdata) = 0;
// Calls the stored callbacks
void CallDeviceErrorCallback(DawnDevice device, const char* message);
void CallDeviceErrorCallback(DawnDevice device, DawnErrorType type, const char* message);
void CallCreateBufferMappedCallback(DawnDevice device, DawnBufferMapAsyncStatus status, DawnCreateBufferMappedResult result);
void CallMapReadCallback(DawnBuffer buffer, DawnBufferMapAsyncStatus status, const void* data, uint64_t dataLength);
void CallMapWriteCallback(DawnBuffer buffer, DawnBufferMapAsyncStatus status, void* data, uint64_t dataLength);
@ -97,7 +97,7 @@ class ProcTableAsClass {
struct Object {
ProcTableAsClass* procs = nullptr;
DawnDeviceErrorCallback deviceErrorCallback = nullptr;
DawnErrorCallback deviceErrorCallback = nullptr;
DawnBufferCreateMappedCallback createBufferMappedCallback = nullptr;
DawnBufferMapReadCallback mapReadCallback = nullptr;
DawnBufferMapWriteCallback mapWriteCallback = nullptr;
@ -133,7 +133,7 @@ class MockProcTable : public ProcTableAsClass {
MOCK_METHOD1({{as_MethodSuffix(type.name, Name("release"))}}, void({{as_cType(type.name)}} self));
{% endfor %}
MOCK_METHOD3(OnDeviceSetErrorCallback, void(DawnDevice device, DawnDeviceErrorCallback callback, void* userdata));
MOCK_METHOD3(OnDeviceSetErrorCallback, void(DawnDevice device, DawnErrorCallback callback, void* userdata));
MOCK_METHOD4(OnDeviceCreateBufferMappedAsyncCallback, void(DawnDevice device, const DawnBufferDescriptor* descriptor, DawnBufferCreateMappedCallback callback, void* userdata));
MOCK_METHOD3(OnBufferMapReadAsyncCallback, void(DawnBuffer buffer, DawnBufferMapReadCallback callback, void* userdata));
MOCK_METHOD3(OnBufferMapWriteAsyncCallback, void(DawnBuffer buffer, DawnBufferMapWriteCallback callback, void* userdata));

View File

@ -88,13 +88,13 @@ namespace dawn_native {
ASSERT(mCaches->shaderModules.empty());
}
void DeviceBase::HandleError(const char* message) {
void DeviceBase::HandleError(dawn::ErrorType type, const char* message) {
if (mErrorCallback) {
mErrorCallback(message, mErrorUserdata);
mErrorCallback(static_cast<DawnErrorType>(type), message, mErrorUserdata);
}
}
void DeviceBase::SetErrorCallback(dawn::DeviceErrorCallback callback, void* userdata) {
void DeviceBase::SetErrorCallback(dawn::ErrorCallback callback, void* userdata) {
mErrorCallback = callback;
mErrorUserdata = userdata;
}
@ -671,7 +671,7 @@ namespace dawn_native {
void DeviceBase::ConsumeError(ErrorData* error) {
ASSERT(error != nullptr);
HandleError(error->GetMessage().c_str());
HandleError(error->GetType(), error->GetMessage().c_str());
delete error;
}

View File

@ -44,7 +44,7 @@ namespace dawn_native {
DeviceBase(AdapterBase* adapter, const DeviceDescriptor* descriptor);
virtual ~DeviceBase();
void HandleError(const char* message);
void HandleError(dawn::ErrorType type, const char* message);
bool ConsumedError(MaybeError maybeError) {
if (DAWN_UNLIKELY(maybeError.IsError())) {
@ -148,7 +148,7 @@ namespace dawn_native {
void Tick();
void SetErrorCallback(dawn::DeviceErrorCallback callback, void* userdata);
void SetErrorCallback(dawn::ErrorCallback callback, void* userdata);
void Reference();
void Release();
@ -247,7 +247,7 @@ namespace dawn_native {
std::unique_ptr<FenceSignalTracker> mFenceSignalTracker;
std::vector<DeferredCreateBufferMappedAsync> mDeferredCreateBufferMappedAsyncResults;
dawn::DeviceErrorCallback mErrorCallback = nullptr;
dawn::ErrorCallback mErrorCallback = nullptr;
void* mErrorUserdata = 0;
uint32_t mRefCount = 1;

View File

@ -45,7 +45,7 @@ namespace dawn_native {
return &mIterator;
}
void EncodingContext::HandleError(const char* message) {
void EncodingContext::HandleError(dawn::ErrorType type, const char* message) {
if (!IsFinished()) {
// If the encoding context is not finished, errors are deferred until
// Finish() is called.
@ -54,7 +54,7 @@ namespace dawn_native {
mErrorMessage = message;
}
} else {
mDevice->HandleError(message);
mDevice->HandleError(type, message);
}
}

View File

@ -18,6 +18,7 @@
#include "dawn_native/CommandAllocator.h"
#include "dawn_native/Error.h"
#include "dawn_native/ErrorData.h"
#include "dawn_native/dawn_platform.h"
#include <string>
@ -37,10 +38,10 @@ namespace dawn_native {
CommandIterator* GetIterator();
// Functions to handle encoder errors
void HandleError(const char* message);
void HandleError(dawn::ErrorType type, const char* message);
inline void ConsumeError(ErrorData* error) {
HandleError(error->GetMessage().c_str());
HandleError(error->GetType(), error->GetMessage().c_str());
delete error;
}
@ -57,9 +58,11 @@ namespace dawn_native {
if (DAWN_UNLIKELY(encoder != mCurrentEncoder)) {
if (mCurrentEncoder != mTopLevelEncoder) {
// The top level encoder was used when a pass encoder was current.
HandleError("Command cannot be recorded inside a pass");
HandleError(dawn::ErrorType::Validation,
"Command cannot be recorded inside a pass");
} else {
HandleError("Recording in an error or already ended pass encoder");
HandleError(dawn::ErrorType::Validation,
"Recording in an error or already ended pass encoder");
}
return false;
}

View File

@ -18,7 +18,7 @@
namespace dawn_native {
ErrorData* MakeError(ErrorType type,
ErrorData* MakeError(InternalErrorType type,
std::string message,
const char* file,
const char* function,

View File

@ -25,7 +25,7 @@ namespace dawn_native {
// file to avoid having all files including headers like <string> and <vector>
class ErrorData;
enum class ErrorType : uint32_t { Validation, DeviceLost, Unimplemented, OutOfMemory };
enum class InternalErrorType : uint32_t { Validation, DeviceLost, Unimplemented, OutOfMemory };
// MaybeError and ResultOrError are meant to be used as return value for function that are not
// expected to, but might fail. The handling of error is potentially much slower than successes.
@ -45,10 +45,10 @@ namespace dawn_native {
// return DAWN_VALIDATION_ERROR("My error message");
#define DAWN_MAKE_ERROR(TYPE, MESSAGE) \
::dawn_native::MakeError(TYPE, MESSAGE, __FILE__, __func__, __LINE__)
#define DAWN_VALIDATION_ERROR(MESSAGE) DAWN_MAKE_ERROR(ErrorType::Validation, MESSAGE)
#define DAWN_DEVICE_LOST_ERROR(MESSAGE) DAWN_MAKE_ERROR(ErrorType::DeviceLost, MESSAGE)
#define DAWN_UNIMPLEMENTED_ERROR(MESSAGE) DAWN_MAKE_ERROR(ErrorType::Unimplemented, MESSAGE)
#define DAWN_OUT_OF_MEMORY_ERROR(MESSAGE) DAWN_MAKE_ERROR(ErrorType::OutOfMemory, MESSAGE)
#define DAWN_VALIDATION_ERROR(MESSAGE) DAWN_MAKE_ERROR(InternalErrorType::Validation, MESSAGE)
#define DAWN_DEVICE_LOST_ERROR(MESSAGE) DAWN_MAKE_ERROR(InternalErrorType::DeviceLost, MESSAGE)
#define DAWN_UNIMPLEMENTED_ERROR(MESSAGE) DAWN_MAKE_ERROR(InternalErrorType::Unimplemented, MESSAGE)
#define DAWN_OUT_OF_MEMORY_ERROR(MESSAGE) DAWN_MAKE_ERROR(InternalErrorType::OutOfMemory, MESSAGE)
#define DAWN_CONCAT1(x, y) x##y
#define DAWN_CONCAT2(x, y) DAWN_CONCAT1(x, y)
@ -88,7 +88,7 @@ namespace dawn_native {
void AppendBacktrace(ErrorData* error, const char* file, const char* function, int line);
// Implementation detail of DAWN_MAKE_ERROR
ErrorData* MakeError(ErrorType type,
ErrorData* MakeError(InternalErrorType type,
std::string message,
const char* file,
const char* function,

View File

@ -14,11 +14,14 @@
#include "dawn_native/ErrorData.h"
#include "dawn_native/Error.h"
#include "dawn_native/dawn_platform.h"
namespace dawn_native {
ErrorData::ErrorData() = default;
ErrorData::ErrorData(ErrorType type, std::string message)
ErrorData::ErrorData(InternalErrorType type, std::string message)
: mType(type), mMessage(std::move(message)) {
}
@ -31,10 +34,23 @@ namespace dawn_native {
mBacktrace.push_back(std::move(record));
}
ErrorType ErrorData::GetType() const {
InternalErrorType ErrorData::GetInternalType() const {
return mType;
}
dawn::ErrorType ErrorData::GetType() const {
switch (mType) {
case InternalErrorType::Validation:
return dawn::ErrorType::Validation;
case InternalErrorType::OutOfMemory:
return dawn::ErrorType::OutOfMemory;
case InternalErrorType::DeviceLost:
return dawn::ErrorType::DeviceLost;
default:
return dawn::ErrorType::Unknown;
}
}
const std::string& ErrorData::GetMessage() const {
return mMessage;
}

View File

@ -19,14 +19,18 @@
#include <string>
#include <vector>
namespace dawn {
enum class ErrorType : uint32_t;
}
namespace dawn_native {
enum class ErrorType : uint32_t;
enum class InternalErrorType : uint32_t;
class ErrorData {
public:
ErrorData();
ErrorData(ErrorType type, std::string message);
ErrorData(InternalErrorType type, std::string message);
struct BacktraceRecord {
const char* file;
@ -35,12 +39,13 @@ namespace dawn_native {
};
void AppendBacktrace(const char* file, const char* function, int line);
ErrorType GetType() const;
InternalErrorType GetInternalType() const;
dawn::ErrorType GetType() const;
const std::string& GetMessage() const;
const std::vector<BacktraceRecord>& GetBacktrace() const;
private:
ErrorType mType;
InternalErrorType mType;
std::string mMessage;
std::vector<BacktraceRecord> mBacktrace;
};

View File

@ -115,7 +115,8 @@ namespace dawn_native {
}
if (resources.push_constant_buffers.size() > 0) {
GetDevice()->HandleError("Push constants aren't supported.");
GetDevice()->HandleError(dawn::ErrorType::Validation,
"Push constants aren't supported.");
}
// Fill in bindingInfo with the SPIRV bindings
@ -132,7 +133,8 @@ namespace dawn_native {
uint32_t set = compiler.get_decoration(resource.id, spv::DecorationDescriptorSet);
if (binding >= kMaxBindingsPerGroup || set >= kMaxBindGroups) {
GetDevice()->HandleError("Binding over limits in the SPIRV");
GetDevice()->HandleError(dawn::ErrorType::Validation,
"Binding over limits in the SPIRV");
continue;
}
@ -159,7 +161,8 @@ namespace dawn_native {
uint32_t location = compiler.get_decoration(attrib.id, spv::DecorationLocation);
if (location >= kMaxVertexAttributes) {
device->HandleError("Attribute location over limits in the SPIRV");
device->HandleError(dawn::ErrorType::Validation,
"Attribute location over limits in the SPIRV");
return;
}
@ -170,7 +173,8 @@ namespace dawn_native {
// all the location 0, causing a compile error.
for (const auto& attrib : resources.stage_outputs) {
if (!compiler.get_decoration_bitset(attrib.id).get(spv::DecorationLocation)) {
device->HandleError("Need location qualifier on vertex output");
device->HandleError(dawn::ErrorType::Validation,
"Need location qualifier on vertex output");
return;
}
}
@ -181,7 +185,8 @@ namespace dawn_native {
// all the location 0, causing a compile error.
for (const auto& attrib : resources.stage_inputs) {
if (!compiler.get_decoration_bitset(attrib.id).get(spv::DecorationLocation)) {
device->HandleError("Need location qualifier on fragment input");
device->HandleError(dawn::ErrorType::Validation,
"Need location qualifier on fragment input");
return;
}
}

View File

@ -40,7 +40,7 @@ namespace dawn_native { namespace d3d12 {
DawnSwapChainNextTexture next = {};
DawnSwapChainError error = im.GetNextTexture(im.userData, &next);
if (error) {
GetDevice()->HandleError(error);
GetDevice()->HandleError(dawn::ErrorType::Unknown, error);
return nullptr;
}

View File

@ -33,7 +33,7 @@ namespace dawn_native { namespace metal {
[mtlDevice newComputePipelineStateWithFunction:computeData.function error:&error];
if (error != nil) {
NSLog(@" error => %@", error);
GetDevice()->HandleError("Error creating pipeline state");
GetDevice()->HandleError(dawn::ErrorType::DeviceLost, "Error creating pipeline state");
return;
}

View File

@ -363,7 +363,8 @@ namespace dawn_native { namespace metal {
[descriptorMTL release];
if (error != nil) {
NSLog(@" error => %@", error);
device->HandleError("Error creating rendering pipeline state");
device->HandleError(dawn::ErrorType::DeviceLost,
"Error creating rendering pipeline state");
return;
}
}

View File

@ -37,7 +37,7 @@ namespace dawn_native { namespace metal {
DawnSwapChainNextTexture next = {};
DawnSwapChainError error = im.GetNextTexture(im.userData, &next);
if (error) {
GetDevice()->HandleError(error);
GetDevice()->HandleError(dawn::ErrorType::Unknown, error);
return nullptr;
}

View File

@ -36,7 +36,7 @@ namespace dawn_native { namespace opengl {
DawnSwapChainNextTexture next = {};
DawnSwapChainError error = im.GetNextTexture(im.userData, &next);
if (error) {
GetDevice()->HandleError(error);
GetDevice()->HandleError(dawn::ErrorType::Unknown, error);
return nullptr;
}
GLuint nativeTexture = next.texture.u32;

View File

@ -38,7 +38,7 @@ namespace dawn_native { namespace vulkan {
DawnSwapChainError error = im.GetNextTexture(im.userData, &next);
if (error) {
GetDevice()->HandleError(error);
GetDevice()->HandleError(dawn::ErrorType::Unknown, error);
return nullptr;
}

View File

@ -275,7 +275,8 @@ namespace dawn_wire { namespace client {
void* userdata) {
Fence* fence = reinterpret_cast<Fence*>(cFence);
if (value > fence->signaledValue) {
fence->device->HandleError("Value greater than fence signaled value");
fence->device->HandleError(DAWN_ERROR_TYPE_VALIDATION,
"Value greater than fence signaled value");
callback(DAWN_FENCE_COMPLETION_STATUS_ERROR, userdata);
return;
}
@ -384,11 +385,13 @@ namespace dawn_wire { namespace client {
Queue* queue = reinterpret_cast<Queue*>(cQueue);
if (fence->queue != queue) {
fence->device->HandleError(
DAWN_ERROR_TYPE_VALIDATION,
"Fence must be signaled on the queue on which it was created.");
return;
}
if (signalValue <= fence->signaledValue) {
fence->device->HandleError("Fence value less than or equal to signaled value");
fence->device->HandleError(DAWN_ERROR_TYPE_VALIDATION,
"Fence value less than or equal to signaled value");
return;
}
fence->signaledValue = signalValue;
@ -411,7 +414,7 @@ namespace dawn_wire { namespace client {
}
void ClientDeviceSetErrorCallback(DawnDevice cSelf,
DawnDeviceErrorCallback callback,
DawnErrorCallback callback,
void* userdata) {
Device* device = reinterpret_cast<Device*>(cSelf);
device->SetErrorCallback(callback, userdata);

View File

@ -15,6 +15,7 @@
#ifndef DAWNWIRE_CLIENT_CLIENT_H_
#define DAWNWIRE_CLIENT_CLIENT_H_
#include <dawn/dawn.h>
#include <dawn_wire/Wire.h>
#include "dawn_wire/WireClient.h"

View File

@ -18,9 +18,18 @@
namespace dawn_wire { namespace client {
bool Client::DoDeviceErrorCallback(const char* message) {
DAWN_ASSERT(message != nullptr);
mDevice->HandleError(message);
bool Client::DoDeviceErrorCallback(DawnErrorType errorType, const char* message) {
switch (errorType) {
case DAWN_ERROR_TYPE_NO_ERROR:
case DAWN_ERROR_TYPE_VALIDATION:
case DAWN_ERROR_TYPE_OUT_OF_MEMORY:
case DAWN_ERROR_TYPE_UNKNOWN:
case DAWN_ERROR_TYPE_DEVICE_LOST:
break;
default:
return false;
}
mDevice->HandleError(errorType, message);
return true;
}

View File

@ -25,13 +25,13 @@ namespace dawn_wire { namespace client {
return mClient;
}
void Device::HandleError(const char* message) {
void Device::HandleError(DawnErrorType errorType, const char* message) {
if (mErrorCallback) {
mErrorCallback(message, mErrorUserdata);
mErrorCallback(errorType, message, mErrorUserdata);
}
}
void Device::SetErrorCallback(DawnDeviceErrorCallback errorCallback, void* errorUserdata) {
void Device::SetErrorCallback(DawnErrorCallback errorCallback, void* errorUserdata) {
mErrorCallback = errorCallback;
mErrorUserdata = errorUserdata;
}

View File

@ -28,12 +28,12 @@ namespace dawn_wire { namespace client {
Device(Client* client, uint32_t refcount, uint32_t id);
Client* GetClient();
void HandleError(const char* message);
void SetErrorCallback(DawnDeviceErrorCallback errorCallback, void* errorUserdata);
void HandleError(DawnErrorType errorType, const char* message);
void SetErrorCallback(DawnErrorCallback errorCallback, void* errorUserdata);
private:
Client* mClient = nullptr;
DawnDeviceErrorCallback mErrorCallback = nullptr;
DawnErrorCallback mErrorCallback = nullptr;
void* mErrorUserdata;
};

View File

@ -54,7 +54,7 @@ namespace dawn_wire { namespace server {
void* GetCmdSpace(size_t size);
// Forwarding callbacks
static void ForwardDeviceError(const char* message, void* userdata);
static void ForwardDeviceError(DawnErrorType type, const char* message, void* userdata);
static void ForwardBufferMapReadAsync(DawnBufferMapAsyncStatus status,
const void* ptr,
uint64_t dataLength,
@ -66,7 +66,7 @@ namespace dawn_wire { namespace server {
static void ForwardFenceCompletedValue(DawnFenceCompletionStatus status, void* userdata);
// Error callbacks
void OnDeviceError(const char* message);
void OnDeviceError(DawnErrorType type, const char* message);
void OnBufferMapReadAsyncCallback(DawnBufferMapAsyncStatus status,
const void* ptr,
uint64_t dataLength,

View File

@ -16,13 +16,14 @@
namespace dawn_wire { namespace server {
void Server::ForwardDeviceError(const char* message, void* userdata) {
void Server::ForwardDeviceError(DawnErrorType type, const char* message, void* userdata) {
auto server = static_cast<Server*>(userdata);
server->OnDeviceError(message);
server->OnDeviceError(type, message);
}
void Server::OnDeviceError(const char* message) {
void Server::OnDeviceError(DawnErrorType type, const char* message) {
ReturnDeviceErrorCallbackCmd cmd;
cmd.type = type;
cmd.message = message;
size_t requiredSize = cmd.GetRequiredSize();

View File

@ -482,7 +482,8 @@ bool DawnTest::EndExpectDeviceError() {
}
// static
void DawnTest::OnDeviceError(const char* message, void* userdata) {
void DawnTest::OnDeviceError(DawnErrorType type, const char* message, void* userdata) {
ASSERT(type != DAWN_ERROR_TYPE_NO_ERROR);
DawnTest* self = static_cast<DawnTest*>(userdata);
ASSERT_TRUE(self->mExpectError) << "Got unexpected device error: " << message;

View File

@ -212,7 +212,7 @@ class DawnTest : public ::testing::TestWithParam<DawnTestParam> {
std::unique_ptr<utils::TerribleCommandBuffer> mS2cBuf;
// Tracking for validation errors
static void OnDeviceError(const char* message, void* userdata);
static void OnDeviceError(DawnErrorType type, const char* message, void* userdata);
bool mExpectError = false;
bool mError = false;

View File

@ -84,7 +84,8 @@ std::string ValidationTest::GetLastDeviceErrorMessage() const {
}
// static
void ValidationTest::OnDeviceError(const char* message, void* userdata) {
void ValidationTest::OnDeviceError(DawnErrorType type, const char* message, void* userdata) {
ASSERT(type != DAWN_ERROR_TYPE_NO_ERROR);
auto self = static_cast<ValidationTest*>(userdata);
self->mDeviceErrorMessage = message;

View File

@ -59,7 +59,7 @@ class ValidationTest : public testing::Test {
std::unique_ptr<dawn_native::Instance> instance;
private:
static void OnDeviceError(const char* message, void* userdata);
static void OnDeviceError(DawnErrorType type, const char* message, void* userdata);
std::string mDeviceErrorMessage;
bool mExpectError = false;
bool mError = false;

View File

@ -22,12 +22,12 @@ namespace {
// Mock classes to add expectations on the wire calling callbacks
class MockDeviceErrorCallback {
public:
MOCK_METHOD2(Call, void(const char* message, void* userdata));
MOCK_METHOD3(Call, void(DawnErrorType type, const char* message, void* userdata));
};
std::unique_ptr<StrictMock<MockDeviceErrorCallback>> mockDeviceErrorCallback;
void ToMockDeviceErrorCallback(const char* message, void* userdata) {
mockDeviceErrorCallback->Call(message, userdata);
void ToMockDeviceErrorCallback(DawnErrorType type, const char* message, void* userdata) {
mockDeviceErrorCallback->Call(type, message, userdata);
}
} // anonymous namespace
@ -66,9 +66,9 @@ TEST_F(WireErrorCallbackTests, DeviceErrorCallback) {
// Calling the callback on the server side will result in the callback being called on the
// client side
api.CallDeviceErrorCallback(apiDevice, "Some error message");
api.CallDeviceErrorCallback(apiDevice, DAWN_ERROR_TYPE_VALIDATION, "Some error message");
EXPECT_CALL(*mockDeviceErrorCallback, Call(StrEq("Some error message"), this)).Times(1);
EXPECT_CALL(*mockDeviceErrorCallback, Call(DAWN_ERROR_TYPE_VALIDATION, StrEq("Some error message"), this)).Times(1);
FlushServer();
}

View File

@ -22,12 +22,12 @@ namespace {
// Mock classes to add expectations on the wire calling callbacks
class MockDeviceErrorCallback {
public:
MOCK_METHOD2(Call, void(const char* message, void* userdata));
MOCK_METHOD3(Call, void(DawnErrorType type, const char* message, void* userdata));
};
std::unique_ptr<StrictMock<MockDeviceErrorCallback>> mockDeviceErrorCallback;
void ToMockDeviceErrorCallback(const char* message, void* userdata) {
mockDeviceErrorCallback->Call(message, userdata);
void ToMockDeviceErrorCallback(DawnErrorType type, const char* message, void* userdata) {
mockDeviceErrorCallback->Call(type, message, userdata);
}
class MockFenceOnCompletionCallback {
@ -121,7 +121,7 @@ TEST_F(WireFenceTests, QueueSignalSuccess) {
// signaled value
TEST_F(WireFenceTests, QueueSignalSynchronousValidationSuccess) {
dawnDeviceSetErrorCallback(device, ToMockDeviceErrorCallback, nullptr);
EXPECT_CALL(*mockDeviceErrorCallback, Call(_, _)).Times(0);
EXPECT_CALL(*mockDeviceErrorCallback, Call(_, _, _)).Times(0);
dawnQueueSignal(queue, fence, 2u);
dawnQueueSignal(queue, fence, 4u);
@ -133,19 +133,19 @@ TEST_F(WireFenceTests, QueueSignalSynchronousValidationSuccess) {
TEST_F(WireFenceTests, QueueSignalSynchronousValidationError) {
dawnDeviceSetErrorCallback(device, ToMockDeviceErrorCallback, nullptr);
EXPECT_CALL(*mockDeviceErrorCallback, Call(_, _)).Times(1);
EXPECT_CALL(*mockDeviceErrorCallback, Call(DAWN_ERROR_TYPE_VALIDATION, _, _)).Times(1);
dawnQueueSignal(queue, fence, 0u); // Error
EXPECT_TRUE(Mock::VerifyAndClear(mockDeviceErrorCallback.get()));
EXPECT_CALL(*mockDeviceErrorCallback, Call(_, _)).Times(1);
EXPECT_CALL(*mockDeviceErrorCallback, Call(DAWN_ERROR_TYPE_VALIDATION, _, _)).Times(1);
dawnQueueSignal(queue, fence, 1u); // Error
EXPECT_TRUE(Mock::VerifyAndClear(mockDeviceErrorCallback.get()));
EXPECT_CALL(*mockDeviceErrorCallback, Call(_, _)).Times(0);
EXPECT_CALL(*mockDeviceErrorCallback, Call(_, _, _)).Times(0);
dawnQueueSignal(queue, fence, 4u); // Success
EXPECT_TRUE(Mock::VerifyAndClear(mockDeviceErrorCallback.get()));
EXPECT_CALL(*mockDeviceErrorCallback, Call(_, _)).Times(1);
EXPECT_CALL(*mockDeviceErrorCallback, Call(DAWN_ERROR_TYPE_VALIDATION, _, _)).Times(1);
dawnQueueSignal(queue, fence, 3u); // Error
EXPECT_TRUE(Mock::VerifyAndClear(mockDeviceErrorCallback.get()));
}
@ -221,7 +221,7 @@ TEST_F(WireFenceTests, OnCompletionSynchronousValidationError) {
EXPECT_CALL(*mockFenceOnCompletionCallback, Call(DAWN_FENCE_COMPLETION_STATUS_ERROR, this + 0))
.Times(1);
EXPECT_CALL(*mockDeviceErrorCallback, Call(_, this + 1)).Times(1);
EXPECT_CALL(*mockDeviceErrorCallback, Call(DAWN_ERROR_TYPE_VALIDATION, _, this + 1)).Times(1);
dawnFenceOnCompletion(fence, 2u, ToMockFenceOnCompletionCallback, this + 0);
}
@ -263,7 +263,7 @@ TEST_F(WireFenceTests, SignalWrongQueue) {
FlushClient();
dawnDeviceSetErrorCallback(device, ToMockDeviceErrorCallback, nullptr);
EXPECT_CALL(*mockDeviceErrorCallback, Call(_, _)).Times(1);
EXPECT_CALL(*mockDeviceErrorCallback, Call(DAWN_ERROR_TYPE_VALIDATION, _, _)).Times(1);
dawnQueueSignal(queue2, fence, 2u); // error
}
@ -275,7 +275,7 @@ TEST_F(WireFenceTests, SignalWrongQueueDoesNotUpdateValue) {
FlushClient();
dawnDeviceSetErrorCallback(device, ToMockDeviceErrorCallback, nullptr);
EXPECT_CALL(*mockDeviceErrorCallback, Call(_, _)).Times(1);
EXPECT_CALL(*mockDeviceErrorCallback, Call(DAWN_ERROR_TYPE_VALIDATION, _, _)).Times(1);
dawnQueueSignal(queue2, fence, 2u); // error
// Fence value should be unchanged.