diff --git a/dawn.json b/dawn.json index d52b9d170f..3d8f070983 100644 --- a/dawn.json +++ b/dawn.json @@ -1096,6 +1096,14 @@ {"name": "descriptor", "type": "shader module descriptor", "annotation": "const*"} ] }, + { + "name": "create error shader module", + "returns": "shader module", + "args": [ + {"name": "descriptor", "type": "shader module descriptor", "annotation": "const*"}, + {"name": "error message", "type": "char", "annotation": "const*", "length": "strlen"} + ] + }, { "name": "create swap chain", "returns": "swap chain", diff --git a/src/dawn/native/CompilationMessages.cpp b/src/dawn/native/CompilationMessages.cpp index 7c8e4e9983..4dfa257a91 100644 --- a/src/dawn/native/CompilationMessages.cpp +++ b/src/dawn/native/CompilationMessages.cpp @@ -77,12 +77,12 @@ OwnedCompilationMessages::OwnedCompilationMessages() { OwnedCompilationMessages::~OwnedCompilationMessages() = default; -void OwnedCompilationMessages::AddMessageForTesting(std::string message, - wgpu::CompilationMessageType type, - uint64_t lineNum, - uint64_t linePos, - uint64_t offset, - uint64_t length) { +void OwnedCompilationMessages::AddMessage(std::string message, + wgpu::CompilationMessageType type, + uint64_t lineNum, + uint64_t linePos, + uint64_t offset, + uint64_t length) { // Cannot add messages after GetCompilationInfo has been called. ASSERT(mCompilationInfo.messages == nullptr); diff --git a/src/dawn/native/CompilationMessages.h b/src/dawn/native/CompilationMessages.h index 9adf8f3efe..c5c427d522 100644 --- a/src/dawn/native/CompilationMessages.h +++ b/src/dawn/native/CompilationMessages.h @@ -37,13 +37,12 @@ class OwnedCompilationMessages : public NonCopyable { OwnedCompilationMessages(); ~OwnedCompilationMessages(); - void AddMessageForTesting( - std::string message, - wgpu::CompilationMessageType type = wgpu::CompilationMessageType::Info, - uint64_t lineNum = 0, - uint64_t linePos = 0, - uint64_t offset = 0, - uint64_t length = 0); + void AddMessage(std::string message, + wgpu::CompilationMessageType type = wgpu::CompilationMessageType::Info, + uint64_t lineNum = 0, + uint64_t linePos = 0, + uint64_t offset = 0, + uint64_t length = 0); MaybeError AddMessages(const tint::diag::List& diagnostics); void ClearMessages(); diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp index 4d774568e7..43e2787f1f 100644 --- a/src/dawn/native/Device.cpp +++ b/src/dawn/native/Device.cpp @@ -1248,6 +1248,21 @@ ShaderModuleBase* DeviceBase::APICreateShaderModule(const ShaderModuleDescriptor return result.Detach(); } +ShaderModuleBase* DeviceBase::APICreateErrorShaderModule(const ShaderModuleDescriptor* descriptor, + const char* errorMessage) { + Ref result = + ShaderModuleBase::MakeError(this, descriptor ? descriptor->label : nullptr); + std::unique_ptr compilationMessages( + std::make_unique()); + compilationMessages->AddMessage(errorMessage, wgpu::CompilationMessageType::Error); + result->InjectCompilationMessages(std::move(compilationMessages)); + + std::unique_ptr errorData = + DAWN_VALIDATION_ERROR("Error in calling %s.CreateShaderModule(%s).", this, descriptor); + ConsumeError(std::move(errorData)); + + return result.Detach(); +} SwapChainBase* DeviceBase::APICreateSwapChain(Surface* surface, const SwapChainDescriptor* descriptor) { Ref result; diff --git a/src/dawn/native/Device.h b/src/dawn/native/Device.h index 28a7f2a440..7601f7d5f3 100644 --- a/src/dawn/native/Device.h +++ b/src/dawn/native/Device.h @@ -285,6 +285,8 @@ class DeviceBase : public RefCountedWithExternalCount { ExternalTextureBase* APICreateExternalTexture(const ExternalTextureDescriptor* descriptor); SamplerBase* APICreateSampler(const SamplerDescriptor* descriptor); ShaderModuleBase* APICreateShaderModule(const ShaderModuleDescriptor* descriptor); + ShaderModuleBase* APICreateErrorShaderModule(const ShaderModuleDescriptor* descriptor, + const char* errorMessage); SwapChainBase* APICreateSwapChain(Surface* surface, const SwapChainDescriptor* descriptor); TextureBase* APICreateTexture(const TextureDescriptor* descriptor); diff --git a/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp b/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp index 8414dadcb2..34b76c9738 100644 --- a/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp @@ -254,11 +254,10 @@ TEST_F(ShaderModuleValidationTest, GetCompilationMessages) { native::ShaderModuleBase* shaderModuleBase = native::FromAPI(shaderModule.Get()); native::OwnedCompilationMessages* messages = shaderModuleBase->GetCompilationMessages(); messages->ClearMessages(); - messages->AddMessageForTesting("Info Message"); - messages->AddMessageForTesting("Warning Message", wgpu::CompilationMessageType::Warning); - messages->AddMessageForTesting("Error Message", wgpu::CompilationMessageType::Error, 3, 4); - messages->AddMessageForTesting("Complete Message", wgpu::CompilationMessageType::Info, 3, 4, 5, - 6); + messages->AddMessage("Info Message"); + messages->AddMessage("Warning Message", wgpu::CompilationMessageType::Warning); + messages->AddMessage("Error Message", wgpu::CompilationMessageType::Error, 3, 4); + messages->AddMessage("Complete Message", wgpu::CompilationMessageType::Info, 3, 4, 5, 6); auto callback = [](WGPUCompilationInfoRequestStatus status, const WGPUCompilationInfo* info, void* userdata) { @@ -728,5 +727,34 @@ TEST_F(ShaderModuleValidationTest, SourceToCodeMemberDeprecation) { native::FromAPI(codeShader.Get()))); } +// Test creating an error shader module with device.CreateErrorShaderModule() +TEST_F(ShaderModuleValidationTest, CreateErrorShaderModule) { + wgpu::ShaderModuleWGSLDescriptor wgslDesc = {}; + wgpu::ShaderModuleDescriptor descriptor = {}; + descriptor.nextInChain = &wgslDesc; + wgslDesc.code = "@compute @workgroup_size(1) fn main() {}"; + + wgpu::ShaderModule errorShaderModule; + ASSERT_DEVICE_ERROR(errorShaderModule = device.CreateErrorShaderModule( + &descriptor, "Shader compilation error")); + + auto callback = [](WGPUCompilationInfoRequestStatus status, const WGPUCompilationInfo* info, + void* userdata) { + ASSERT_EQ(WGPUCompilationInfoRequestStatus_Success, status); + ASSERT_NE(nullptr, info); + ASSERT_EQ(1u, info->messageCount); + + const WGPUCompilationMessage* message = &info->messages[0]; + ASSERT_STREQ("Shader compilation error", message->message); + ASSERT_EQ(WGPUCompilationMessageType_Error, message->type); + ASSERT_EQ(0u, message->lineNum); + ASSERT_EQ(0u, message->linePos); + }; + + errorShaderModule.GetCompilationInfo(callback, nullptr); + + FlushWire(); +} + } // anonymous namespace } // namespace dawn