diff options
| -rw-r--r-- | source/compiler-core/slang-test-server-protocol.cpp | 1 | ||||
| -rw-r--r-- | source/compiler-core/slang-test-server-protocol.h | 1 | ||||
| -rw-r--r-- | source/core/slang-process-util.h | 2 | ||||
| -rw-r--r-- | source/core/slang-std-writers.h | 25 | ||||
| -rw-r--r-- | tools/gfx-unit-test/gfx-test-util.cpp | 29 | ||||
| -rw-r--r-- | tools/render-test/render-test-main.cpp | 22 | ||||
| -rw-r--r-- | tools/render-test/slang-support.h | 56 | ||||
| -rw-r--r-- | tools/slang-test/slang-test-main.cpp | 40 | ||||
| -rw-r--r-- | tools/test-server/test-server-main.cpp | 11 | ||||
| -rw-r--r-- | tools/unit-test/slang-unit-test.h | 6 |
10 files changed, 146 insertions, 47 deletions
diff --git a/source/compiler-core/slang-test-server-protocol.cpp b/source/compiler-core/slang-test-server-protocol.cpp index 4b1f210d1..a9a0c5420 100644 --- a/source/compiler-core/slang-test-server-protocol.cpp +++ b/source/compiler-core/slang-test-server-protocol.cpp @@ -36,6 +36,7 @@ static const StructRttiInfo _makeExecutionResultRtti() StructRttiBuilder builder(&obj, "TestServerProtocol::ExecutionResult", nullptr); builder.addField("stdOut", &obj.stdOut); builder.addField("stdError", &obj.stdError); + builder.addField("debugLayer", &obj.debugLayer); builder.addField("result", &obj.result); builder.addField("returnCode", &obj.returnCode); return builder.make(); diff --git a/source/compiler-core/slang-test-server-protocol.h b/source/compiler-core/slang-test-server-protocol.h index 7d7ad2389..f0e8dcab1 100644 --- a/source/compiler-core/slang-test-server-protocol.h +++ b/source/compiler-core/slang-test-server-protocol.h @@ -42,6 +42,7 @@ struct ExecutionResult { String stdOut; String stdError; + String debugLayer; int32_t result = SLANG_OK; int32_t returnCode = 0; ///< As returned if invoked as command line diff --git a/source/core/slang-process-util.h b/source/core/slang-process-util.h index 25cf0aca3..6c765b6cd 100644 --- a/source/core/slang-process-util.h +++ b/source/core/slang-process-util.h @@ -16,11 +16,13 @@ struct ExecuteResult resultCode = 0; standardOutput = String(); standardError = String(); + debugLayer = String(); } ResultCode resultCode; String standardOutput; String standardError; + String debugLayer; }; struct ProcessUtil diff --git a/source/core/slang-std-writers.h b/source/core/slang-std-writers.h index bb67d9d9c..bb38d12e0 100644 --- a/source/core/slang-std-writers.h +++ b/source/core/slang-std-writers.h @@ -7,6 +7,27 @@ namespace Slang { +enum class DebugMessageType +{ + Info, + Warning, + Error +}; + +enum class DebugMessageSource +{ + Layer, + Driver, + Slang +}; + +class IDebugCallback +{ +public: + virtual SLANG_NO_THROW void SLANG_MCALL + handleMessage(DebugMessageType type, DebugMessageSource source, const char* message) = 0; +}; + /* Holds standard writers for the channels */ class StdWriters : public RefObject { @@ -14,6 +35,9 @@ public: ISlangWriter* getWriter(SlangWriterChannel chan) const { return m_writers[chan]; } void setWriter(SlangWriterChannel chan, ISlangWriter* writer) { m_writers[chan] = writer; } + IDebugCallback* getDebugCallback() const { return m_debugCallback; } + void setDebugCallback(IDebugCallback* callback) { m_debugCallback = callback; } + /// Flush all the set writers void flushWriters(); @@ -42,6 +66,7 @@ public: protected: ComPtr<ISlangWriter> m_writers[SLANG_WRITER_CHANNEL_COUNT_OF]; + IDebugCallback* m_debugCallback = nullptr; static StdWriters* s_singleton; }; diff --git a/tools/gfx-unit-test/gfx-test-util.cpp b/tools/gfx-unit-test/gfx-test-util.cpp index b5a39a4f0..2e3efe09f 100644 --- a/tools/gfx-unit-test/gfx-test-util.cpp +++ b/tools/gfx-unit-test/gfx-test-util.cpp @@ -15,33 +15,6 @@ using Slang::ComPtr; namespace gfx_test { -class DebugPrinter : public rhi::IDebugCallback -{ -public: - virtual SLANG_NO_THROW void SLANG_MCALL handleMessage( - rhi::DebugMessageType type, - rhi::DebugMessageSource source, - const char* message) override - { - static const char* kTypeStrings[] = {"INFO", "WARN", "ERROR"}; - static const char* kSourceStrings[] = {"Layer", "Driver", "Slang"}; - if (type == rhi::DebugMessageType::Error) - { - fprintf( - stderr, - "[%s] (%s) %s\n", - kTypeStrings[int(type)], - kSourceStrings[int(source)], - message); - fflush(stderr); - } - } - static DebugPrinter* getInstance() - { - static DebugPrinter instance; - return &instance; - } -}; void diagnoseIfNeeded(slang::IBlob* diagnosticsBlob) { @@ -278,7 +251,7 @@ Slang::ComPtr<IDevice> createTestingDevice( if (context->enableDebugLayers) { deviceDesc.enableValidation = context->enableDebugLayers; - deviceDesc.debugCallback = DebugPrinter::getInstance(); + deviceDesc.debugCallback = context->debugCallback; } D3D12DeviceExtendedDesc extDesc = {}; diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp index 23035280c..af0415bd0 100644 --- a/tools/render-test/render-test-main.cpp +++ b/tools/render-test/render-test-main.cpp @@ -4,6 +4,7 @@ #include "../../source/core/slang-test-tool-util.h" #include "../source/core/slang-io.h" +#include "../source/core/slang-std-writers.h" #include "../source/core/slang-string-util.h" #include "core/slang-token-reader.h" #include "options.h" @@ -1322,23 +1323,6 @@ static void renderDocBeginFrame() {} static void renderDocEndFrame() {} #endif -class StdWritersDebugCallback : public rhi::IDebugCallback -{ -public: - Slang::StdWriters* writers; - virtual SLANG_NO_THROW void SLANG_MCALL handleMessage( - rhi::DebugMessageType type, - rhi::DebugMessageSource source, - const char* message) override - { - SLANG_UNUSED(source); - if (type == rhi::DebugMessageType::Error) - { - writers->getOut().print("%s\n", message); - } - } -}; - static SlangResult _innerMain( Slang::StdWriters* stdWriters, SlangSession* session, @@ -1456,8 +1440,8 @@ static SlangResult _innerMain( } } - StdWritersDebugCallback debugCallback; - debugCallback.writers = stdWriters; + renderer_test::CoreToRHIDebugBridge debugCallback; + debugCallback.setCoreCallback(stdWriters->getDebugCallback()); // Use the profile name set on options if set input.profile = options.profileName.getLength() ? options.profileName : input.profile; diff --git a/tools/render-test/slang-support.h b/tools/render-test/slang-support.h index 916166c3a..51a2c8de1 100644 --- a/tools/render-test/slang-support.h +++ b/tools/render-test/slang-support.h @@ -1,6 +1,7 @@ // slang-support.h #pragma once +#include "core/slang-std-writers.h" #include "options.h" #include "shader-input-layout.h" #include "slang.h" @@ -10,6 +11,61 @@ namespace renderer_test { +/// Bridge from core debug callback to RHI debug callback +/// This allows core callbacks to receive messages from RHI systems +/// TODO: We should replace rhi::IDebugCallback with Slang::IDebugCallback. +class CoreToRHIDebugBridge : public rhi::IDebugCallback +{ +public: + void setCoreCallback(Slang::IDebugCallback* coreCallback) { m_coreCallback = coreCallback; } + + virtual SLANG_NO_THROW void SLANG_MCALL handleMessage( + rhi::DebugMessageType type, + rhi::DebugMessageSource source, + const char* message) override + { + if (m_coreCallback) + { + // Convert RHI types to core types + Slang::DebugMessageType coreType = static_cast<Slang::DebugMessageType>(type); + Slang::DebugMessageSource coreSource = static_cast<Slang::DebugMessageSource>(source); + m_coreCallback->handleMessage(coreType, coreSource, message); + } + } + +private: + Slang::IDebugCallback* m_coreCallback = nullptr; +}; + +/// Core debug callback that captures debug messages in a string buffer +class CoreDebugCallback : public Slang::IDebugCallback +{ +public: + virtual SLANG_NO_THROW void SLANG_MCALL handleMessage( + Slang::DebugMessageType type, + Slang::DebugMessageSource source, + const char* message) override + { + SLANG_UNUSED(source); + + // Only capture error messages + if (type == Slang::DebugMessageType::Error) + { + m_buf << message; + if (message[strlen(message) - 1] != '\n') + { + m_buf << '\n'; + } + } + } + + void clear() { m_buf.clear(); } + Slang::String getString() { return m_buf.toString(); } + +private: + Slang::StringBuilder m_buf; +}; + struct ShaderCompileRequest { struct SourceInfo diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp index 54ec1a842..97c63c392 100644 --- a/tools/slang-test/slang-test-main.cpp +++ b/tools/slang-test/slang-test-main.cpp @@ -24,6 +24,7 @@ #include "../../source/compiler-core/slang-downstream-compiler.h" #include "../../source/compiler-core/slang-language-server-protocol.h" #include "../../source/compiler-core/slang-nvrtc-compiler.h" +#include "../render-test/slang-support.h" #include "directory-util.h" #include "options.h" #include "parse-diagnostic-util.h" @@ -844,6 +845,9 @@ Result spawnAndWaitSharedLibrary( { StringBuilder stdErrorString; StringBuilder stdOutString; + renderer_test::CoreDebugCallback coreDebugCallback; + renderer_test::CoreToRHIDebugBridge rhiDebugBridge; + rhiDebugBridge.setCoreCallback(&coreDebugCallback); // Say static so not released StringWriter stdError(&stdErrorString, WriterFlag::IsConsole | WriterFlag::IsStatic); @@ -854,6 +858,7 @@ Result spawnAndWaitSharedLibrary( StdWriters stdWriters; stdWriters.setWriter(SLANG_WRITER_CHANNEL_STD_ERROR, &stdError); stdWriters.setWriter(SLANG_WRITER_CHANNEL_STD_OUTPUT, &stdOut); + stdWriters.setDebugCallback(&coreDebugCallback); if (exeName == "slangc" || exeName == "slangi") { @@ -876,6 +881,7 @@ Result spawnAndWaitSharedLibrary( outRes.standardError = stdErrorString; outRes.standardOutput = stdOutString; + outRes.debugLayer = coreDebugCallback.getString(); outRes.resultCode = (int)TestToolUtil::getReturnCode(res); @@ -1013,6 +1019,7 @@ static Result _executeRPC( outRes.resultCode = exeRes.returnCode; outRes.standardError = exeRes.stdError; outRes.standardOutput = exeRes.stdOut; + outRes.debugLayer = exeRes.debugLayer; return SLANG_OK; } @@ -1530,6 +1537,7 @@ String getOutput(const ExecuteResult& exeRes) String standardOuptut = exeRes.standardOutput; String standardError = exeRes.standardError; + String debugLayer = exeRes.debugLayer; // We construct a single output string that captures the results StringBuilder actualOutputBuilder; @@ -1540,6 +1548,12 @@ String getOutput(const ExecuteResult& exeRes) actualOutputBuilder.append("}\nstandard output = {\n"); actualOutputBuilder.append(standardOuptut); actualOutputBuilder.append("}\n"); + if (debugLayer.getLength() > 0) + { + actualOutputBuilder.append("debug layer = {\n"); + actualOutputBuilder.append(debugLayer); + actualOutputBuilder.append("}\n"); + } return actualOutputBuilder.produceString(); } @@ -3262,6 +3276,7 @@ static TestResult _runHLSLComparisonTest( String standardOutput = exeRes.standardOutput; String standardError = exeRes.standardError; + String debugLayer = exeRes.debugLayer; // We construct a single output string that captures the results StringBuilder actualOutputBuilder; @@ -3272,6 +3287,12 @@ static TestResult _runHLSLComparisonTest( actualOutputBuilder.append("}\nstandard output = {\n"); actualOutputBuilder.append(standardOutput); actualOutputBuilder.append("}\n"); + if (debugLayer.getLength() > 0) + { + actualOutputBuilder.append("debug layer = {\n"); + actualOutputBuilder.append(debugLayer); + actualOutputBuilder.append("}\n"); + } String actualOutput = actualOutputBuilder.produceString(); @@ -3339,6 +3360,7 @@ TestResult doGLSLComparisonTestRun( String standardOuptut = exeRes.standardOutput; String standardError = exeRes.standardError; + String debugLayer = exeRes.debugLayer; // We construct a single output string that captures the results StringBuilder outputBuilder; @@ -3349,6 +3371,12 @@ TestResult doGLSLComparisonTestRun( outputBuilder.append("}\nstandard output = {\n"); outputBuilder.append(standardOuptut); outputBuilder.append("}\n"); + if (debugLayer.getLength() > 0) + { + outputBuilder.append("debug layer = {\n"); + outputBuilder.append(debugLayer); + outputBuilder.append("}\n"); + } String outputPath = outputStem + outputKind; String output = outputBuilder.produceString(); @@ -3748,6 +3776,7 @@ TestResult doRenderComparisonTestRun( String standardOutput = exeRes.standardOutput; String standardError = exeRes.standardError; + String debugLayer = exeRes.debugLayer; // We construct a single output string that captures the results StringBuilder outputBuilder; @@ -3758,6 +3787,12 @@ TestResult doRenderComparisonTestRun( outputBuilder.append("}\nstandard output = {\n"); outputBuilder.append(standardOutput); outputBuilder.append("}\n"); + if (debugLayer.getLength() > 0) + { + outputBuilder.append("debug layer = {\n"); + outputBuilder.append(debugLayer); + outputBuilder.append("}\n"); + } String outputPath = outputStem + outputKind; String output = outputBuilder.produceString(); @@ -4733,12 +4768,17 @@ static SlangResult runUnitTestModule( if (!testModule) return SLANG_FAIL; + renderer_test::CoreDebugCallback coreDebugCallback; + renderer_test::CoreToRHIDebugBridge rhiDebugBridge; + rhiDebugBridge.setCoreCallback(&coreDebugCallback); + UnitTestContext unitTestContext; unitTestContext.slangGlobalSession = context->getSession(); unitTestContext.workDirectory = ""; unitTestContext.enabledApis = context->options.enabledApis; unitTestContext.enableDebugLayers = context->options.enableDebugLayers; unitTestContext.executableDirectory = context->exeDirectoryPath.getBuffer(); + unitTestContext.debugCallback = &rhiDebugBridge; auto testCount = testModule->getTestCount(); diff --git a/tools/test-server/test-server-main.cpp b/tools/test-server/test-server-main.cpp index a2f7f8153..e98be6e5a 100644 --- a/tools/test-server/test-server-main.cpp +++ b/tools/test-server/test-server-main.cpp @@ -10,7 +10,10 @@ #include "../../source/core/slang-string.h" #include "../../source/core/slang-test-tool-util.h" #include "../../source/core/slang-writer.h" +#include "../render-test/slang-support.h" +#include "gfx-unit-test/gfx-test-util.h" #include "slang-com-helper.h" +#include "slang-rhi.h" #include "test-server-diagnostics.h" #include "unit-test/slang-unit-test.h" @@ -422,6 +425,9 @@ SlangResult TestServer::_executeUnitTest(const JSONRPCCall& call) } TestReporter testReporter; + renderer_test::CoreDebugCallback coreDebugCallback; + renderer_test::CoreToRHIDebugBridge rhiDebugCallback; + rhiDebugCallback.setCoreCallback(&coreDebugCallback); testModule->setTestReporter(&testReporter); @@ -438,6 +444,7 @@ SlangResult TestServer::_executeUnitTest(const JSONRPCCall& call) unitTestContext.enabledApis = RenderApiFlags(args.enabledApis); unitTestContext.executableDirectory = m_exeDirectory.getBuffer(); unitTestContext.enableDebugLayers = args.enableDebugLayers; + unitTestContext.debugCallback = &rhiDebugCallback; auto testCount = testModule->getTestCount(); SLANG_ASSERT(testIndex >= 0 && testIndex < testCount); @@ -455,6 +462,7 @@ SlangResult TestServer::_executeUnitTest(const JSONRPCCall& call) TestServerProtocol::ExecutionResult result; result.result = SLANG_OK; + result.debugLayer = coreDebugCallback.getString(); if (testReporter.m_failCount > 0) { @@ -508,6 +516,7 @@ SlangResult TestServer::_executeTool(const JSONRPCCall& call) StdWriters stdWriters; StringBuilder stdOut; StringBuilder stdError; + renderer_test::CoreDebugCallback debugCallback; // Make writer/s act as if they are the console. RefPtr<StringWriter> stdOutWriter(new StringWriter(&stdOut, WriterFlag::IsConsole)); @@ -515,6 +524,7 @@ SlangResult TestServer::_executeTool(const JSONRPCCall& call) stdWriters.setWriter(SLANG_WRITER_CHANNEL_STD_ERROR, stdErrorWriter); stdWriters.setWriter(SLANG_WRITER_CHANNEL_STD_OUTPUT, stdOutWriter); + stdWriters.setDebugCallback(&debugCallback); // HACK, to make behavior the same as previously if (args.toolName == "slangc") @@ -529,6 +539,7 @@ SlangResult TestServer::_executeTool(const JSONRPCCall& call) result.result = funcRes; result.stdError = stdError; result.stdOut = stdOut; + result.debugLayer = debugCallback.getString(); result.returnCode = int32_t(TestToolUtil::getReturnCode(result.result)); return m_connection->sendResult(&result, id); diff --git a/tools/unit-test/slang-unit-test.h b/tools/unit-test/slang-unit-test.h index 49cb5d8d7..db921ded9 100644 --- a/tools/unit-test/slang-unit-test.h +++ b/tools/unit-test/slang-unit-test.h @@ -37,6 +37,11 @@ public: ITestReporter* getTestReporter(); +namespace rhi +{ +class IDebugCallback; +} + struct UnitTestContext { slang::IGlobalSession* slangGlobalSession; @@ -44,6 +49,7 @@ struct UnitTestContext const char* executableDirectory; Slang::RenderApiFlags enabledApis; bool enableDebugLayers; + rhi::IDebugCallback* debugCallback = nullptr; }; typedef void (*UnitTestFunc)(UnitTestContext*); |
