diff options
| author | Ellie Hermaszewska <ellieh@nvidia.com> | 2024-10-29 14:49:26 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-29 14:49:26 +0800 |
| commit | f65d756bff8d4c5cbc15bd0322a2ae8e6b896a21 (patch) | |
| tree | ea1d61342cd29368e19135000ec2948813096205 /tools/render-test | |
| parent | a729c15e9dce9f5116a38afc66329ab2ca4cea54 (diff) | |
format
* format
* Minor test fixes
* enable checking cpp format in ci
Diffstat (limited to 'tools/render-test')
| -rw-r--r-- | tools/render-test/diagnostic-defs.h | 14 | ||||
| -rw-r--r-- | tools/render-test/diagnostics.cpp | 13 | ||||
| -rw-r--r-- | tools/render-test/diagnostics.h | 10 | ||||
| -rw-r--r-- | tools/render-test/options.cpp | 97 | ||||
| -rw-r--r-- | tools/render-test/options.h | 36 | ||||
| -rw-r--r-- | tools/render-test/png-serialize-util.cpp | 7 | ||||
| -rw-r--r-- | tools/render-test/png-serialize-util.h | 12 | ||||
| -rw-r--r-- | tools/render-test/render-test-main.cpp | 584 | ||||
| -rw-r--r-- | tools/render-test/shader-input-layout.cpp | 2396 | ||||
| -rw-r--r-- | tools/render-test/shader-input-layout.h | 75 | ||||
| -rw-r--r-- | tools/render-test/shader-renderer-util.cpp | 47 | ||||
| -rw-r--r-- | tools/render-test/shader-renderer-util.h | 18 | ||||
| -rw-r--r-- | tools/render-test/slang-support.cpp | 225 | ||||
| -rw-r--r-- | tools/render-test/slang-support.h | 66 |
14 files changed, 1927 insertions, 1673 deletions
diff --git a/tools/render-test/diagnostic-defs.h b/tools/render-test/diagnostic-defs.h index e48012550..58f1fe6a6 100644 --- a/tools/render-test/diagnostic-defs.h +++ b/tools/render-test/diagnostic-defs.h @@ -14,7 +14,7 @@ // for any arguments. #ifndef DIAGNOSTIC -#error Need to #define DIAGNOSTIC(...) before including +#error Need to #define DIAGNOSTIC(...) before including #define DIAGNOSTIC(id, severity, name, messageFormat) /* */ #endif @@ -23,8 +23,16 @@ // -DIAGNOSTIC(1001, Error, expectingCommaComputeDispatch, "expected 3 comma separated integers for compute dispatch size") -DIAGNOSTIC(1002, Error, expectingPositiveComputeDispatch, "expected 3 comma positive integers for compute dispatch size") +DIAGNOSTIC( + 1001, + Error, + expectingCommaComputeDispatch, + "expected 3 comma separated integers for compute dispatch size") +DIAGNOSTIC( + 1002, + Error, + expectingPositiveComputeDispatch, + "expected 3 comma positive integers for compute dispatch size") DIAGNOSTIC(1003, Error, unknownSourceLanguage, "unknown source language name") DIAGNOSTIC(1003, Error, unknown, "unknown source language name") DIAGNOSTIC(1004, Error, unknownCommandLineOption, "unknown command-line option '$0'") diff --git a/tools/render-test/diagnostics.cpp b/tools/render-test/diagnostics.cpp index 2bc337256..929642976 100644 --- a/tools/render-test/diagnostics.cpp +++ b/tools/render-test/diagnostics.cpp @@ -1,18 +1,19 @@ // diagnostics.cpp #include "diagnostics.h" -namespace Slang { +namespace Slang +{ namespace RenderTestDiagnostics { -#define DIAGNOSTIC(id, severity, name, messageFormat) const DiagnosticInfo name = { id, Severity::severity, #name, messageFormat }; +#define DIAGNOSTIC(id, severity, name, messageFormat) \ + const DiagnosticInfo name = {id, Severity::severity, #name, messageFormat}; #include "diagnostic-defs.h" #undef DIAGNOSTIC -} +} // namespace RenderTestDiagnostics -static const DiagnosticInfo* const kDiagnostics[] = -{ -#define DIAGNOSTIC(id, severity, name, messageFormat) &RenderTestDiagnostics::name, +static const DiagnosticInfo* const kDiagnostics[] = { +#define DIAGNOSTIC(id, severity, name, messageFormat) &RenderTestDiagnostics::name, #include "diagnostic-defs.h" #undef DIAGNOSTIC }; diff --git a/tools/render-test/diagnostics.h b/tools/render-test/diagnostics.h index fa4c8a389..26872f5fa 100644 --- a/tools/render-test/diagnostics.h +++ b/tools/render-test/diagnostics.h @@ -1,12 +1,10 @@ #ifndef SLANG_CORE_DIAGNOSTICS_H #define SLANG_CORE_DIAGNOSTICS_H +#include "../../source/compiler-core/slang-diagnostic-sink.h" +#include "../../source/compiler-core/slang-source-loc.h" #include "../../source/core/slang-basic.h" #include "../../source/core/slang-writer.h" - -#include "../../source/compiler-core/slang-source-loc.h" -#include "../../source/compiler-core/slang-diagnostic-sink.h" - #include "slang.h" namespace Slang @@ -18,8 +16,8 @@ namespace RenderTestDiagnostics { #define DIAGNOSTIC(id, severity, name, messageFormat) extern const DiagnosticInfo name; #include "diagnostic-defs.h" -} +} // namespace RenderTestDiagnostics -} +} // namespace Slang #endif diff --git a/tools/render-test/options.cpp b/tools/render-test/options.cpp index 07e8b0e2a..68efacca3 100644 --- a/tools/render-test/options.cpp +++ b/tools/render-test/options.cpp @@ -2,24 +2,22 @@ #include "options.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "../../source/core/slang-writer.h" -#include "../../source/core/slang-render-api-util.h" - #include "../../source/core/slang-list.h" +#include "../../source/core/slang-render-api-util.h" #include "../../source/core/slang-string-util.h" -//#include "../../source/core/slang-downstream-compiler.h" +#include "../../source/core/slang-writer.h" -#include "../../source/core/slang-type-text-util.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +// #include "../../source/core/slang-downstream-compiler.h" #include "../../source/compiler-core/slang-command-line-args.h" - +#include "../../source/core/slang-type-text-util.h" #include "diagnostics.h" -namespace renderer_test { +namespace renderer_test +{ using namespace Slang; static rhi::DeviceType _toRenderType(Slang::RenderApiType apiType) @@ -34,12 +32,15 @@ static rhi::DeviceType _toRenderType(Slang::RenderApiType apiType) case RenderApiType::CPU: return rhi::DeviceType::CPU; case RenderApiType::CUDA: return rhi::DeviceType::CUDA; case RenderApiType::WebGPU: return rhi::DeviceType::WGPU; - default: - return rhi::DeviceType::Default; + default: return rhi::DeviceType::Default; } } -/* static */SlangResult Options::parse(int argc, const char*const* argv, Slang::WriterHelper stdError, Options& outOptions) +/* static */ SlangResult Options::parse( + int argc, + const char* const* argv, + Slang::WriterHelper stdError, + Options& outOptions) { using namespace Slang; @@ -48,7 +49,7 @@ static rhi::DeviceType _toRenderType(Slang::RenderApiType apiType) DiagnosticSink sink(cmdLineContext->getSourceManager(), nullptr); sink.writer = stdError.getWriter(); sink.setFlag(DiagnosticSink::Flag::SourceLocationLine); - + outOptions = Options(); CommandLineArgs args(cmdLineContext); @@ -78,7 +79,7 @@ static rhi::DeviceType _toRenderType(Slang::RenderApiType apiType) CommandLineArg arg = reader.getArgAndAdvance(); const auto& argValue = arg.value; - if(!argValue.startsWith("-")) + if (!argValue.startsWith("-")) { positionalArgs.add(arg); continue; @@ -92,7 +93,7 @@ static rhi::DeviceType _toRenderType(Slang::RenderApiType apiType) } break; } - else if(argValue == "-o") + else if (argValue == "-o") { SLANG_RETURN_ON_FAIL(reader.expectArg(outOptions.outputPath)); } @@ -113,7 +114,7 @@ static rhi::DeviceType _toRenderType(Slang::RenderApiType apiType) outOptions.renderFeatures.add(value); } } - else if( argValue == "-xslang" || argValue == "-compile-arg") + else if (argValue == "-xslang" || argValue == "-compile-arg") { // This is legacy support, should use -Xslang now // This is an option that we want to pass along to Slang @@ -121,14 +122,14 @@ static rhi::DeviceType _toRenderType(Slang::RenderApiType apiType) SLANG_RETURN_ON_FAIL(reader.expectArg(slangArg)); outOptions.downstreamArgs.getArgsByName("slang").add(slangArg); } - else if (argValue == "-compute") - { - outOptions.shaderType = ShaderProgramType::Compute; - } - else if (argValue == "-graphics") - { - outOptions.shaderType = ShaderProgramType::Graphics; - } + else if (argValue == "-compute") + { + outOptions.shaderType = ShaderProgramType::Compute; + } + else if (argValue == "-graphics") + { + outOptions.shaderType = ShaderProgramType::Graphics; + } else if (argValue == "-gcompute") { outOptions.shaderType = ShaderProgramType::GraphicsCompute; @@ -145,17 +146,17 @@ static rhi::DeviceType _toRenderType(Slang::RenderApiType apiType) { outOptions.shaderType = ShaderProgramType::GraphicsTaskMeshCompute; } - else if(argValue == "-use-dxil") + else if (argValue == "-use-dxil") { outOptions.useDXIL = true; } else if (argValue == "-emit-spirv-directly") { - outOptions.generateSPIRVDirectly= true; + outOptions.generateSPIRVDirectly = true; } else if (argValue == "-emit-spirv-via-glsl") { - outOptions.generateSPIRVDirectly= false; + outOptions.generateSPIRVDirectly = false; } else if (argValue == "-only-startup") { @@ -178,10 +179,12 @@ static rhi::DeviceType _toRenderType(Slang::RenderApiType apiType) StringUtil::split(dispatchSize.value.getUnownedSlice(), ',', slices); if (slices.getCount() != 3) { - sink.diagnose(dispatchSize.loc, RenderTestDiagnostics::expectingCommaComputeDispatch); + sink.diagnose( + dispatchSize.loc, + RenderTestDiagnostics::expectingCommaComputeDispatch); return SLANG_FAIL; } - + String string; for (Index i = 0; i < 3; ++i) { @@ -189,7 +192,9 @@ static rhi::DeviceType _toRenderType(Slang::RenderApiType apiType) int v = stringToInt(string); if (v < 1) { - sink.diagnose(dispatchSize.loc, RenderTestDiagnostics::expectingPositiveComputeDispatch); + sink.diagnose( + dispatchSize.loc, + RenderTestDiagnostics::expectingPositiveComputeDispatch); return SLANG_FAIL; } outOptions.computeDispatchSize[i] = v; @@ -199,8 +204,9 @@ static rhi::DeviceType _toRenderType(Slang::RenderApiType apiType) { CommandLineArg sourceLanguageName; SLANG_RETURN_ON_FAIL(reader.expectArg(sourceLanguageName)); - - const SlangSourceLanguage sourceLanguage = TypeTextUtil::findSourceLanguage(sourceLanguageName.value.getUnownedSlice()); + + const SlangSourceLanguage sourceLanguage = + TypeTextUtil::findSourceLanguage(sourceLanguageName.value.getUnownedSlice()); if (sourceLanguage == SLANG_SOURCE_LANGUAGE_UNKNOWN) { sink.diagnose(sourceLanguageName.loc, RenderTestDiagnostics::unknownSourceLanguage); @@ -209,7 +215,7 @@ static rhi::DeviceType _toRenderType(Slang::RenderApiType apiType) outOptions.sourceLanguage = sourceLanguage; } - else if(argValue == "-no-default-entry-point") + else if (argValue == "-no-default-entry-point") { outOptions.dontAddDefaultEntryPoints = true; } @@ -252,12 +258,17 @@ static rhi::DeviceType _toRenderType(Slang::RenderApiType apiType) } // Lookup the target language type - DeviceType targetLanguageDeviceType = _toRenderType(RenderApiUtil::findImplicitLanguageRenderApiType(argName)); - + DeviceType targetLanguageDeviceType = + _toRenderType(RenderApiUtil::findImplicitLanguageRenderApiType(argName)); + if (targetLanguageDeviceType != DeviceType::Default || argName == "glsl") { outOptions.targetLanguageDeviceType = targetLanguageDeviceType; - outOptions.inputLanguageID = (argName == "hlsl" || argName == "glsl" || argName == "cpp" || argName == "cxx" || argName == "c") ? InputLanguageID::Native : InputLanguageID::Slang; + outOptions.inputLanguageID = + (argName == "hlsl" || argName == "glsl" || argName == "cpp" || + argName == "cxx" || argName == "c") + ? InputLanguageID::Native + : InputLanguageID::Slang; continue; } } @@ -266,26 +277,26 @@ static rhi::DeviceType _toRenderType(Slang::RenderApiType apiType) } } - // If a render option isn't set use defaultRenderType + // If a render option isn't set use defaultRenderType outOptions.deviceType = (outOptions.deviceType == DeviceType::Default) ? outOptions.targetLanguageDeviceType : outOptions.deviceType; // first positional argument is source shader path - if(positionalArgs.getCount()) + if (positionalArgs.getCount()) { outOptions.sourcePath = positionalArgs[0].value; positionalArgs.removeAt(0); } // any remaining arguments represent an error - if(positionalArgs.getCount() != 0) + if (positionalArgs.getCount() != 0) { sink.diagnose(positionalArgs[0].loc, RenderTestDiagnostics::unexpectedPositionalArg); return SLANG_FAIL; } - return SLANG_OK; + return SLANG_OK; } -} // renderer_test +} // namespace renderer_test diff --git a/tools/render-test/options.h b/tools/render-test/options.h index bd5e65a1a..2497ce782 100644 --- a/tools/render-test/options.h +++ b/tools/render-test/options.h @@ -7,16 +7,15 @@ #define SLANG_HANDLE_RESULT_FAIL(x) assert(!"failure") #endif -#include "slang-com-helper.h" -#include "../../source/core/slang-writer.h" - -#include "../../source/core/slang-process-util.h" - #include "../../source/compiler-core/slang-command-line-args.h" +#include "../../source/core/slang-process-util.h" +#include "../../source/core/slang-writer.h" +#include "slang-com-helper.h" #include <slang-rhi.h> -namespace renderer_test { +namespace renderer_test +{ using namespace rhi; @@ -50,16 +49,17 @@ struct Options Slang::String appName = "render-test"; Slang::String sourcePath; Slang::String outputPath; - ShaderProgramType shaderType = ShaderProgramType::Graphics; + ShaderProgramType shaderType = ShaderProgramType::Graphics; - /// The renderer type inferred from the target language type. Used if a rendererType is not explicitly set. + /// The renderer type inferred from the target language type. Used if a rendererType is not + /// explicitly set. DeviceType targetLanguageDeviceType = DeviceType::Default; - /// The set render type + /// The set render type DeviceType deviceType = DeviceType::Default; InputLanguageID inputLanguageID = InputLanguageID::Slang; SlangSourceLanguage sourceLanguage = SLANG_SOURCE_LANGUAGE_UNKNOWN; - /// Can be used for overriding the profile + /// Can be used for overriding the profile Slang::String profileName; bool outputUsingType = false; @@ -77,19 +77,23 @@ struct Options Slang::String entryPointName; - Slang::List<Slang::String> renderFeatures; /// Required render features for this test to run + Slang::List<Slang::String> renderFeatures; /// Required render features for this test to run - uint32_t computeDispatchSize[3] = { 1, 1, 1 }; + uint32_t computeDispatchSize[3] = {1, 1, 1}; - Slang::String nvapiExtnSlot; ///< The nvapiRegister to use. + Slang::String nvapiExtnSlot; ///< The nvapiRegister to use. - Slang::DownstreamArgs downstreamArgs; ///< Args to downstream tools. Here it's just slang + Slang::DownstreamArgs downstreamArgs; ///< Args to downstream tools. Here it's just slang bool generateSPIRVDirectly = true; Options() { downstreamArgs.addName("slang"); } - static SlangResult parse(int argc, const char*const* argv, Slang::WriterHelper stdError, Options& outOptions); + static SlangResult parse( + int argc, + const char* const* argv, + Slang::WriterHelper stdError, + Options& outOptions); }; -} // renderer_test +} // namespace renderer_test diff --git a/tools/render-test/png-serialize-util.cpp b/tools/render-test/png-serialize-util.cpp index dc1a9f241..8a649ee87 100644 --- a/tools/render-test/png-serialize-util.cpp +++ b/tools/render-test/png-serialize-util.cpp @@ -3,13 +3,14 @@ #include "png-serialize-util.h" -#include <stdlib.h> #include <stdio.h> +#include <stdlib.h> #define STB_IMAGE_WRITE_IMPLEMENTATION #include "external/stb/stb_image_write.h" -namespace renderer_test { +namespace renderer_test +{ using namespace Slang; /* static */ Slang::Result PngSerializeUtil::write( @@ -24,4 +25,4 @@ using namespace Slang; return stbResult ? SLANG_OK : SLANG_FAIL; } -} // renderer_test +} // namespace renderer_test diff --git a/tools/render-test/png-serialize-util.h b/tools/render-test/png-serialize-util.h index 80eda3729..4eb119b30 100644 --- a/tools/render-test/png-serialize-util.h +++ b/tools/render-test/png-serialize-util.h @@ -3,12 +3,16 @@ #include "core/slang-blob.h" -namespace renderer_test { +namespace renderer_test +{ struct PngSerializeUtil { - static Slang::Result write(const char* filename, ISlangBlob* pixels, uint32_t width, uint32_t height); - + static Slang::Result write( + const char* filename, + ISlangBlob* pixels, + uint32_t width, + uint32_t height); }; -} // renderer_test +} // namespace renderer_test diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp index 7d8f3a8aa..a36121af0 100644 --- a/tools/render-test/render-test-main.cpp +++ b/tools/render-test/render-test-main.cpp @@ -2,35 +2,32 @@ #define _CRT_SECURE_NO_WARNINGS 1 -#include "options.h" -#include <slang-rhi.h> -#include <slang-rhi/shader-cursor.h> -#include <slang-rhi/acceleration-structure-utils.h> -#include "slang-support.h" -#include "png-serialize-util.h" - -#include "shader-renderer-util.h" - +#include "../../source/core/slang-test-tool-util.h" #include "../source/core/slang-io.h" #include "../source/core/slang-string-util.h" - #include "core/slang-token-reader.h" - +#include "options.h" +#include "png-serialize-util.h" #include "shader-input-layout.h" -#include <stdio.h> -#include <stdlib.h> - +#include "shader-renderer-util.h" +#include "slang-support.h" #include "window.h" -#include "../../source/core/slang-test-tool-util.h" +#include <slang-rhi.h> +#include <slang-rhi/acceleration-structure-utils.h> +#include <slang-rhi/shader-cursor.h> +#include <stdio.h> +#include <stdlib.h> #define ENABLE_RENDERDOC_INTEGRATION 0 #if ENABLE_RENDERDOC_INTEGRATION -# include "external/renderdoc_app.h" -# include <windows.h> +#include "external/renderdoc_app.h" + +#include <windows.h> #endif -namespace renderer_test { +namespace renderer_test +{ using Slang::Result; @@ -50,11 +47,10 @@ struct Vertex float uv[2]; }; -static const Vertex kVertexData[] = -{ - { { 0, 0, 0.5 }, {1, 0, 0} , {0, 0} }, - { { 0, 1, 0.5 }, {0, 0, 1} , {1, 0} }, - { { 1, 0, 0.5 }, {0, 1, 0} , {1, 1} }, +static const Vertex kVertexData[] = { + {{0, 0, 0.5}, {1, 0, 0}, {0, 0}}, + {{0, 1, 0.5}, {0, 0, 1}, {1, 0}}, + {{1, 0, 0.5}, {0, 1, 0}, {1, 1}}, }; static const int kVertexCount = SLANG_COUNT_OF(kVertexData); @@ -73,8 +69,8 @@ struct ShaderOutputPlan { struct Item { - ComPtr<IResource> resource; - slang::TypeLayoutReflection* typeLayout = nullptr; + ComPtr<IResource> resource; + slang::TypeLayoutReflection* typeLayout = nullptr; }; List<Item> items; @@ -153,28 +149,32 @@ protected: struct AssignValsFromLayoutContext { - IDevice* device; - slang::ISession* slangSession; - ShaderOutputPlan& outputPlan; - slang::ProgramLayout* slangReflection; + IDevice* device; + slang::ISession* slangSession; + ShaderOutputPlan& outputPlan; + slang::ProgramLayout* slangReflection; IAccelerationStructure* accelerationStructure; AssignValsFromLayoutContext( - IDevice* device, - slang::ISession* slangSession, - ShaderOutputPlan& outputPlan, - slang::ProgramLayout* slangReflection, - IAccelerationStructure* accelerationStructure) + IDevice* device, + slang::ISession* slangSession, + ShaderOutputPlan& outputPlan, + slang::ProgramLayout* slangReflection, + IAccelerationStructure* accelerationStructure) : device(device) , slangSession(slangSession) , outputPlan(outputPlan) , slangReflection(slangReflection) , accelerationStructure(accelerationStructure) - {} + { + } - void maybeAddOutput(ShaderCursor const& dstCursor, ShaderInputLayout::Val* srcVal, IResource* resource) + void maybeAddOutput( + ShaderCursor const& dstCursor, + ShaderInputLayout::Val* srcVal, + IResource* resource) { - if(srcVal->isOutput) + if (srcVal->isOutput) { ShaderOutputPlan::Item item; item.resource = resource; @@ -188,16 +188,14 @@ struct AssignValsFromLayoutContext const size_t bufferSize = srcVal->bufferData.getCount() * sizeof(uint32_t); ShaderCursor dataCursor = dstCursor; - switch(dataCursor.getTypeLayout()->getKind()) + switch (dataCursor.getTypeLayout()->getKind()) { case slang::TypeReflection::Kind::ConstantBuffer: case slang::TypeReflection::Kind::ParameterBlock: dataCursor = dataCursor.getDereferenced(); break; - default: - break; - + default: break; } SLANG_RETURN_ON_FAIL(dataCursor.setData(srcVal->bufferData.getBuffer(), bufferSize)); @@ -208,19 +206,26 @@ struct AssignValsFromLayoutContext { const InputBufferDesc& srcBuffer = srcVal->bufferDesc; auto& bufferData = srcVal->bufferData; - const size_t bufferSize = Math::Max((size_t)bufferData.getCount() * sizeof(uint32_t), (size_t)(srcBuffer.elementCount * srcBuffer.stride)); + const size_t bufferSize = Math::Max( + (size_t)bufferData.getCount() * sizeof(uint32_t), + (size_t)(srcBuffer.elementCount * srcBuffer.stride)); bufferData.reserve(bufferSize / sizeof(uint32_t)); for (size_t i = bufferData.getCount(); i < bufferSize / sizeof(uint32_t); i++) bufferData.add(0); ComPtr<IBuffer> bufferResource; - SLANG_RETURN_ON_FAIL(ShaderRendererUtil::createBuffer(srcBuffer, /*entry.isOutput,*/ bufferSize, bufferData.getBuffer(), device, bufferResource)); + SLANG_RETURN_ON_FAIL(ShaderRendererUtil::createBuffer( + srcBuffer, + /*entry.isOutput,*/ bufferSize, + bufferData.getBuffer(), + device, + bufferResource)); ComPtr<IBuffer> counterResource; const auto explicitCounterCursor = dstCursor.getExplicitCounter(); - if(srcBuffer.counter != ~0u) + if (srcBuffer.counter != ~0u) { - if(explicitCounterCursor.isValid()) + if (explicitCounterCursor.isValid()) { // If this cursor has a full buffer object associated with the // resource, then assign to that. @@ -244,11 +249,10 @@ struct AssignValsFromLayoutContext sizeof(srcBuffer.counter), &srcBuffer.counter, device, - counterResource - )); + counterResource)); } } - else if(explicitCounterCursor.isValid()) + else if (explicitCounterCursor.isValid()) { // If we know we require a counter for this resource but haven't // been given one, error @@ -268,14 +272,19 @@ struct AssignValsFromLayoutContext return SLANG_OK; } - SlangResult assignCombinedTextureSampler(ShaderCursor const& dstCursor, ShaderInputLayout::CombinedTextureSamplerVal* srcVal) + SlangResult assignCombinedTextureSampler( + ShaderCursor const& dstCursor, + ShaderInputLayout::CombinedTextureSamplerVal* srcVal) { auto& textureEntry = srcVal->textureVal; auto& samplerEntry = srcVal->samplerVal; ComPtr<ITexture> texture; SLANG_RETURN_ON_FAIL(ShaderRendererUtil::generateTexture( - textureEntry->textureDesc, ResourceState::ShaderResource, device, texture)); + textureEntry->textureDesc, + ResourceState::ShaderResource, + device, + texture)); auto sampler = _createSampler(device, samplerEntry->samplerDesc); @@ -288,11 +297,15 @@ struct AssignValsFromLayoutContext SlangResult assignTexture(ShaderCursor const& dstCursor, ShaderInputLayout::TextureVal* srcVal) { ComPtr<ITexture> texture; - ResourceState defaultState = srcVal->textureDesc.isRWTexture ? - ResourceState::UnorderedAccess : ResourceState::ShaderResource; + ResourceState defaultState = srcVal->textureDesc.isRWTexture + ? ResourceState::UnorderedAccess + : ResourceState::ShaderResource; SLANG_RETURN_ON_FAIL(ShaderRendererUtil::generateTexture( - srcVal->textureDesc, defaultState, device, texture)); + srcVal->textureDesc, + defaultState, + device, + texture)); dstCursor.setBinding(texture); maybeAddOutput(dstCursor, srcVal, texture); @@ -310,17 +323,19 @@ struct AssignValsFromLayoutContext SlangResult assignAggregate(ShaderCursor const& dstCursor, ShaderInputLayout::AggVal* srcVal) { Index fieldCount = srcVal->fields.getCount(); - for(Index fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex) + for (Index fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex) { auto& field = srcVal->fields[fieldIndex]; - if(field.name.getLength() == 0) + if (field.name.getLength() == 0) { // If no name was given, assume by-indexing matching is requested auto fieldCursor = dstCursor.getElement((GfxIndex)fieldIndex); - if(!fieldCursor.isValid()) + if (!fieldCursor.isValid()) { - StdWriters::getError().print("error: could not find shader parameter at index %d\n", (int)fieldIndex); + StdWriters::getError().print( + "error: could not find shader parameter at index %d\n", + (int)fieldIndex); return SLANG_E_INVALID_ARG; } SLANG_RETURN_ON_FAIL(assign(fieldCursor, field.val)); @@ -328,9 +343,11 @@ struct AssignValsFromLayoutContext else { auto fieldCursor = dstCursor.getPath(field.name.getBuffer()); - if(!fieldCursor.isValid()) + if (!fieldCursor.isValid()) { - StdWriters::getError().print("error: could not find shader parameter matching '%s'\n", field.name.begin()); + StdWriters::getError().print( + "error: could not find shader parameter matching '%s'\n", + field.name.begin()); return SLANG_E_INVALID_ARG; } SLANG_RETURN_ON_FAIL(assign(fieldCursor, field.val)); @@ -343,7 +360,7 @@ struct AssignValsFromLayoutContext { auto typeName = srcVal->typeName; slang::TypeReflection* slangType = nullptr; - if(typeName.getLength() != 0) + if (typeName.getLength() != 0) { // If the input line specified the name of the type // to allocate, then we use it directly. @@ -357,10 +374,9 @@ struct AssignValsFromLayoutContext // value pointed to by `entryCursor`. // auto slangTypeLayout = dstCursor.getTypeLayout(); - switch(slangTypeLayout->getKind()) + switch (slangTypeLayout->getKind()) { - default: - break; + default: break; case slang::TypeReflection::Kind::ConstantBuffer: case slang::TypeReflection::Kind::ParameterBlock: @@ -376,7 +392,11 @@ struct AssignValsFromLayoutContext } ComPtr<IShaderObject> shaderObject; - device->createShaderObject2(slangSession, slangType, ShaderObjectContainerType::None, shaderObject.writeRef()); + device->createShaderObject2( + slangSession, + slangType, + ShaderObjectContainerType::None, + shaderObject.writeRef()); SLANG_RETURN_ON_FAIL(assign(ShaderCursor(shaderObject), srcVal->contentVal)); dstCursor.setObject(shaderObject); @@ -394,7 +414,9 @@ struct AssignValsFromLayoutContext auto slangType = slangReflection->findTypeByName(typeName.getBuffer()); if (!slangType) { - StdWriters::getError().print("error: could not find shader type '%s'\n", typeName.getBuffer()); + StdWriters::getError().print( + "error: could not find shader type '%s'\n", + typeName.getBuffer()); return SLANG_E_INVALID_ARG; } args.add(slang::SpecializationArg::fromType(slangType)); @@ -405,7 +427,7 @@ struct AssignValsFromLayoutContext SlangResult assignArray(ShaderCursor const& dstCursor, ShaderInputLayout::ArrayVal* srcVal) { Index elementCounter = 0; - for(auto elementVal : srcVal->vals) + for (auto elementVal : srcVal->vals) { Index elementIndex = elementCounter++; SLANG_RETURN_ON_FAIL(assign(dstCursor[elementIndex], elementVal)); @@ -424,57 +446,59 @@ struct AssignValsFromLayoutContext SlangResult assign(ShaderCursor const& dstCursor, ShaderInputLayout::ValPtr const& srcVal) { auto& entryCursor = dstCursor; - switch(srcVal->kind) + switch (srcVal->kind) { case ShaderInputType::UniformData: - return assignData(dstCursor, (ShaderInputLayout::DataVal*) srcVal.Ptr()); + return assignData(dstCursor, (ShaderInputLayout::DataVal*)srcVal.Ptr()); case ShaderInputType::Buffer: - return assignBuffer(dstCursor, (ShaderInputLayout::BufferVal*) srcVal.Ptr()); + return assignBuffer(dstCursor, (ShaderInputLayout::BufferVal*)srcVal.Ptr()); case ShaderInputType::CombinedTextureSampler: - return assignCombinedTextureSampler(dstCursor, (ShaderInputLayout::CombinedTextureSamplerVal*) srcVal.Ptr()); + return assignCombinedTextureSampler( + dstCursor, + (ShaderInputLayout::CombinedTextureSamplerVal*)srcVal.Ptr()); case ShaderInputType::Texture: - return assignTexture(dstCursor, (ShaderInputLayout::TextureVal*) srcVal.Ptr()); + return assignTexture(dstCursor, (ShaderInputLayout::TextureVal*)srcVal.Ptr()); case ShaderInputType::Sampler: - return assignSampler(dstCursor, (ShaderInputLayout::SamplerVal*) srcVal.Ptr()); + return assignSampler(dstCursor, (ShaderInputLayout::SamplerVal*)srcVal.Ptr()); case ShaderInputType::Object: - return assignObject(dstCursor, (ShaderInputLayout::ObjectVal*) srcVal.Ptr()); + return assignObject(dstCursor, (ShaderInputLayout::ObjectVal*)srcVal.Ptr()); case ShaderInputType::Specialize: return assignValWithSpecializationArg( - dstCursor, (ShaderInputLayout::SpecializeVal*)srcVal.Ptr()); + dstCursor, + (ShaderInputLayout::SpecializeVal*)srcVal.Ptr()); case ShaderInputType::Aggregate: - return assignAggregate(dstCursor, (ShaderInputLayout::AggVal*) srcVal.Ptr()); + return assignAggregate(dstCursor, (ShaderInputLayout::AggVal*)srcVal.Ptr()); case ShaderInputType::Array: - return assignArray(dstCursor, (ShaderInputLayout::ArrayVal*) srcVal.Ptr()); + return assignArray(dstCursor, (ShaderInputLayout::ArrayVal*)srcVal.Ptr()); case ShaderInputType::AccelerationStructure: return assignAccelerationStructure( - dstCursor, (ShaderInputLayout::AccelerationStructureVal*)srcVal.Ptr()); - default: - assert(!"Unhandled type"); - return SLANG_FAIL; + dstCursor, + (ShaderInputLayout::AccelerationStructureVal*)srcVal.Ptr()); + default: assert(!"Unhandled type"); return SLANG_FAIL; } } }; SlangResult _assignVarsFromLayout( - IDevice* device, - slang::ISession* slangSession, - IShaderObject* shaderObject, - ShaderInputLayout const& layout, - ShaderOutputPlan& ioOutputPlan, - slang::ProgramLayout* slangReflection, - IAccelerationStructure* accelerationStructure) + IDevice* device, + slang::ISession* slangSession, + IShaderObject* shaderObject, + ShaderInputLayout const& layout, + ShaderOutputPlan& ioOutputPlan, + slang::ProgramLayout* slangReflection, + IAccelerationStructure* accelerationStructure) { - AssignValsFromLayoutContext context( - device, slangSession, ioOutputPlan, slangReflection, accelerationStructure); + AssignValsFromLayoutContext + context(device, slangSession, ioOutputPlan, slangReflection, accelerationStructure); ShaderCursor rootCursor = ShaderCursor(shaderObject); return context.assign(rootCursor, layout.rootVal); } @@ -517,8 +541,7 @@ Result RenderTestApp::applyBinding(PipelineType pipelineType, IPassEncoder* enco setProjectionMatrix(rootObject); } break; - default: - throw "unknown pipeline type"; + default: throw "unknown pipeline type"; } return SLANG_OK; } @@ -533,35 +556,40 @@ SlangResult RenderTestApp::initialize( // We begin by compiling the shader file and entry points that specified via the options. // - SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(device->getSlangSession()->getGlobalSession(), options, input, m_compilationOutput)); + SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout( + device->getSlangSession()->getGlobalSession(), + options, + input, + m_compilationOutput)); m_shaderInputLayout = m_compilationOutput.layout; // Once the shaders have been compiled we load them via the underlying API. // ComPtr<ISlangBlob> outDiagnostics; - auto result = device->createShaderProgram(m_compilationOutput.output.desc, m_shaderProgram.writeRef(), outDiagnostics.writeRef()); + auto result = device->createShaderProgram( + m_compilationOutput.output.desc, + m_shaderProgram.writeRef(), + outDiagnostics.writeRef()); // If there was a failure creating a program, we can't continue // Special case SLANG_E_NOT_AVAILABLE error code to make it a failure, - // as it is also used to indicate an attempt setup something failed gracefully (because it couldn't be supported) - // but that's not this. + // as it is also used to indicate an attempt setup something failed gracefully (because it + // couldn't be supported) but that's not this. if (SLANG_FAILED(result)) { result = (result == SLANG_E_NOT_AVAILABLE) ? SLANG_FAIL : result; return result; } - m_device = device; + m_device = device; _initializeRenderPass(); _initializeAccelerationStructure(); { - switch(m_options.shaderType) + switch (m_options.shaderType) { - default: - assert(!"unexpected test shader type"); - return SLANG_FAIL; + default: assert(!"unexpected test shader type"); return SLANG_FAIL; case Options::ShaderProgramType::Compute: { @@ -585,14 +613,17 @@ SlangResult RenderTestApp::initialize( // fixed/known set of attributes. // const InputElementDesc inputElements[] = { - { "A", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position) }, - { "A", 1, Format::R32G32B32_FLOAT, offsetof(Vertex, color) }, - { "A", 2, Format::R32G32_FLOAT, offsetof(Vertex, uv) }, + {"A", 0, Format::R32G32B32_FLOAT, offsetof(Vertex, position)}, + {"A", 1, Format::R32G32B32_FLOAT, offsetof(Vertex, color)}, + {"A", 2, Format::R32G32_FLOAT, offsetof(Vertex, uv)}, }; ComPtr<IInputLayout> inputLayout; SLANG_RETURN_ON_FAIL(device->createInputLayout( - sizeof(Vertex), inputElements, SLANG_COUNT_OF(inputElements), inputLayout.writeRef())); + sizeof(Vertex), + inputElements, + SLANG_COUNT_OF(inputElements), + inputLayout.writeRef())); BufferDesc vertexBufferDesc; vertexBufferDesc.size = kVertexCount * sizeof(Vertex); @@ -600,10 +631,8 @@ SlangResult RenderTestApp::initialize( vertexBufferDesc.usage = BufferUsage::VertexBuffer; vertexBufferDesc.defaultState = ResourceState::VertexBuffer; - SLANG_RETURN_ON_FAIL(device->createBuffer( - vertexBufferDesc, - kVertexData, - m_vertexBuffer.writeRef())); + SLANG_RETURN_ON_FAIL( + device->createBuffer(vertexBufferDesc, kVertexData, m_vertexBuffer.writeRef())); ColorTargetState colorTarget; colorTarget.format = Format::R8G8B8A8_UNORM; @@ -640,7 +669,11 @@ Result RenderTestApp::_initializeShaders( Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input) { - SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(device->getSlangSession()->getGlobalSession(), m_options, input, m_compilationOutput)); + SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout( + device->getSlangSession()->getGlobalSession(), + m_options, + input, + m_compilationOutput)); m_shaderInputLayout = m_compilationOutput.layout; m_shaderProgram = device->createShaderProgram(m_compilationOutput.output.desc); return m_shaderProgram ? SLANG_OK : SLANG_FAIL; @@ -655,7 +688,7 @@ void RenderTestApp::_initializeRenderPass() m_queue = m_device->getQueue(QueueType::Graphics); SLANG_ASSERT(m_queue); - + rhi::TextureDesc depthBufferDesc; depthBufferDesc.type = TextureType::Texture2D; depthBufferDesc.size.width = gWindowWidth; @@ -693,17 +726,15 @@ void RenderTestApp::_initializeAccelerationStructure() vertexBufferDesc.size = kVertexCount * sizeof(Vertex); vertexBufferDesc.usage = BufferUsage::AccelerationStructureBuildInput; vertexBufferDesc.defaultState = ResourceState::AccelerationStructureBuildInput; - ComPtr<IBuffer> vertexBuffer = - m_device->createBuffer(vertexBufferDesc, &kVertexData[0]); + ComPtr<IBuffer> vertexBuffer = m_device->createBuffer(vertexBufferDesc, &kVertexData[0]); BufferDesc transformBufferDesc = {}; transformBufferDesc.size = sizeof(float) * 12; transformBufferDesc.usage = BufferUsage::AccelerationStructureBuildInput; transformBufferDesc.defaultState = ResourceState::AccelerationStructureBuildInput; - float transformData[12] = { - 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f}; - ComPtr<IBuffer> transformBuffer = - m_device->createBuffer(transformBufferDesc, &transformData); + float transformData[12] = + {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f}; + ComPtr<IBuffer> transformBuffer = m_device->createBuffer(transformBufferDesc, &transformData); // Build bottom level acceleration structure. { @@ -750,7 +781,13 @@ void RenderTestApp::_initializeAccelerationStructure() AccelerationStructureQueryDesc compactedSizeQueryDesc = {}; compactedSizeQueryDesc.queryPool = compactedSizeQuery; compactedSizeQueryDesc.queryType = QueryType::AccelerationStructureCompactedSize; - passEncoder->buildAccelerationStructure(buildDesc, draftAS, nullptr, scratchBuffer, 1, &compactedSizeQueryDesc); + passEncoder->buildAccelerationStructure( + buildDesc, + draftAS, + nullptr, + scratchBuffer, + 1, + &compactedSizeQueryDesc); passEncoder->end(); commandBuffer->close(); m_queue->submit(commandBuffer); @@ -760,12 +797,16 @@ void RenderTestApp::_initializeAccelerationStructure() compactedSizeQuery->getResult(0, 1, &compactedSize); AccelerationStructureDesc finalDesc; finalDesc.size = compactedSize; - m_device->createAccelerationStructure(finalDesc, m_bottomLevelAccelerationStructure.writeRef()); + m_device->createAccelerationStructure( + finalDesc, + m_bottomLevelAccelerationStructure.writeRef()); commandBuffer = m_transientHeap->createCommandBuffer(); passEncoder = commandBuffer->beginRayTracingPass(); passEncoder->copyAccelerationStructure( - m_bottomLevelAccelerationStructure, draftAS, AccelerationStructureCopyMode::Compact); + m_bottomLevelAccelerationStructure, + draftAS, + AccelerationStructureCopyMode::Compact); passEncoder->end(); commandBuffer->close(); m_queue->submit(commandBuffer); @@ -776,17 +817,20 @@ void RenderTestApp::_initializeAccelerationStructure() { AccelerationStructureInstanceDescType nativeInstanceDescType = getAccelerationStructureInstanceDescType(m_device); - Size nativeInstanceDescSize = getAccelerationStructureInstanceDescSize(nativeInstanceDescType); + Size nativeInstanceDescSize = + getAccelerationStructureInstanceDescSize(nativeInstanceDescType); List<AccelerationStructureInstanceDescGeneric> genericInstanceDescs; genericInstanceDescs.setCount(1); - genericInstanceDescs[0].accelerationStructure = m_bottomLevelAccelerationStructure->getHandle(); - genericInstanceDescs[0].flags = AccelerationStructureInstanceFlags::TriangleFacingCullDisable; + genericInstanceDescs[0].accelerationStructure = + m_bottomLevelAccelerationStructure->getHandle(); + genericInstanceDescs[0].flags = + AccelerationStructureInstanceFlags::TriangleFacingCullDisable; genericInstanceDescs[0].instanceContributionToHitGroupIndex = 0; genericInstanceDescs[0].instanceID = 0; genericInstanceDescs[0].instanceMask = 0xFF; - float transformMatrix[] = { - 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f}; + float transformMatrix[] = + {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f}; memcpy(&genericInstanceDescs[0].transform[0][0], transformMatrix, sizeof(float) * 12); List<unsigned char> nativeInstanceDescs; @@ -797,8 +841,7 @@ void RenderTestApp::_initializeAccelerationStructure() nativeInstanceDescs.getBuffer(), nativeInstanceDescSize, genericInstanceDescs.getBuffer(), - sizeof(AccelerationStructureInstanceDescGeneric) - ); + sizeof(AccelerationStructureInstanceDescGeneric)); BufferDesc instanceBufferDesc = {}; instanceBufferDesc.size = nativeInstanceDescs.getCount(); @@ -828,11 +871,18 @@ void RenderTestApp::_initializeAccelerationStructure() AccelerationStructureDesc createDesc = {}; createDesc.size = accelerationStructureSizes.accelerationStructureSize; m_device->createAccelerationStructure( - createDesc, m_topLevelAccelerationStructure.writeRef()); + createDesc, + m_topLevelAccelerationStructure.writeRef()); auto commandBuffer = m_transientHeap->createCommandBuffer(); auto passEncoder = commandBuffer->beginRayTracingPass(); - passEncoder->buildAccelerationStructure(buildDesc, m_topLevelAccelerationStructure, nullptr, scratchBuffer, 0, nullptr); + passEncoder->buildAccelerationStructure( + buildDesc, + m_topLevelAccelerationStructure, + nullptr, + scratchBuffer, + 0, + nullptr); passEncoder->end(); commandBuffer->close(); m_queue->submit(commandBuffer); @@ -853,11 +903,10 @@ void RenderTestApp::renderFrameMesh(IRenderPassEncoder* encoder) { auto pipelineType = PipelineType::Graphics; applyBinding(pipelineType, encoder); - encoder->drawMeshTasks( + encoder->drawMeshTasks( m_options.computeDispatchSize[0], m_options.computeDispatchSize[1], - m_options.computeDispatchSize[2] - ); + m_options.computeDispatchSize[2]); } void RenderTestApp::renderFrame(IRenderPassEncoder* encoder) @@ -865,16 +914,16 @@ void RenderTestApp::renderFrame(IRenderPassEncoder* encoder) auto pipelineType = PipelineType::Graphics; applyBinding(pipelineType, encoder); - encoder->setVertexBuffer(0, m_vertexBuffer); + encoder->setVertexBuffer(0, m_vertexBuffer); - encoder->draw(3); + encoder->draw(3); } void RenderTestApp::runCompute(IComputePassEncoder* encoder) { auto pipelineType = PipelineType::Compute; applyBinding(pipelineType, encoder); - encoder->dispatchCompute( + encoder->dispatchCompute( m_options.computeDispatchSize[0], m_options.computeDispatchSize[1], m_options.computeDispatchSize[2]); @@ -890,14 +939,14 @@ Result RenderTestApp::writeBindingOutput(const String& fileName) // Wait until everything is complete m_queue->waitOnHost(); - FILE * f = fopen(fileName.getBuffer(), "wb"); + FILE* f = fopen(fileName.getBuffer(), "wb"); if (!f) { return SLANG_FAIL; } FileWriter writer(f, WriterFlags(0)); - for(auto outputItem : m_outputPlan.items) + for (auto outputItem : m_outputPlan.items) { auto resource = outputItem.resource; IBuffer* buffer = nullptr; @@ -916,7 +965,8 @@ Result RenderTestApp::writeBindingOutput(const String& fileName) return SLANG_FAIL; } const SlangResult res = ShaderInputLayout::writeBinding( - m_options.outputUsingType ? outputItem.typeLayout : nullptr, // TODO: always output using type + m_options.outputUsingType ? outputItem.typeLayout + : nullptr, // TODO: always output using type blob->getBufferPointer(), bufferSize, &writer); @@ -935,7 +985,8 @@ Result RenderTestApp::writeScreen(const String& filename) { size_t rowPitch, pixelSize; ComPtr<ISlangBlob> blob; - SLANG_RETURN_ON_FAIL(m_device->readTexture(m_colorBuffer, blob.writeRef(), &rowPitch, &pixelSize)); + SLANG_RETURN_ON_FAIL( + m_device->readTexture(m_colorBuffer, blob.writeRef(), &rowPitch, &pixelSize)); auto bufferSize = blob->getBufferSize(); uint32_t width = static_cast<uint32_t>(rowPitch / pixelSize); uint32_t height = static_cast<uint32_t>(bufferSize / rowPitch); @@ -972,8 +1023,8 @@ Result RenderTestApp::update() viewport.extentX = (float)gWindowWidth; viewport.extentY = (float)gWindowHeight; passEncoder->setViewportAndScissor(viewport); - if(m_options.shaderType == Options::ShaderProgramType::GraphicsMeshCompute - || m_options.shaderType == Options::ShaderProgramType::GraphicsTaskMeshCompute) + if (m_options.shaderType == Options::ShaderProgramType::GraphicsMeshCompute || + m_options.shaderType == Options::ShaderProgramType::GraphicsTaskMeshCompute) renderFrameMesh(passEncoder); else renderFrame(passEncoder); @@ -1017,8 +1068,9 @@ Result RenderTestApp::update() } #endif - // Note we don't do the same with screen rendering -> as that will do a lot of work, which may swamp any computation - // so can only really profile compute shaders at the moment + // Note we don't do the same with screen rendering -> as that will do a lot of work, + // which may swamp any computation so can only really profile compute shaders at the + // moment const uint64_t endTicks = Process::getClockTick(); @@ -1027,13 +1079,13 @@ Result RenderTestApp::update() if (m_options.outputPath.getLength()) { - if (m_options.shaderType == Options::ShaderProgramType::Compute - || m_options.shaderType == Options::ShaderProgramType::GraphicsCompute - || m_options.shaderType == Options::ShaderProgramType::GraphicsMeshCompute - || m_options.shaderType == Options::ShaderProgramType::GraphicsTaskMeshCompute) + if (m_options.shaderType == Options::ShaderProgramType::Compute || + m_options.shaderType == Options::ShaderProgramType::GraphicsCompute || + m_options.shaderType == Options::ShaderProgramType::GraphicsMeshCompute || + m_options.shaderType == Options::ShaderProgramType::GraphicsTaskMeshCompute) { auto request = m_compilationOutput.output.getRequestForReflection(); - auto slangReflection = (slang::ShaderReflection*) spGetReflection(request); + auto slangReflection = (slang::ShaderReflection*)spGetReflection(request); SLANG_RETURN_ON_FAIL(writeBindingOutput(m_options.outputPath)); } @@ -1053,7 +1105,10 @@ Result RenderTestApp::update() } -static SlangResult _setSessionPrelude(const Options& options, const char* exePath, SlangSession* session) +static SlangResult _setSessionPrelude( + const Options& options, + const char* exePath, + SlangSession* session) { // Let's see if we need to set up special prelude for HLSL if (options.nvapiExtnSlot.getLength()) @@ -1066,15 +1121,19 @@ static SlangResult _setSessionPrelude(const Options& options, const char* exePat String rootPath; SLANG_RETURN_ON_FAIL(TestToolUtil::getRootPath(exePath, rootPath)); String includePath; - SLANG_RETURN_ON_FAIL(TestToolUtil::getIncludePath(rootPath, "external/nvapi/nvHLSLExtns.h", includePath)) + SLANG_RETURN_ON_FAIL( + TestToolUtil::getIncludePath(rootPath, "external/nvapi/nvHLSLExtns.h", includePath)) StringBuilder buf; - // We have to choose a slot that NVAPI will use. + // We have to choose a slot that NVAPI will use. buf << "#define NV_SHADER_EXTN_SLOT " << options.nvapiExtnSlot << "\n"; // Include the NVAPI header buf << "#include "; - StringEscapeUtil::appendQuoted(StringEscapeUtil::getHandler(StringEscapeUtil::Style::Cpp), includePath.getUnownedSlice(), buf); + StringEscapeUtil::appendQuoted( + StringEscapeUtil::getHandler(StringEscapeUtil::Style::Cpp), + includePath.getUnownedSlice(), + buf); buf << "\n\n"; session->setLanguagePrelude(SLANG_SOURCE_LANGUAGE_HLSL, buf.getBuffer()); @@ -1102,7 +1161,11 @@ static void initializeRenderDoc() assert(ret == 1); } } -static void renderDocBeginFrame() { if (rdoc_api) rdoc_api->StartFrameCapture(nullptr, nullptr); } +static void renderDocBeginFrame() +{ + if (rdoc_api) + rdoc_api->StartFrameCapture(nullptr, nullptr); +} static void renderDocEndFrame() { if (rdoc_api) @@ -1110,9 +1173,9 @@ static void renderDocEndFrame() _fgetchar(); } #else -static void initializeRenderDoc(){} -static void renderDocBeginFrame(){} -static void renderDocEndFrame(){} +static void initializeRenderDoc() {} +static void renderDocBeginFrame() {} +static void renderDocEndFrame() {} #endif class StdWritersDebugCallback : public rhi::IDebugCallback @@ -1132,7 +1195,11 @@ public: } }; -static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* session, int argcIn, const char*const* argvIn) +static SlangResult _innerMain( + Slang::StdWriters* stdWriters, + SlangSession* session, + int argcIn, + const char* const* argvIn) { using namespace renderer_test; using namespace Slang; @@ -1143,102 +1210,100 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi Options options; - // Parse command-line options - SLANG_RETURN_ON_FAIL(Options::parse(argcIn, argvIn, StdWriters::getError(), options)); + // Parse command-line options + SLANG_RETURN_ON_FAIL(Options::parse(argcIn, argvIn, StdWriters::getError(), options)); if (options.deviceType == DeviceType::Default) { return SLANG_OK; } ShaderCompilerUtil::Input input; - + input.profile = ""; input.target = SLANG_TARGET_NONE; - SlangSourceLanguage nativeLanguage = SLANG_SOURCE_LANGUAGE_UNKNOWN; - SlangPassThrough slangPassThrough = SLANG_PASS_THROUGH_NONE; + SlangSourceLanguage nativeLanguage = SLANG_SOURCE_LANGUAGE_UNKNOWN; + SlangPassThrough slangPassThrough = SLANG_PASS_THROUGH_NONE; char const* profileName = ""; - switch (options.deviceType) - { - case DeviceType::D3D11: - input.target = SLANG_DXBC; - input.profile = "sm_5_0"; - nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL; - slangPassThrough = SLANG_PASS_THROUGH_FXC; - - break; - - case DeviceType::D3D12: - input.target = SLANG_DXBC; - input.profile = "sm_5_0"; - nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL; - slangPassThrough = SLANG_PASS_THROUGH_FXC; - - if( options.useDXIL ) - { - input.target = SLANG_DXIL; - input.profile = "sm_6_5"; - slangPassThrough = SLANG_PASS_THROUGH_DXC; - } - break; - - case DeviceType::Vulkan: - input.target = SLANG_SPIRV; - input.profile = ""; - nativeLanguage = SLANG_SOURCE_LANGUAGE_GLSL; - slangPassThrough = SLANG_PASS_THROUGH_GLSLANG; - break; - case DeviceType::Metal: - input.target = SLANG_METAL_LIB; - input.profile = ""; - nativeLanguage = SLANG_SOURCE_LANGUAGE_METAL; - slangPassThrough = SLANG_PASS_THROUGH_METAL; - break; - case DeviceType::CPU: - input.target = SLANG_SHADER_HOST_CALLABLE; - input.profile = ""; - nativeLanguage = SLANG_SOURCE_LANGUAGE_CPP; - slangPassThrough = SLANG_PASS_THROUGH_GENERIC_C_CPP; - break; - case DeviceType::CUDA: - input.target = SLANG_PTX; - input.profile = ""; - nativeLanguage = SLANG_SOURCE_LANGUAGE_CUDA; - slangPassThrough = SLANG_PASS_THROUGH_NVRTC; - break; - case DeviceType::WGPU: - input.target = SLANG_WGSL; - input.profile = ""; - nativeLanguage = SLANG_SOURCE_LANGUAGE_WGSL; - slangPassThrough = SLANG_PASS_THROUGH_NONE; - break; + switch (options.deviceType) + { + case DeviceType::D3D11: + input.target = SLANG_DXBC; + input.profile = "sm_5_0"; + nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL; + slangPassThrough = SLANG_PASS_THROUGH_FXC; + + break; + + case DeviceType::D3D12: + input.target = SLANG_DXBC; + input.profile = "sm_5_0"; + nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL; + slangPassThrough = SLANG_PASS_THROUGH_FXC; + + if (options.useDXIL) + { + input.target = SLANG_DXIL; + input.profile = "sm_6_5"; + slangPassThrough = SLANG_PASS_THROUGH_DXC; + } + break; + + case DeviceType::Vulkan: + input.target = SLANG_SPIRV; + input.profile = ""; + nativeLanguage = SLANG_SOURCE_LANGUAGE_GLSL; + slangPassThrough = SLANG_PASS_THROUGH_GLSLANG; + break; + case DeviceType::Metal: + input.target = SLANG_METAL_LIB; + input.profile = ""; + nativeLanguage = SLANG_SOURCE_LANGUAGE_METAL; + slangPassThrough = SLANG_PASS_THROUGH_METAL; + break; + case DeviceType::CPU: + input.target = SLANG_SHADER_HOST_CALLABLE; + input.profile = ""; + nativeLanguage = SLANG_SOURCE_LANGUAGE_CPP; + slangPassThrough = SLANG_PASS_THROUGH_GENERIC_C_CPP; + break; + case DeviceType::CUDA: + input.target = SLANG_PTX; + input.profile = ""; + nativeLanguage = SLANG_SOURCE_LANGUAGE_CUDA; + slangPassThrough = SLANG_PASS_THROUGH_NVRTC; + break; + case DeviceType::WGPU: + input.target = SLANG_WGSL; + input.profile = ""; + nativeLanguage = SLANG_SOURCE_LANGUAGE_WGSL; + slangPassThrough = SLANG_PASS_THROUGH_NONE; + break; - default: - fprintf(stderr, "error: unexpected\n"); - return SLANG_FAIL; - } + default: fprintf(stderr, "error: unexpected\n"); return SLANG_FAIL; + } switch (options.inputLanguageID) { - case Options::InputLanguageID::Slang: - input.sourceLanguage = SLANG_SOURCE_LANGUAGE_SLANG; - input.passThrough = SLANG_PASS_THROUGH_NONE; - break; + case Options::InputLanguageID::Slang: + input.sourceLanguage = SLANG_SOURCE_LANGUAGE_SLANG; + input.passThrough = SLANG_PASS_THROUGH_NONE; + break; - case Options::InputLanguageID::Native: - input.sourceLanguage = nativeLanguage; - input.passThrough = slangPassThrough; - break; + case Options::InputLanguageID::Native: + input.sourceLanguage = nativeLanguage; + input.passThrough = slangPassThrough; + break; - default: - break; + default: break; } if (options.sourceLanguage != SLANG_SOURCE_LANGUAGE_UNKNOWN) { input.sourceLanguage = options.sourceLanguage; - if (input.sourceLanguage == SLANG_SOURCE_LANGUAGE_C || input.sourceLanguage == SLANG_SOURCE_LANGUAGE_CPP) + if (input.sourceLanguage == SLANG_SOURCE_LANGUAGE_C || + input.sourceLanguage == SLANG_SOURCE_LANGUAGE_CPP) { input.passThrough = SLANG_PASS_THROUGH_GENERIC_C_CPP; } @@ -1251,28 +1316,28 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi input.profile = options.profileName.getLength() ? options.profileName : input.profile; StringBuilder rendererName; - auto info = - rendererName << "[" << getRHI()->getDeviceTypeName(options.deviceType) << "] "; + auto info = rendererName << "[" << getRHI()->getDeviceTypeName(options.deviceType) << "] "; if (options.onlyStartup) { switch (options.deviceType) { - case DeviceType::CUDA: + case DeviceType::CUDA: { #if RENDER_TEST_CUDA - if(SLANG_FAILED(spSessionCheckPassThroughSupport(session, SLANG_PASS_THROUGH_NVRTC))) + if (SLANG_FAILED( + spSessionCheckPassThroughSupport(session, SLANG_PASS_THROUGH_NVRTC))) return SLANG_FAIL; #else return SLANG_FAIL; #endif } - case DeviceType::CPU: + case DeviceType::CPU: { // As long as we have CPU, then this should work return spSessionCheckPassThroughSupport(session, SLANG_PASS_THROUGH_GENERIC_C_CPP); } - default: break; + default: break; } } @@ -1284,14 +1349,15 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi // Slang::Int value; UnownedStringSlice slice = options.nvapiExtnSlot.getUnownedSlice(); - UnownedStringSlice indexText(slice.begin() + 1 , slice.end()); + UnownedStringSlice indexText(slice.begin() + 1, slice.end()); if (SLANG_SUCCEEDED(StringUtil::parseInt(indexText, value))) { nvapiExtnSlot = Index(value); } } - // If can't set up a necessary prelude make not available (which will lead to the test being ignored) + // If can't set up a necessary prelude make not available (which will lead to the test being + // ignored) if (SLANG_FAILED(_setSessionPrelude(options, argvIn[0], session))) { return SLANG_E_NOT_AVAILABLE; @@ -1333,7 +1399,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi } } } - + desc.nvapiExtnSlot = int(nvapiExtnSlot); desc.slang.slangGlobalSession = session; desc.slang.targetProfile = options.profileName.getBuffer(); @@ -1341,13 +1407,16 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi SlangResult res = getRHI()->createDevice(desc, device.writeRef()); if (SLANG_FAILED(res)) { - // We need to be careful here about SLANG_E_NOT_AVAILABLE. This return value means that the renderer couldn't - // be created because it required *features* that were *not available*. It does not mean the renderer in general couldn't - // be constructed. + // We need to be careful here about SLANG_E_NOT_AVAILABLE. This return value means + // that the renderer couldn't be created because it required *features* that were + // *not available*. It does not mean the renderer in general couldn't be + // constructed. // - // Returning SLANG_E_NOT_AVAILABLE will lead to the test infrastructure ignoring this test. + // Returning SLANG_E_NOT_AVAILABLE will lead to the test infrastructure ignoring + // this test. // - // We also don't want to output the 'Unable to create renderer' error, as this isn't an error. + // We also don't want to output the 'Unable to create renderer' error, as this isn't + // an error. if (res == SLANG_E_NOT_AVAILABLE) { return res; @@ -1372,25 +1441,29 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi } } } - + // If the only test is we can startup, then we are done if (options.onlyStartup) { return SLANG_OK; } - { + { RenderTestApp app; renderDocBeginFrame(); SLANG_RETURN_ON_FAIL(app.initialize(session, device, options, input)); app.update(); renderDocEndFrame(); app.finalize(); - } + } return SLANG_OK; } -SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSession* sharedSession, int inArgc, const char*const* inArgv) +SLANG_TEST_TOOL_API SlangResult innerMain( + Slang::StdWriters* stdWriters, + SlangSession* sharedSession, + int inArgc, + const char* const* inArgv) { using namespace Slang; @@ -1399,10 +1472,12 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe // The sharedSession always has a pre-loaded core module. // This differed test checks if the command line has an option to setup the core module. - // If so we *don't* use the sharedSession, and create a new session without the core module just for this compilation. + // If so we *don't* use the sharedSession, and create a new session without the core module just + // for this compilation. if (TestToolUtil::hasDeferredCoreModule(Index(inArgc - 1), inArgv + 1)) { - SLANG_RETURN_ON_FAIL(slang_createGlobalSessionWithoutCoreModule(SLANG_API_VERSION, session.writeRef())); + SLANG_RETURN_ON_FAIL( + slang_createGlobalSessionWithoutCoreModule(SLANG_API_VERSION, session.writeRef())); } SlangResult res = SLANG_FAIL; @@ -1424,19 +1499,18 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe return res; } -int main(int argc, char** argv) +int main(int argc, char** argv) { using namespace Slang; SlangSession* session = spCreateSession(nullptr); TestToolUtil::setSessionDefaultPreludeFromExePath(argv[0], session); - + auto stdWriters = StdWriters::initDefaultSingleton(); - + SlangResult res = innerMain(stdWriters, session, argc, argv); spDestroySession(session); slang::shutdown(); - return (int)TestToolUtil::getReturnCode(res); + return (int)TestToolUtil::getReturnCode(res); } - diff --git a/tools/render-test/shader-input-layout.cpp b/tools/render-test/shader-input-layout.cpp index 013e86c37..e2cf25809 100644 --- a/tools/render-test/shader-input-layout.cpp +++ b/tools/render-test/shader-input-layout.cpp @@ -2,6 +2,7 @@ #define _CRT_SECURE_NO_WARNINGS 1 #include "shader-input-layout.h" + #include "core/slang-token-reader.h" #include "core/slang-type-text-util.h" @@ -9,7 +10,7 @@ namespace renderer_test { - using namespace Slang; +using namespace Slang; // clang-format off #define SLANG_SCALAR_TYPES(x) \ @@ -19,1177 +20,1229 @@ namespace renderer_test // clang-format on - Format _getFormatFromName(const UnownedStringSlice& slice) +Format _getFormatFromName(const UnownedStringSlice& slice) +{ + for (int i = 0; i < int(Format::_Count); ++i) { - for (int i = 0; i < int(Format::_Count); ++i) + const FormatInfo& info = getFormatInfo(Format(i)); + if (slice == info.name) { - const FormatInfo& info = getFormatInfo(Format(i)); - if (slice == info.name) - { - return Format(i); - } + return Format(i); } - return Format::Unknown; } + return Format::Unknown; +} - struct TypeInfo - { - UnownedStringSlice name; - SlangScalarType type; - }; +struct TypeInfo +{ + UnownedStringSlice name; + SlangScalarType type; +}; -#define SLANG_SCALAR_TYPE_INFO(name, value) { UnownedStringSlice::fromLiteral(name), SLANG_SCALAR_TYPE_##value }, - static const TypeInfo g_scalarTypeInfos[] = - { - SLANG_SCALAR_TYPES(SLANG_SCALAR_TYPE_INFO) - }; +#define SLANG_SCALAR_TYPE_INFO(name, value) \ + {UnownedStringSlice::fromLiteral(name), SLANG_SCALAR_TYPE_##value}, +static const TypeInfo g_scalarTypeInfos[] = {SLANG_SCALAR_TYPES(SLANG_SCALAR_TYPE_INFO)}; #undef SLANG_SCALAR_TYPES #undef SLANG_SCALAR_TYPE_INFO - static SlangScalarType _getScalarType(const UnownedStringSlice& slice) +static SlangScalarType _getScalarType(const UnownedStringSlice& slice) +{ + for (const auto& info : g_scalarTypeInfos) { - for (const auto& info : g_scalarTypeInfos) + if (info.name == slice) { - if (info.name == slice) - { - return info.type; - } + return info.type; } - return SLANG_SCALAR_TYPE_NONE; } + return SLANG_SCALAR_TYPE_NONE; +} - void ShaderInputLayout::AggVal::addField(ShaderInputLayout::Field const& field) - { - fields.add(field); - } +void ShaderInputLayout::AggVal::addField(ShaderInputLayout::Field const& field) +{ + fields.add(field); +} - void ShaderInputLayout::ArrayVal::addField(ShaderInputLayout::Field const& field) +void ShaderInputLayout::ArrayVal::addField(ShaderInputLayout::Field const& field) +{ + vals.add(field.val); +} + +class ShaderInputLayoutFormatException : public Exception +{ +public: + ShaderInputLayoutFormatException(String message) + : Exception(message) { - vals.add(field.val); } +}; - class ShaderInputLayoutFormatException : public Exception - { - public: - ShaderInputLayoutFormatException(String message) - : Exception(message) - {} - }; +struct ShaderInputLayoutParser +{ + ShaderInputLayout* layout; + RandomGenerator* rand; - struct ShaderInputLayoutParser + ShaderInputLayoutParser(ShaderInputLayout* layout, RandomGenerator* rand) + : layout(layout), rand(rand) { - ShaderInputLayout* layout; - RandomGenerator* rand; - - ShaderInputLayoutParser(ShaderInputLayout* layout, RandomGenerator* rand) - : layout(layout) - , rand(rand) - {} + } - RefPtr<ShaderInputLayout::ParentVal> parentVal; - List<RefPtr<ShaderInputLayout::ParentVal>> parentValStack; + RefPtr<ShaderInputLayout::ParentVal> parentVal; + List<RefPtr<ShaderInputLayout::ParentVal>> parentValStack; - SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::TextureVal* val) + SlangResult parseOption( + Misc::TokenReader& parser, + String const& word, + ShaderInputLayout::TextureVal* val) + { + if (word == "depth") { - if (word == "depth") - { - val->textureDesc.isDepthTexture = true; - } - else if (word == "arrayLength") - { - parser.Read("="); - val->textureDesc.arrayLength = parser.ReadInt(); - } - else if (word == "size") - { - parser.Read("="); - auto size = parser.ReadInt(); - val->textureDesc.size = size; - } - else if (word == "content") - { - parser.Read("="); - auto contentWord = parser.ReadWord(); - if (contentWord == "zero") - val->textureDesc.content = InputTextureContent::Zero; - else if (contentWord == "one") - val->textureDesc.content = InputTextureContent::One; - else if (contentWord == "chessboard") - val->textureDesc.content = InputTextureContent::ChessBoard; - else - val->textureDesc.content = InputTextureContent::Gradient; - } - else if (word == "sampleCount") - { - parser.Read("="); - auto contentWord = parser.ReadWord(); - if(contentWord == "one") - val->textureDesc.sampleCount = InputTextureSampleCount::One; - else if(contentWord == "two") - val->textureDesc.sampleCount = InputTextureSampleCount::Two; - else if(contentWord == "four") - val->textureDesc.sampleCount = InputTextureSampleCount::Four; - else if(contentWord == "eight") - val->textureDesc.sampleCount = InputTextureSampleCount::Eight; - else if(contentWord == "sixteen") - val->textureDesc.sampleCount = InputTextureSampleCount::Sixteen; - else if(contentWord == "thirtyTwo") - val->textureDesc.sampleCount = InputTextureSampleCount::ThirtyTwo; - else if(contentWord == "sixtyFour") - val->textureDesc.sampleCount = InputTextureSampleCount::SixtyFour; - } - else if(word == "mipMaps") - { - parser.Read("="); - val->textureDesc.mipMapCount = int(parser.ReadInt()); - } - else if(word == "format") - { - val->textureDesc.format = parseFormatOption(parser); - - if (val->textureDesc.format == Format::Unknown) - { - return SLANG_FAIL; - } - } - else - { - return SLANG_FAIL; - } - return SLANG_OK; + val->textureDesc.isDepthTexture = true; } - - SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::SamplerVal* val) + else if (word == "arrayLength") { - if (word == "depthCompare") - { - val->samplerDesc.isCompareSampler = true; - } + parser.Read("="); + val->textureDesc.arrayLength = parser.ReadInt(); + } + else if (word == "size") + { + parser.Read("="); + auto size = parser.ReadInt(); + val->textureDesc.size = size; + } + else if (word == "content") + { + parser.Read("="); + auto contentWord = parser.ReadWord(); + if (contentWord == "zero") + val->textureDesc.content = InputTextureContent::Zero; + else if (contentWord == "one") + val->textureDesc.content = InputTextureContent::One; + else if (contentWord == "chessboard") + val->textureDesc.content = InputTextureContent::ChessBoard; else + val->textureDesc.content = InputTextureContent::Gradient; + } + else if (word == "sampleCount") + { + parser.Read("="); + auto contentWord = parser.ReadWord(); + if (contentWord == "one") + val->textureDesc.sampleCount = InputTextureSampleCount::One; + else if (contentWord == "two") + val->textureDesc.sampleCount = InputTextureSampleCount::Two; + else if (contentWord == "four") + val->textureDesc.sampleCount = InputTextureSampleCount::Four; + else if (contentWord == "eight") + val->textureDesc.sampleCount = InputTextureSampleCount::Eight; + else if (contentWord == "sixteen") + val->textureDesc.sampleCount = InputTextureSampleCount::Sixteen; + else if (contentWord == "thirtyTwo") + val->textureDesc.sampleCount = InputTextureSampleCount::ThirtyTwo; + else if (contentWord == "sixtyFour") + val->textureDesc.sampleCount = InputTextureSampleCount::SixtyFour; + } + else if (word == "mipMaps") + { + parser.Read("="); + val->textureDesc.mipMapCount = int(parser.ReadInt()); + } + else if (word == "format") + { + val->textureDesc.format = parseFormatOption(parser); + + if (val->textureDesc.format == Format::Unknown) { return SLANG_FAIL; } - return SLANG_OK; } + else + { + return SLANG_FAIL; + } + return SLANG_OK; + } - - SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::CombinedTextureSamplerVal* val) + SlangResult parseOption( + Misc::TokenReader& parser, + String const& word, + ShaderInputLayout::SamplerVal* val) + { + if (word == "depthCompare") + { + val->samplerDesc.isCompareSampler = true; + } + else { - auto result = parseOption(parser, word, val->textureVal); - if(SLANG_SUCCEEDED(result)) return result; + return SLANG_FAIL; + } + return SLANG_OK; + } + - result = parseOption(parser, word, val->samplerVal); + SlangResult parseOption( + Misc::TokenReader& parser, + String const& word, + ShaderInputLayout::CombinedTextureSamplerVal* val) + { + auto result = parseOption(parser, word, val->textureVal); + if (SLANG_SUCCEEDED(result)) return result; - } - SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::DataValBase* val) + result = parseOption(parser, word, val->samplerVal); + return result; + } + + SlangResult parseOption( + Misc::TokenReader& parser, + String const& word, + ShaderInputLayout::DataValBase* val) + { + if (word == "data") { - if (word == "data") - { - parser.Read("="); + parser.Read("="); - parser.Read("["); - uint32_t offset = 0; - while (!parser.IsEnd() && !parser.LookAhead("]")) + parser.Read("["); + uint32_t offset = 0; + while (!parser.IsEnd() && !parser.LookAhead("]")) + { + bool negate = false; + if (parser.NextToken().Type == Misc::TokenType::OpSub) { - bool negate = false; - if(parser.NextToken().Type == Misc::TokenType::OpSub) - { - parser.ReadToken(); - negate = true; - } + parser.ReadToken(); + negate = true; + } - if (parser.NextToken().Type == Misc::TokenType::IntLiteral) - { - uint32_t value = parser.ReadUInt(); - if(negate) value = uint32_t(-int32_t(value)); - val->bufferData.add(value); - } - else - { - auto floatNum = parser.ReadFloat(); - if(negate) floatNum = -floatNum; - val->bufferData.add(*(unsigned int*)&floatNum); - } - offset += 4; + if (parser.NextToken().Type == Misc::TokenType::IntLiteral) + { + uint32_t value = parser.ReadUInt(); + if (negate) + value = uint32_t(-int32_t(value)); + val->bufferData.add(value); } - parser.Read("]"); - } - else - { - return SLANG_FAIL; + else + { + auto floatNum = parser.ReadFloat(); + if (negate) + floatNum = -floatNum; + val->bufferData.add(*(unsigned int*)&floatNum); + } + offset += 4; } - return SLANG_OK; + parser.Read("]"); } + else + { + return SLANG_FAIL; + } + return SLANG_OK; + } - SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::BufferVal* val) + SlangResult parseOption( + Misc::TokenReader& parser, + String const& word, + ShaderInputLayout::BufferVal* val) + { + if (word == "stride") { - if (word == "stride") - { - parser.Read("="); - val->bufferDesc.stride = parser.ReadInt(); - } - else if (word == "count") - { - parser.Read("="); - val->bufferDesc.elementCount = parser.ReadInt(); - } - else if (word == "counter") - { - parser.Read("="); - val->bufferDesc.counter = parser.ReadInt(); - } - else if (word == "random") - { - parser.Read("("); - // Read the type - String type = parser.ReadWord(); - SlangScalarType scalarType = _getScalarType(type.getUnownedSlice()); - if (scalarType == SLANG_SCALAR_TYPE_NONE) + parser.Read("="); + val->bufferDesc.stride = parser.ReadInt(); + } + else if (word == "count") + { + parser.Read("="); + val->bufferDesc.elementCount = parser.ReadInt(); + } + else if (word == "counter") + { + parser.Read("="); + val->bufferDesc.counter = parser.ReadInt(); + } + else if (word == "random") + { + parser.Read("("); + // Read the type + String type = parser.ReadWord(); + SlangScalarType scalarType = _getScalarType(type.getUnownedSlice()); + if (scalarType == SLANG_SCALAR_TYPE_NONE) + { + StringBuilder scalarTypeNames; + for (const auto& info : g_scalarTypeInfos) { - StringBuilder scalarTypeNames; - for (const auto& info : g_scalarTypeInfos) + if (scalarTypeNames.getLength() != 0) { - if (scalarTypeNames.getLength() != 0) - { - scalarTypeNames << ", "; - } - scalarTypeNames << info.name; + scalarTypeNames << ", "; } - - throw ShaderInputLayoutFormatException(StringBuilder() << "Expecting " << scalarTypeNames << " " << parser.NextToken().Position.Line); + scalarTypeNames << info.name; } - parser.Read(","); - const int size = int(parser.ReadUInt()); + throw ShaderInputLayoutFormatException( + StringBuilder() + << "Expecting " << scalarTypeNames << " " << parser.NextToken().Position.Line); + } + + parser.Read(","); + const int size = int(parser.ReadUInt()); - switch (scalarType) + switch (scalarType) + { + case SLANG_SCALAR_TYPE_INT32: { - case SLANG_SCALAR_TYPE_INT32: - { - bool hasRange = false; + bool hasRange = false; + + int32_t minValue = -0x7fffffff - 1; + int32_t maxValue = 0x7fffffff; - int32_t minValue = -0x7fffffff - 1; - int32_t maxValue = 0x7fffffff; + if (parser.LookAhead(",")) + { + hasRange = true; + parser.ReadToken(); + minValue = parser.ReadInt(); if (parser.LookAhead(",")) { - hasRange = true; parser.ReadToken(); - minValue = parser.ReadInt(); - - if (parser.LookAhead(",")) - { - parser.ReadToken(); - maxValue = parser.ReadInt(); - } + maxValue = parser.ReadInt(); } - SLANG_ASSERT(minValue <= maxValue); - maxValue = (maxValue >= minValue) ? maxValue : minValue; + } + SLANG_ASSERT(minValue <= maxValue); + maxValue = (maxValue >= minValue) ? maxValue : minValue; - // Generate the data - val->bufferData.setCount(size); + // Generate the data + val->bufferData.setCount(size); - int32_t* dst = (int32_t*)val->bufferData.getBuffer(); - for (int i = 0; i < size; ++i) - { - dst[i] = hasRange ? rand->nextInt32InRange(minValue, maxValue) : rand->nextInt32(); - } - break; + int32_t* dst = (int32_t*)val->bufferData.getBuffer(); + for (int i = 0; i < size; ++i) + { + dst[i] = hasRange ? rand->nextInt32InRange(minValue, maxValue) + : rand->nextInt32(); } - case SLANG_SCALAR_TYPE_UINT32: + break; + } + case SLANG_SCALAR_TYPE_UINT32: + { + bool hasRange = false; + uint32_t minValue = 0; + uint32_t maxValue = 0xffffffff; + + if (parser.LookAhead(",")) { - bool hasRange = false; - uint32_t minValue = 0; - uint32_t maxValue = 0xffffffff; + parser.ReadToken(); + minValue = parser.ReadUInt(); + + hasRange = true; if (parser.LookAhead(",")) { parser.ReadToken(); - minValue = parser.ReadUInt(); - - hasRange = true; - - if (parser.LookAhead(",")) - { - parser.ReadToken(); - maxValue = parser.ReadUInt(); - } + maxValue = parser.ReadUInt(); } + } - SLANG_ASSERT(minValue <= maxValue); - maxValue = (maxValue >= minValue) ? maxValue : minValue; + SLANG_ASSERT(minValue <= maxValue); + maxValue = (maxValue >= minValue) ? maxValue : minValue; - // Generate the data - val->bufferData.setCount(size); + // Generate the data + val->bufferData.setCount(size); - uint32_t* dst = (uint32_t*)val->bufferData.getBuffer(); - for (int i = 0; i < size; ++i) - { - dst[i] = hasRange ? rand->nextUInt32InRange(minValue, maxValue) : rand->nextUInt32(); - } - - break; + uint32_t* dst = (uint32_t*)val->bufferData.getBuffer(); + for (int i = 0; i < size; ++i) + { + dst[i] = hasRange ? rand->nextUInt32InRange(minValue, maxValue) + : rand->nextUInt32(); } - case SLANG_SCALAR_TYPE_FLOAT32: + + break; + } + case SLANG_SCALAR_TYPE_FLOAT32: + { + float minValue = -1.0f; + float maxValue = 1.0f; + + if (parser.LookAhead(",")) { - float minValue = -1.0f; - float maxValue = 1.0f; - + parser.ReadToken(); + minValue = parser.ReadFloat(); + if (parser.LookAhead(",")) { parser.ReadToken(); - minValue = parser.ReadFloat(); - - if (parser.LookAhead(",")) - { - parser.ReadToken(); - maxValue = parser.ReadFloat(); - } + maxValue = parser.ReadFloat(); } + } - SLANG_ASSERT(minValue <= maxValue); - maxValue = (maxValue >= minValue) ? maxValue : minValue; + SLANG_ASSERT(minValue <= maxValue); + maxValue = (maxValue >= minValue) ? maxValue : minValue; - // Generate the data - val->bufferData.setCount(size); + // Generate the data + val->bufferData.setCount(size); - float* dst = (float*)val->bufferData.getBuffer(); - for (int i = 0; i < size; ++i) - { - dst[i] = (rand->nextUnitFloat32() * (maxValue - minValue)) + minValue; - } - break; + float* dst = (float*)val->bufferData.getBuffer(); + for (int i = 0; i < size; ++i) + { + dst[i] = (rand->nextUnitFloat32() * (maxValue - minValue)) + minValue; } + break; } + } - // Read the range + // Read the range - parser.Read(")"); - } - else if(word == "format") - { - val->bufferDesc.format = parseFormatOption(parser); - } - else - { - return parseOption(parser, word, static_cast<ShaderInputLayout::DataValBase*>(val)); - } - return SLANG_OK; + parser.Read(")"); } - - SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::ObjectVal* val) + else if (word == "format") { - if( word == "type" ) - { - parser.Read("="); - val->typeName = parser.ReadWord(); - } - else - { - return SLANG_FAIL; - } - return SLANG_OK; + val->bufferDesc.format = parseFormatOption(parser); + } + else + { + return parseOption(parser, word, static_cast<ShaderInputLayout::DataValBase*>(val)); } + return SLANG_OK; + } - Format parseFormatOption(Misc::TokenReader& parser) + SlangResult parseOption( + Misc::TokenReader& parser, + String const& word, + ShaderInputLayout::ObjectVal* val) + { + if (word == "type") { parser.Read("="); - auto formatWord = parser.ReadWord(); - - return _getFormatFromName(formatWord.getUnownedSlice()); + val->typeName = parser.ReadWord(); } + else + { + return SLANG_FAIL; + } + return SLANG_OK; + } - template<typename T> - void maybeParseOptions(Misc::TokenReader& parser, T* val) + Format parseFormatOption(Misc::TokenReader& parser) + { + parser.Read("="); + auto formatWord = parser.ReadWord(); + + return _getFormatFromName(formatWord.getUnownedSlice()); + } + + template<typename T> + void maybeParseOptions(Misc::TokenReader& parser, T* val) + { + // parse options + if (parser.LookAhead("(")) { - // parse options - if (parser.LookAhead("(")) + parser.Read("("); + while (!parser.IsEnd() && !parser.LookAhead(")")) { - parser.Read("("); - while (!parser.IsEnd() && !parser.LookAhead(")")) + auto word = parser.ReadWord(); + if (SLANG_FAILED(parseOption(parser, word, val))) { - auto word = parser.ReadWord(); - if( SLANG_FAILED(parseOption(parser, word, val)) ) - { - throw ShaderInputLayoutFormatException(String("Unsupported option '") + word + String("' at line ") + String(parser.NextToken().Position.Line)); - } - - if (parser.LookAhead(",")) - parser.Read(","); - else - break; + throw ShaderInputLayoutFormatException( + String("Unsupported option '") + word + String("' at line ") + + String(parser.NextToken().Position.Line)); } - parser.Read(")"); + + if (parser.LookAhead(",")) + parser.Read(","); + else + break; } + parser.Read(")"); } + } - RefPtr<ShaderInputLayout::Val> parseNumericValExpr(Misc::TokenReader& parser, bool negate = false) + RefPtr<ShaderInputLayout::Val> parseNumericValExpr( + Misc::TokenReader& parser, + bool negate = false) + { + switch (parser.NextToken().Type) { - switch(parser.NextToken().Type) + case Misc::TokenType::IntLiteral: { - case Misc::TokenType::IntLiteral: - { - RefPtr<ShaderInputLayout::DataVal> val = new ShaderInputLayout::DataVal; - - uint32_t value = parser.ReadUInt(); - if(negate) value = uint32_t(-int32_t(value)); - val->bufferData.add(value); + RefPtr<ShaderInputLayout::DataVal> val = new ShaderInputLayout::DataVal; - return val; - } - break; + uint32_t value = parser.ReadUInt(); + if (negate) + value = uint32_t(-int32_t(value)); + val->bufferData.add(value); - case Misc::TokenType::DoubleLiteral: - { - RefPtr<ShaderInputLayout::DataVal> val = new ShaderInputLayout::DataVal; + return val; + } + break; - float floatValue = parser.ReadFloat(); - if(negate) floatValue = -floatValue; + case Misc::TokenType::DoubleLiteral: + { + RefPtr<ShaderInputLayout::DataVal> val = new ShaderInputLayout::DataVal; - uint32_t value = 0; - memcpy(&value, &floatValue, sizeof(floatValue)); - val->bufferData.add(value); + float floatValue = parser.ReadFloat(); + if (negate) + floatValue = -floatValue; - return val; - } - break; + uint32_t value = 0; + memcpy(&value, &floatValue, sizeof(floatValue)); + val->bufferData.add(value); - default: - throw ShaderInputLayoutFormatException(String("Expected a numeric literal but found '") + parser.NextToken().Content + String("' at line") + String(parser.NextToken().Position.Line)); + return val; } + break; + + default: + throw ShaderInputLayoutFormatException( + String("Expected a numeric literal but found '") + parser.NextToken().Content + + String("' at line") + String(parser.NextToken().Position.Line)); } + } - String parseTypeName(Misc::TokenReader& parser) + String parseTypeName(Misc::TokenReader& parser) + { + String typeName = parser.ReadWord(); + if (parser.AdvanceIf("<")) { - String typeName = parser.ReadWord(); - if (parser.AdvanceIf("<")) + StringBuilder sb; + sb << typeName << "<"; + for (;;) { - StringBuilder sb; - sb << typeName << "<"; - for (;;) - { - if (parser.LookAhead(Misc::TokenType::IntLiteral)) - sb << parser.ReadInt(); - else - sb << parseTypeName(parser); - if (!parser.AdvanceIf(",")) - break; - sb << ","; - } - sb << ">"; - parser.Read(">"); - return sb.produceString(); + if (parser.LookAhead(Misc::TokenType::IntLiteral)) + sb << parser.ReadInt(); + else + sb << parseTypeName(parser); + if (!parser.AdvanceIf(",")) + break; + sb << ","; } - return typeName; + sb << ">"; + parser.Read(">"); + return sb.produceString(); } + return typeName; + } - RefPtr<ShaderInputLayout::Val> parseValExpr(Misc::TokenReader& parser) - { - typedef Misc::TokenType TokenType; + RefPtr<ShaderInputLayout::Val> parseValExpr(Misc::TokenReader& parser) + { + typedef Misc::TokenType TokenType; - switch(parser.NextToken().Type) + switch (parser.NextToken().Type) + { + case TokenType::OpSub: { - case TokenType::OpSub: - { - parser.ReadToken(); - return parseNumericValExpr(parser, true); - } - break; - - case TokenType::IntLiteral: - case TokenType::DoubleLiteral: - return parseNumericValExpr(parser); - - case TokenType::LBrace: - { - // aggregate - parser.ReadToken(); - RefPtr<ShaderInputLayout::AggVal> val = new ShaderInputLayout::AggVal; - - while( !parser.IsEnd() && !parser.LookAhead(TokenType::RBrace) ) - { - ShaderInputLayout::Field field; - - if( parser.LookAhead(TokenType::Identifier) && parser.NextToken(1).Type == TokenType::Colon ) - { - field.name = parser.ReadWord(); - parser.Read(TokenType::Colon); - } - - field.val = parseValExpr(parser); - - val->fields.add(field); - - if(parser.LookAhead(TokenType::RBrace)) - break; - - parser.Read(TokenType::Comma); - } - parser.Read(TokenType::RBrace); + parser.ReadToken(); + return parseNumericValExpr(parser, true); + } + break; + case TokenType::IntLiteral: + case TokenType::DoubleLiteral: return parseNumericValExpr(parser); - return val; - } - break; + case TokenType::LBrace: + { + // aggregate + parser.ReadToken(); + RefPtr<ShaderInputLayout::AggVal> val = new ShaderInputLayout::AggVal; - case TokenType::LBracket: + while (!parser.IsEnd() && !parser.LookAhead(TokenType::RBrace)) { - // array - parser.ReadToken(); - RefPtr<ShaderInputLayout::ArrayVal> val = new ShaderInputLayout::ArrayVal; + ShaderInputLayout::Field field; - while( !parser.IsEnd() && !parser.LookAhead(TokenType::RBracket) ) + if (parser.LookAhead(TokenType::Identifier) && + parser.NextToken(1).Type == TokenType::Colon) { - val->vals.add(parseValExpr(parser)); - - if(parser.LookAhead(TokenType::RBracket)) - break; - - parser.Read(TokenType::Comma); + field.name = parser.ReadWord(); + parser.Read(TokenType::Colon); } - parser.Read(TokenType::RBracket); - - return val; - } - break; - case TokenType::Identifier: - { - if( parser.AdvanceIf("new") ) - { - RefPtr<ShaderInputLayout::ObjectVal> val = new ShaderInputLayout::ObjectVal; + field.val = parseValExpr(parser); - if( parser.NextToken().Type == TokenType::Identifier ) - { - val->typeName = parseTypeName(parser); - } + val->fields.add(field); - val->contentVal = parseValExpr(parser); - return val; - } - else if( parser.AdvanceIf("out") ) - { - auto val = parseValExpr(parser); - val->isOutput = true; - return val; - } - else if (parser.AdvanceIf("specialize")) - { - RefPtr<ShaderInputLayout::SpecializeVal> val = - new ShaderInputLayout::SpecializeVal(); + if (parser.LookAhead(TokenType::RBrace)) + break; - parser.Read(Misc::TokenType::LParent); - while (!parser.IsEnd() && - parser.NextToken().Type != Misc::TokenType::RParent) - { - val->typeArgs.add(parseTypeName(parser)); - if (!parser.AdvanceIf(",")) - break; - } - parser.Read(Misc::TokenType::RParent); - val->contentVal = parseValExpr(parser); - return val; - } - else if (parser.AdvanceIf("dynamic")) - { - RefPtr<ShaderInputLayout::SpecializeVal> val = - new ShaderInputLayout::SpecializeVal(); - val->typeArgs.add("__Dynamic"); - val->contentVal = parseValExpr(parser); - return val; - } - else - { - // We assume that any other word is introducing one of the other - // cases for a parse-able value. - return parseVal(parser); - } + parser.Read(TokenType::Comma); } - break; + parser.Read(TokenType::RBrace); - default: - throw ShaderInputLayoutFormatException(String("Unexpected '") + parser.NextToken().Content + String("' at line") + String(parser.NextToken().Position.Line)); - } - } - RefPtr<ShaderInputLayout::Val> parseVal(Misc::TokenReader& parser) - { - auto word = parser.NextToken().Content; - if (parser.AdvanceIf("begin_array")) - { - RefPtr<ShaderInputLayout::ArrayVal> val = new ShaderInputLayout::ArrayVal; - pushParentVal(val); return val; } - else if (parser.AdvanceIf("begin_object")) - { - RefPtr<ShaderInputLayout::ObjectVal> val = new ShaderInputLayout::ObjectVal; - maybeParseOptions(parser, val.Ptr()); - - RefPtr<ShaderInputLayout::AggVal> contentVal = new ShaderInputLayout::AggVal; - val->contentVal = contentVal; - pushParentVal(contentVal); + break; - return val; - } - else if (parser.AdvanceIf("uniform")) + case TokenType::LBracket: { - RefPtr<ShaderInputLayout::DataVal> val = new ShaderInputLayout::DataVal; - maybeParseOptions(parser, val.Ptr()); - return val; - } - else if (parser.AdvanceIf("cbuffer")) - { - // A `cbuffer` is basically just an object where the content of - // the object is being provided by `uniform` data instead. + // array + parser.ReadToken(); + RefPtr<ShaderInputLayout::ArrayVal> val = new ShaderInputLayout::ArrayVal; - RefPtr<ShaderInputLayout::ObjectVal> objVal = new ShaderInputLayout::ObjectVal; + while (!parser.IsEnd() && !parser.LookAhead(TokenType::RBracket)) + { + val->vals.add(parseValExpr(parser)); - RefPtr<ShaderInputLayout::DataVal> dataVal = new ShaderInputLayout::DataVal; - maybeParseOptions(parser, dataVal.Ptr()); + if (parser.LookAhead(TokenType::RBracket)) + break; - objVal->contentVal = dataVal; + parser.Read(TokenType::Comma); + } + parser.Read(TokenType::RBracket); - return objVal; - } - else if (parser.AdvanceIf("ubuffer")) - { - RefPtr<ShaderInputLayout::BufferVal> val = new ShaderInputLayout::BufferVal; - val->bufferDesc.type = InputBufferType::StorageBuffer; - maybeParseOptions(parser, val.Ptr()); - return val; - } - else if (parser.AdvanceIf("Texture1D")) - { - RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; - val->textureDesc.dimension = 1; - maybeParseOptions(parser, val.Ptr()); - return val; - } - else if (parser.AdvanceIf("RWTextureBuffer")) - { - RefPtr<ShaderInputLayout::BufferVal> val = new ShaderInputLayout::BufferVal; - val->bufferDesc.type = InputBufferType::StorageBuffer; - maybeParseOptions(parser, val.Ptr()); - return val; - } - else if (parser.AdvanceIf("Texture2D")) - { - RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; - val->textureDesc.dimension = 2; - maybeParseOptions(parser, val.Ptr()); - return val; - } - else if (parser.AdvanceIf("Texture3D")) - { - RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; - val->textureDesc.dimension = 3; - maybeParseOptions(parser, val.Ptr()); - return val; - } - else if (parser.AdvanceIf("TextureCube")) - { - RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; - val->textureDesc.dimension = 2; - val->textureDesc.isCube = true; - maybeParseOptions(parser, val.Ptr()); - return val; - } - else if (parser.AdvanceIf("RWTexture1D")) - { - RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; - val->textureDesc.dimension = 1; - val->textureDesc.isRWTexture = true; - maybeParseOptions(parser, val.Ptr()); - return val; - } - else if (parser.AdvanceIf("RWTexture2D")) - { - RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; - val->textureDesc.dimension = 2; - val->textureDesc.isRWTexture = true; - maybeParseOptions(parser, val.Ptr()); - return val; - } - else if (parser.AdvanceIf("RWTexture3D")) - { - RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; - val->textureDesc.dimension = 3; - val->textureDesc.isRWTexture = true; - maybeParseOptions(parser, val.Ptr()); return val; } - else if (parser.AdvanceIf("RWTextureCube")) - { - RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; - val->textureDesc.dimension = 2; - val->textureDesc.isCube = true; - val->textureDesc.isRWTexture = true; - maybeParseOptions(parser, val.Ptr()); - return val; - } - else if (parser.AdvanceIf("Sampler")) - { - RefPtr<ShaderInputLayout::SamplerVal> val = new ShaderInputLayout::SamplerVal; - maybeParseOptions(parser, val.Ptr()); - return val; - } - else if (parser.AdvanceIf("TextureSampler1D")) - { - RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val = new ShaderInputLayout::CombinedTextureSamplerVal; - val->textureVal = new ShaderInputLayout::TextureVal; - val->samplerVal = new ShaderInputLayout::SamplerVal; - val->textureVal->textureDesc.dimension = 1; - maybeParseOptions(parser, val.Ptr()); - return val; - } - else if (parser.AdvanceIf("TextureSampler2D")) - { - RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val = new ShaderInputLayout::CombinedTextureSamplerVal; - val->textureVal = new ShaderInputLayout::TextureVal; - val->samplerVal = new ShaderInputLayout::SamplerVal; - val->textureVal->textureDesc.dimension = 2; - maybeParseOptions(parser, val.Ptr()); - return val; - } - else if (parser.AdvanceIf("TextureSampler3D")) - { - RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val = new ShaderInputLayout::CombinedTextureSamplerVal; - val->textureVal = new ShaderInputLayout::TextureVal; - val->samplerVal = new ShaderInputLayout::SamplerVal; - val->textureVal->textureDesc.dimension = 3; - maybeParseOptions(parser, val.Ptr()); - return val; - } - else if (parser.AdvanceIf("TextureSamplerCube")) - { - RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val = new ShaderInputLayout::CombinedTextureSamplerVal; - val->textureVal = new ShaderInputLayout::TextureVal; - val->samplerVal = new ShaderInputLayout::SamplerVal; - val->textureVal->textureDesc.dimension = 2; - val->textureVal->textureDesc.isCube = true; - maybeParseOptions(parser, val.Ptr()); - return val; - } - else if (parser.AdvanceIf("AccelerationStructure")) - { - RefPtr<ShaderInputLayout::AccelerationStructureVal> val = - new ShaderInputLayout::AccelerationStructureVal(); - return val; - } - else - { - throw ShaderInputLayoutFormatException(String("Unknown shader input type '") + word + String("' at line") + String(parser.NextToken().Position.Line)); - } - parser.ReadToken(); - return nullptr; - } - - String parseName(Misc::TokenReader& parser) - { - typedef Misc::Token Token; - typedef Misc::TokenType TokenType; - - StringBuilder builder; + break; - Token nameToken = parser.ReadToken(); - if (nameToken.Type != TokenType::Identifier) + case TokenType::Identifier: { - throw ShaderInputLayoutFormatException(StringBuilder() << "Invalid input syntax at line " << parser.NextToken().Position.Line); - } - builder << nameToken.Content; + if (parser.AdvanceIf("new")) + { + RefPtr<ShaderInputLayout::ObjectVal> val = new ShaderInputLayout::ObjectVal; - for(;;) - { - Token token = parser.NextToken(0); + if (parser.NextToken().Type == TokenType::Identifier) + { + val->typeName = parseTypeName(parser); + } - if (token.Type == TokenType::LBracket) + val->contentVal = parseValExpr(parser); + return val; + } + else if (parser.AdvanceIf("out")) { - parser.ReadToken(); - int index = parser.ReadInt(); - SLANG_ASSERT(index >= 0); - parser.ReadMatchingToken(TokenType::RBracket); - - builder << "[" << index << "]"; + auto val = parseValExpr(parser); + val->isOutput = true; + return val; } - else if (token.Type == TokenType::Dot) + else if (parser.AdvanceIf("specialize")) { - parser.ReadToken(); - Token identifierToken = parser.ReadMatchingToken(TokenType::Identifier); + RefPtr<ShaderInputLayout::SpecializeVal> val = + new ShaderInputLayout::SpecializeVal(); - builder << "." << identifierToken.Content; + parser.Read(Misc::TokenType::LParent); + while (!parser.IsEnd() && parser.NextToken().Type != Misc::TokenType::RParent) + { + val->typeArgs.add(parseTypeName(parser)); + if (!parser.AdvanceIf(",")) + break; + } + parser.Read(Misc::TokenType::RParent); + val->contentVal = parseValExpr(parser); + return val; + } + else if (parser.AdvanceIf("dynamic")) + { + RefPtr<ShaderInputLayout::SpecializeVal> val = + new ShaderInputLayout::SpecializeVal(); + val->typeArgs.add("__Dynamic"); + val->contentVal = parseValExpr(parser); + return val; } else { - return builder; + // We assume that any other word is introducing one of the other + // cases for a parse-able value. + return parseVal(parser); } } + break; + + default: + throw ShaderInputLayoutFormatException( + String("Unexpected '") + parser.NextToken().Content + String("' at line") + + String(parser.NextToken().Position.Line)); } + } - void parseFieldBindings(Misc::TokenReader& parser, ShaderInputLayout::Field& ioField) + RefPtr<ShaderInputLayout::Val> parseVal(Misc::TokenReader& parser) + { + auto word = parser.NextToken().Content; + if (parser.AdvanceIf("begin_array")) { - // parse bindings - if (parser.LookAhead(":")) - { - parser.Read(":"); - while (!parser.IsEnd()) - { - if (parser.AdvanceIf("out")) - { - ioField.val->isOutput = true; - } - else if (parser.AdvanceIf("name")) - { - // Optionally consume '=' - if (parser.NextToken().Type == Misc::TokenType::OpAssign) - { - parser.ReadToken(); - } + RefPtr<ShaderInputLayout::ArrayVal> val = new ShaderInputLayout::ArrayVal; + pushParentVal(val); + return val; + } + else if (parser.AdvanceIf("begin_object")) + { + RefPtr<ShaderInputLayout::ObjectVal> val = new ShaderInputLayout::ObjectVal; + maybeParseOptions(parser, val.Ptr()); - ioField.name = parseName(parser); - } - else - { - fprintf(stderr, "Invalid TEST_INPUT syntax '%s'\n", parser.NextToken().Content.getBuffer()); - break; - } + RefPtr<ShaderInputLayout::AggVal> contentVal = new ShaderInputLayout::AggVal; + val->contentVal = contentVal; + pushParentVal(contentVal); - if (parser.LookAhead(",")) - parser.Read(","); - } - } + return val; } - - void pushParentVal(ShaderInputLayout::ParentVal* val) + else if (parser.AdvanceIf("uniform")) { - parentValStack.add(parentVal); - parentVal = val; + RefPtr<ShaderInputLayout::DataVal> val = new ShaderInputLayout::DataVal; + maybeParseOptions(parser, val.Ptr()); + return val; } - - void parseValEntry(Misc::TokenReader& parser) + else if (parser.AdvanceIf("cbuffer")) { - auto parentForNewVal = parentVal; + // A `cbuffer` is basically just an object where the content of + // the object is being provided by `uniform` data instead. - ShaderInputLayout::Field field; - field.val = parseVal(parser); - parseFieldBindings(parser, field); + RefPtr<ShaderInputLayout::ObjectVal> objVal = new ShaderInputLayout::ObjectVal; - parentForNewVal->addField(field); - } + RefPtr<ShaderInputLayout::DataVal> dataVal = new ShaderInputLayout::DataVal; + maybeParseOptions(parser, dataVal.Ptr()); + + objVal->contentVal = dataVal; - void parseSetEntry(Misc::TokenReader& parser) + return objVal; + } + else if (parser.AdvanceIf("ubuffer")) + { + RefPtr<ShaderInputLayout::BufferVal> val = new ShaderInputLayout::BufferVal; + val->bufferDesc.type = InputBufferType::StorageBuffer; + maybeParseOptions(parser, val.Ptr()); + return val; + } + else if (parser.AdvanceIf("Texture1D")) + { + RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; + val->textureDesc.dimension = 1; + maybeParseOptions(parser, val.Ptr()); + return val; + } + else if (parser.AdvanceIf("RWTextureBuffer")) + { + RefPtr<ShaderInputLayout::BufferVal> val = new ShaderInputLayout::BufferVal; + val->bufferDesc.type = InputBufferType::StorageBuffer; + maybeParseOptions(parser, val.Ptr()); + return val; + } + else if (parser.AdvanceIf("Texture2D")) + { + RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; + val->textureDesc.dimension = 2; + maybeParseOptions(parser, val.Ptr()); + return val; + } + else if (parser.AdvanceIf("Texture3D")) + { + RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; + val->textureDesc.dimension = 3; + maybeParseOptions(parser, val.Ptr()); + return val; + } + else if (parser.AdvanceIf("TextureCube")) + { + RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; + val->textureDesc.dimension = 2; + val->textureDesc.isCube = true; + maybeParseOptions(parser, val.Ptr()); + return val; + } + else if (parser.AdvanceIf("RWTexture1D")) + { + RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; + val->textureDesc.dimension = 1; + val->textureDesc.isRWTexture = true; + maybeParseOptions(parser, val.Ptr()); + return val; + } + else if (parser.AdvanceIf("RWTexture2D")) + { + RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; + val->textureDesc.dimension = 2; + val->textureDesc.isRWTexture = true; + maybeParseOptions(parser, val.Ptr()); + return val; + } + else if (parser.AdvanceIf("RWTexture3D")) + { + RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; + val->textureDesc.dimension = 3; + val->textureDesc.isRWTexture = true; + maybeParseOptions(parser, val.Ptr()); + return val; + } + else if (parser.AdvanceIf("RWTextureCube")) + { + RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal; + val->textureDesc.dimension = 2; + val->textureDesc.isCube = true; + val->textureDesc.isRWTexture = true; + maybeParseOptions(parser, val.Ptr()); + return val; + } + else if (parser.AdvanceIf("Sampler")) + { + RefPtr<ShaderInputLayout::SamplerVal> val = new ShaderInputLayout::SamplerVal; + maybeParseOptions(parser, val.Ptr()); + return val; + } + else if (parser.AdvanceIf("TextureSampler1D")) + { + RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val = + new ShaderInputLayout::CombinedTextureSamplerVal; + val->textureVal = new ShaderInputLayout::TextureVal; + val->samplerVal = new ShaderInputLayout::SamplerVal; + val->textureVal->textureDesc.dimension = 1; + maybeParseOptions(parser, val.Ptr()); + return val; + } + else if (parser.AdvanceIf("TextureSampler2D")) + { + RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val = + new ShaderInputLayout::CombinedTextureSamplerVal; + val->textureVal = new ShaderInputLayout::TextureVal; + val->samplerVal = new ShaderInputLayout::SamplerVal; + val->textureVal->textureDesc.dimension = 2; + maybeParseOptions(parser, val.Ptr()); + return val; + } + else if (parser.AdvanceIf("TextureSampler3D")) { - auto parentForNewVal = parentVal; + RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val = + new ShaderInputLayout::CombinedTextureSamplerVal; + val->textureVal = new ShaderInputLayout::TextureVal; + val->samplerVal = new ShaderInputLayout::SamplerVal; + val->textureVal->textureDesc.dimension = 3; + maybeParseOptions(parser, val.Ptr()); + return val; + } + else if (parser.AdvanceIf("TextureSamplerCube")) + { + RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val = + new ShaderInputLayout::CombinedTextureSamplerVal; + val->textureVal = new ShaderInputLayout::TextureVal; + val->samplerVal = new ShaderInputLayout::SamplerVal; + val->textureVal->textureDesc.dimension = 2; + val->textureVal->textureDesc.isCube = true; + maybeParseOptions(parser, val.Ptr()); + return val; + } + else if (parser.AdvanceIf("AccelerationStructure")) + { + RefPtr<ShaderInputLayout::AccelerationStructureVal> val = + new ShaderInputLayout::AccelerationStructureVal(); + return val; + } + else + { + throw ShaderInputLayoutFormatException( + String("Unknown shader input type '") + word + String("' at line") + + String(parser.NextToken().Position.Line)); + } + parser.ReadToken(); + return nullptr; + } - ShaderInputLayout::Field field; - field.name = parseName(parser); - parser.Read(Misc::TokenType::OpAssign); - field.val = parseValExpr(parser); + String parseName(Misc::TokenReader& parser) + { + typedef Misc::Token Token; + typedef Misc::TokenType TokenType; - parentForNewVal->addField(field); - } + StringBuilder builder; - void parseTypeConformance(Misc::TokenReader& parser) + Token nameToken = parser.ReadToken(); + if (nameToken.Type != TokenType::Identifier) { - ShaderInputLayout::TypeConformanceVal conformance; - conformance.derivedTypeName = parseTypeName(parser); - parser.Read(":"); - conformance.baseTypeName = parseTypeName(parser); - if (parser.AdvanceIf("=")) - conformance.idOverride = parser.ReadInt(); - layout->typeConformances.add(conformance); + throw ShaderInputLayoutFormatException( + StringBuilder() << "Invalid input syntax at line " + << parser.NextToken().Position.Line); } + builder << nameToken.Content; - void parseLine(Misc::TokenReader& parser) + for (;;) { - if (parser.LookAhead("entryPointSpecializationArg") - || parser.LookAhead("type") - || parser.LookAhead("entryPointExistentialType")) + Token token = parser.NextToken(0); + + if (token.Type == TokenType::LBracket) { parser.ReadToken(); - StringBuilder typeExp; - while (!parser.IsEnd()) - typeExp << parser.ReadToken().Content; - layout->entryPointSpecializationArgs.add(typeExp); + int index = parser.ReadInt(); + SLANG_ASSERT(index >= 0); + parser.ReadMatchingToken(TokenType::RBracket); + + builder << "[" << index << "]"; } - else if (parser.LookAhead("globalSpecializationArg") - || parser.LookAhead("global_type") - || parser.LookAhead("globalExistentialType")) + else if (token.Type == TokenType::Dot) { parser.ReadToken(); - StringBuilder typeExp; - while (!parser.IsEnd()) - typeExp << parser.ReadToken().Content; - layout->globalSpecializationArgs.add(typeExp); - } - else if (parser.AdvanceIf("render_targets")) - { - layout->numRenderTargets = parser.ReadInt(); - } - else if( parser.AdvanceIf("end") ) - { - parentVal = parentValStack.getLast(); - parentValStack.removeLast(); - } - else if( parser.AdvanceIf("set") ) - { - parseSetEntry(parser); - } - else if (parser.AdvanceIf("type_conformance")) - { - parseTypeConformance(parser); + Token identifierToken = parser.ReadMatchingToken(TokenType::Identifier); + + builder << "." << identifierToken.Content; } else { - parseValEntry(parser); + return builder; } } + } - RefPtr<ShaderInputLayout::AggVal> parse(const char * source) + void parseFieldBindings(Misc::TokenReader& parser, ShaderInputLayout::Field& ioField) + { + // parse bindings + if (parser.LookAhead(":")) { - RefPtr<ShaderInputLayout::AggVal> rootVal = new ShaderInputLayout::AggVal; - parentVal = rootVal; - - auto lines = Misc::Split(source, '\n'); - for (auto & line : lines) + parser.Read(":"); + while (!parser.IsEnd()) { - if (line.startsWith("//TEST_INPUT:")) + if (parser.AdvanceIf("out")) { - auto lineContent = line.subString(13, line.getLength() - 13); - Misc::TokenReader parser(lineContent); - try - { - parseLine(parser); - } - catch (const Misc::TextFormatException&) + ioField.val->isOutput = true; + } + else if (parser.AdvanceIf("name")) + { + // Optionally consume '=' + if (parser.NextToken().Type == Misc::TokenType::OpAssign) { - StringBuilder msg; - msg << "Invalid input syntax at line " << parser.NextToken().Position.Line; - throw ShaderInputLayoutFormatException(msg); + parser.ReadToken(); } + + ioField.name = parseName(parser); } + else + { + fprintf( + stderr, + "Invalid TEST_INPUT syntax '%s'\n", + parser.NextToken().Content.getBuffer()); + break; + } + + if (parser.LookAhead(",")) + parser.Read(","); } + } + } - // TODO: check that stack has been maintained correctly... + void pushParentVal(ShaderInputLayout::ParentVal* val) + { + parentValStack.add(parentVal); + parentVal = val; + } - return rootVal; - } - }; + void parseValEntry(Misc::TokenReader& parser) + { + auto parentForNewVal = parentVal; + + ShaderInputLayout::Field field; + field.val = parseVal(parser); + parseFieldBindings(parser, field); + + parentForNewVal->addField(field); + } - void ShaderInputLayout::parse(RandomGenerator* rand, const char * source) + void parseSetEntry(Misc::TokenReader& parser) { - rootVal = nullptr; - globalSpecializationArgs.clear(); - entryPointSpecializationArgs.clear(); + auto parentForNewVal = parentVal; + + ShaderInputLayout::Field field; + field.name = parseName(parser); + parser.Read(Misc::TokenType::OpAssign); + field.val = parseValExpr(parser); - ShaderInputLayoutParser parser(this, rand); - rootVal = parser.parse(source); + parentForNewVal->addField(field); } - /* static */SlangResult ShaderInputLayout::writeBinding(slang::TypeLayoutReflection* typeLayout, const void* data, size_t sizeInBytes, WriterHelper writer) + void parseTypeConformance(Misc::TokenReader& parser) { - typedef slang::TypeReflection::ScalarType ScalarType; + ShaderInputLayout::TypeConformanceVal conformance; + conformance.derivedTypeName = parseTypeName(parser); + parser.Read(":"); + conformance.baseTypeName = parseTypeName(parser); + if (parser.AdvanceIf("=")) + conformance.idOverride = parser.ReadInt(); + layout->typeConformances.add(conformance); + } - slang::TypeReflection::ScalarType scalarType = slang::TypeReflection::ScalarType::None; + void parseLine(Misc::TokenReader& parser) + { + if (parser.LookAhead("entryPointSpecializationArg") || parser.LookAhead("type") || + parser.LookAhead("entryPointExistentialType")) + { + parser.ReadToken(); + StringBuilder typeExp; + while (!parser.IsEnd()) + typeExp << parser.ReadToken().Content; + layout->entryPointSpecializationArgs.add(typeExp); + } + else if ( + parser.LookAhead("globalSpecializationArg") || parser.LookAhead("global_type") || + parser.LookAhead("globalExistentialType")) + { + parser.ReadToken(); + StringBuilder typeExp; + while (!parser.IsEnd()) + typeExp << parser.ReadToken().Content; + layout->globalSpecializationArgs.add(typeExp); + } + else if (parser.AdvanceIf("render_targets")) + { + layout->numRenderTargets = parser.ReadInt(); + } + else if (parser.AdvanceIf("end")) + { + parentVal = parentValStack.getLast(); + parentValStack.removeLast(); + } + else if (parser.AdvanceIf("set")) + { + parseSetEntry(parser); + } + else if (parser.AdvanceIf("type_conformance")) + { + parseTypeConformance(parser); + } + else + { + parseValEntry(parser); + } + } - slang::TypeLayoutReflection* elementTypeLayout = nullptr; + RefPtr<ShaderInputLayout::AggVal> parse(const char* source) + { + RefPtr<ShaderInputLayout::AggVal> rootVal = new ShaderInputLayout::AggVal; + parentVal = rootVal; - if (typeLayout) + auto lines = Misc::Split(source, '\n'); + for (auto& line : lines) { - switch (typeLayout->getKind()) + if (line.startsWith("//TEST_INPUT:")) { - - //case slang::TypeReflection::Kind::Struct: - case slang::TypeReflection::Kind::Array: - case slang::TypeReflection::Kind::Matrix: - case slang::TypeReflection::Kind::Vector: + auto lineContent = line.subString(13, line.getLength() - 13); + Misc::TokenReader parser(lineContent); + try { - elementTypeLayout = typeLayout->getElementTypeLayout(); - break; + parseLine(parser); } - case slang::TypeReflection::Kind::Scalar: + catch (const Misc::TextFormatException&) { - elementTypeLayout = typeLayout; - break; - } - case slang::TypeReflection::Kind::Resource: - { - elementTypeLayout = typeLayout->getElementTypeLayout(); - break; - } - case slang::TypeReflection::Kind::TextureBuffer: - case slang::TypeReflection::Kind::ShaderStorageBuffer: - { - elementTypeLayout = typeLayout->getElementTypeLayout(); - break; + StringBuilder msg; + msg << "Invalid input syntax at line " << parser.NextToken().Position.Line; + throw ShaderInputLayoutFormatException(msg); } } } - if (elementTypeLayout) - { - scalarType = elementTypeLayout->getScalarType(); - } + // TODO: check that stack has been maintained correctly... - if (scalarType != ScalarType::None && scalarType != ScalarType::Void) - { - UnownedStringSlice text = TypeTextUtil::getScalarTypeName(scalarType); - // Write out the type - writer.put("type: "); - writer.put(text); - writer.put("\n"); - } + return rootVal; + } +}; + +void ShaderInputLayout::parse(RandomGenerator* rand, const char* source) +{ + rootVal = nullptr; + globalSpecializationArgs.clear(); + entryPointSpecializationArgs.clear(); + + ShaderInputLayoutParser parser(this, rand); + rootVal = parser.parse(source); +} + +/* static */ SlangResult ShaderInputLayout::writeBinding( + slang::TypeLayoutReflection* typeLayout, + const void* data, + size_t sizeInBytes, + WriterHelper writer) +{ + typedef slang::TypeReflection::ScalarType ScalarType; - switch (scalarType) + slang::TypeReflection::ScalarType scalarType = slang::TypeReflection::ScalarType::None; + + slang::TypeLayoutReflection* elementTypeLayout = nullptr; + + if (typeLayout) + { + switch (typeLayout->getKind()) { - // TODO(JS): - // Bool is here, because it's not clear across APIs how bool is laid out in memory - default: - case ScalarType::None: - case ScalarType::Void: - case ScalarType::Bool: + + // case slang::TypeReflection::Kind::Struct: + case slang::TypeReflection::Kind::Array: + case slang::TypeReflection::Kind::Matrix: + case slang::TypeReflection::Kind::Vector: { - auto ptr = (const uint32_t*)data; - const size_t size = sizeInBytes / sizeof(ptr[0]); - for (size_t i = 0; i < size; ++i) - { - uint32_t v = ptr[i]; - writer.print("%X\n", v); - } + elementTypeLayout = typeLayout->getElementTypeLayout(); break; } - case ScalarType::Float16: + case slang::TypeReflection::Kind::Scalar: { - auto ptr = (const uint16_t*)data; - const size_t size = sizeInBytes / sizeof(ptr[0]); - for (size_t i = 0; i < size; ++i) - { - const float v = HalfToFloat(ptr[i]); - writer.print("%f\n", v); - } + elementTypeLayout = typeLayout; break; } - case ScalarType::UInt32: + case slang::TypeReflection::Kind::Resource: { - auto ptr = (const uint32_t*)data; - const size_t size = sizeInBytes / sizeof(ptr[0]); - for (size_t i = 0; i < size; ++i) - { - uint32_t v = ptr[i]; - writer.print("%u\n", v); - } + elementTypeLayout = typeLayout->getElementTypeLayout(); break; } - case ScalarType::Int32: + case slang::TypeReflection::Kind::TextureBuffer: + case slang::TypeReflection::Kind::ShaderStorageBuffer: { - auto ptr = (const int32_t*)data; - const size_t size = sizeInBytes / sizeof(ptr[0]); - for (size_t i = 0; i < size; ++i) - { - int32_t v = ptr[i]; - writer.print("%i\n", v); - } + elementTypeLayout = typeLayout->getElementTypeLayout(); break; } - case ScalarType::Int64: + } + } + + if (elementTypeLayout) + { + scalarType = elementTypeLayout->getScalarType(); + } + + if (scalarType != ScalarType::None && scalarType != ScalarType::Void) + { + UnownedStringSlice text = TypeTextUtil::getScalarTypeName(scalarType); + // Write out the type + writer.put("type: "); + writer.put(text); + writer.put("\n"); + } + + switch (scalarType) + { + // TODO(JS): + // Bool is here, because it's not clear across APIs how bool is laid out in memory + default: + case ScalarType::None: + case ScalarType::Void: + case ScalarType::Bool: + { + auto ptr = (const uint32_t*)data; + const size_t size = sizeInBytes / sizeof(ptr[0]); + for (size_t i = 0; i < size; ++i) + { + uint32_t v = ptr[i]; + writer.print("%X\n", v); + } + break; + } + case ScalarType::Float16: + { + auto ptr = (const uint16_t*)data; + const size_t size = sizeInBytes / sizeof(ptr[0]); + for (size_t i = 0; i < size; ++i) { - auto ptr = (const int64_t*)data; - const size_t size = sizeInBytes / sizeof(ptr[0]); - for (size_t i = 0; i < size; ++i) - { - int64_t v = ptr[i]; - writer.print("%" PRId64 "\n", v); - } - break; + const float v = HalfToFloat(ptr[i]); + writer.print("%f\n", v); } - case ScalarType::UInt64: + break; + } + case ScalarType::UInt32: + { + auto ptr = (const uint32_t*)data; + const size_t size = sizeInBytes / sizeof(ptr[0]); + for (size_t i = 0; i < size; ++i) { - auto ptr = (const uint64_t*)data; - const size_t size = sizeInBytes / sizeof(ptr[0]); - for (size_t i = 0; i < size; ++i) - { - uint64_t v = ptr[i]; - writer.print("%" PRIu64 "\n", v); - } - break; + uint32_t v = ptr[i]; + writer.print("%u\n", v); } - case ScalarType::Float32: + break; + } + case ScalarType::Int32: + { + auto ptr = (const int32_t*)data; + const size_t size = sizeInBytes / sizeof(ptr[0]); + for (size_t i = 0; i < size; ++i) { - auto ptr = (const float*)data; - const size_t size = sizeInBytes / sizeof(ptr[0]); - for (size_t i = 0; i < size; ++i) - { - const float v = ptr[i]; - writer.print("%f\n", v); - } - break; + int32_t v = ptr[i]; + writer.print("%i\n", v); } - case ScalarType::Float64: + break; + } + case ScalarType::Int64: + { + auto ptr = (const int64_t*)data; + const size_t size = sizeInBytes / sizeof(ptr[0]); + for (size_t i = 0; i < size; ++i) { - auto ptr = (const double*)data; - const size_t size = sizeInBytes / sizeof(ptr[0]); - for (size_t i = 0; i < size; ++i) - { - const double v = ptr[i]; - writer.print("%f\n", v); - } - break; + int64_t v = ptr[i]; + writer.print("%" PRId64 "\n", v); } + break; + } + case ScalarType::UInt64: + { + auto ptr = (const uint64_t*)data; + const size_t size = sizeInBytes / sizeof(ptr[0]); + for (size_t i = 0; i < size; ++i) + { + uint64_t v = ptr[i]; + writer.print("%" PRIu64 "\n", v); + } + break; + } + case ScalarType::Float32: + { + auto ptr = (const float*)data; + const size_t size = sizeInBytes / sizeof(ptr[0]); + for (size_t i = 0; i < size; ++i) + { + const float v = ptr[i]; + writer.print("%f\n", v); + } + break; + } + case ScalarType::Float64: + { + auto ptr = (const double*)data; + const size_t size = sizeInBytes / sizeof(ptr[0]); + for (size_t i = 0; i < size; ++i) + { + const double v = ptr[i]; + writer.print("%f\n", v); + } + break; } - - return SLANG_OK; } - void loadDataIntoHalf(uint16_t& out, const uint8_t& in) - { - out = FloatToHalf((float(in) / 255.0f)); - } - void loadDataIntoFloat(float& out, const uint8_t& in) - { - out = (float(in)/255.0f); - } - template<typename T> - void loadDataIntoUint(T& out, const uint8_t& in) - { - out = T(in); - } - template<typename T> - void loadDataIntoInt(T& out, const uint8_t& in) - { - out = T(in); - } + return SLANG_OK; +} - // T for type to return, F for function pointer to operate on uint8->T - template<typename T, typename F> - void generateTextureDataWithTargetTStorage(TextureData& output, const InputTextureDesc& desc, const rhi::FormatInfo& formatInfo, F loadUint8ToT) - { - // the following function assumes input of 0 or 1 since our testing framework only tests with 0 or 1 - TextureData work; - generateTextureDataRGB8(work, desc); +void loadDataIntoHalf(uint16_t& out, const uint8_t& in) +{ + out = FloatToHalf((float(in) / 255.0f)); +} +void loadDataIntoFloat(float& out, const uint8_t& in) +{ + out = (float(in) / 255.0f); +} +template<typename T> +void loadDataIntoUint(T& out, const uint8_t& in) +{ + out = T(in); +} +template<typename T> +void loadDataIntoInt(T& out, const uint8_t& in) +{ + out = T(in); +} - output.init(desc.format); +// T for type to return, F for function pointer to operate on uint8->T +template<typename T, typename F> +void generateTextureDataWithTargetTStorage( + TextureData& output, + const InputTextureDesc& desc, + const rhi::FormatInfo& formatInfo, + F loadUint8ToT) +{ + // the following function assumes input of 0 or 1 since our testing framework only tests with 0 + // or 1 + TextureData work; + generateTextureDataRGB8(work, desc); - output.m_textureSize = work.m_textureSize; - output.m_mipLevels = work.m_mipLevels; - output.m_arraySize = work.m_arraySize; + output.init(desc.format); - List<TextureData::Slice>& dstSlices = output.m_slices; + output.m_textureSize = work.m_textureSize; + output.m_mipLevels = work.m_mipLevels; + output.m_arraySize = work.m_arraySize; - Index numSlices = work.m_slices.getCount(); - dstSlices.setCount(numSlices); + List<TextureData::Slice>& dstSlices = output.m_slices; - for (int i = 0; i < numSlices; ++i) - { - const TextureData::Slice& srcSlice = work.m_slices[i]; + Index numSlices = work.m_slices.getCount(); + dstSlices.setCount(numSlices); - const Index pixelCount = srcSlice.valuesCount; - const uint8_t* srcPixels = (const uint8_t*)srcSlice.values; + for (int i = 0; i < numSlices; ++i) + { + const TextureData::Slice& srcSlice = work.m_slices[i]; - T* dstPixels = (T*)output.setSliceCount(i, pixelCount); - switch (formatInfo.channelCount) - { - case 1: + const Index pixelCount = srcSlice.valuesCount; + const uint8_t* srcPixels = (const uint8_t*)srcSlice.values; + + T* dstPixels = (T*)output.setSliceCount(i, pixelCount); + switch (formatInfo.channelCount) + { + case 1: { for (Index j = 0; j < pixelCount; ++j, srcPixels += 4, dstPixels += 1) { @@ -1198,7 +1251,7 @@ namespace renderer_test } break; } - case 2: + case 2: { for (Index j = 0; j < pixelCount; ++j, srcPixels += 4, dstPixels += 2) { @@ -1208,7 +1261,7 @@ namespace renderer_test } break; } - case 3: + case 3: { for (Index j = 0; j < pixelCount; ++j, srcPixels += 4, dstPixels += 3) { @@ -1219,7 +1272,7 @@ namespace renderer_test } break; } - case 4: + case 4: { for (Index j = 0; j < pixelCount; ++j, srcPixels += 4, dstPixels += 4) { @@ -1231,245 +1284,286 @@ namespace renderer_test } break; } - } } } - void generateTextureData(TextureData& output, const InputTextureDesc& desc) - { - const FormatInfo& formatInfo = getFormatInfo(desc.format); +} +void generateTextureData(TextureData& output, const InputTextureDesc& desc) +{ + const FormatInfo& formatInfo = getFormatInfo(desc.format); - switch (desc.format) + switch (desc.format) + { + case Format::R8G8B8A8_UNORM: { - case Format::R8G8B8A8_UNORM: - { - generateTextureDataRGB8(output, desc); - break; - } - case Format::R16_FLOAT: - case Format::R16G16_FLOAT: - case Format::R16G16B16A16_FLOAT: - { - generateTextureDataWithTargetTStorage<uint16_t>(output, desc, formatInfo, loadDataIntoHalf); - break; - } - case Format::R64_UINT: - { - generateTextureDataWithTargetTStorage<uint64_t>(output, desc, formatInfo, loadDataIntoUint<uint64_t>); - break; - } - case Format::R32_FLOAT: - case Format::R32G32_FLOAT: - case Format::R32G32B32_FLOAT: - case Format::R32G32B32A32_FLOAT: - case Format::D32_FLOAT: - { - generateTextureDataWithTargetTStorage<float>(output, desc, formatInfo, loadDataIntoFloat); - break; - } - case Format::R32_UINT: - case Format::R32G32_UINT: - case Format::R32G32B32_UINT: - case Format::R32G32B32A32_UINT: - { - generateTextureDataWithTargetTStorage<uint32_t>(output, desc, formatInfo, loadDataIntoUint<uint32_t>); - break; - } - case Format::R16_UINT: - case Format::R16G16_UINT: - case Format::R16G16B16A16_UINT: - { - generateTextureDataWithTargetTStorage<uint16_t>(output, desc, formatInfo, loadDataIntoUint<uint16_t>); - break; - } - case Format::R8_UINT: - case Format::R8G8_UINT: - case Format::R8G8B8A8_UINT: - { - generateTextureDataWithTargetTStorage<uint8_t>(output, desc, formatInfo, loadDataIntoUint<uint8_t>); - break; - } - case Format::R64_SINT: - { - generateTextureDataWithTargetTStorage<int64_t>(output, desc, formatInfo, loadDataIntoInt<int64_t>); - break; - } - case Format::R32_SINT: - case Format::R32G32_SINT: - case Format::R32G32B32_SINT: - case Format::R32G32B32A32_SINT: - { - generateTextureDataWithTargetTStorage<int32_t>(output, desc, formatInfo, loadDataIntoInt<int32_t>); - break; - } - case Format::R16_SINT: - case Format::R16G16_SINT: - case Format::R16G16B16A16_SINT: - { - generateTextureDataWithTargetTStorage<int16_t>(output, desc, formatInfo, loadDataIntoInt<int16_t>); - break; - } - case Format::R8_SINT: - case Format::R8G8_SINT: - case Format::R8G8B8A8_SINT: - { - generateTextureDataWithTargetTStorage<int8_t>(output, desc, formatInfo, loadDataIntoInt<int8_t>); - break; - } - default: - { - SLANG_ASSERT(!"Unhandled format"); - break; - } + generateTextureDataRGB8(output, desc); + break; } - } - - template <typename F> - void _iteratePixels(int dimension, int size, unsigned int * buffer, F f) - { - if (dimension == 1) - for (int i = 0; i < size; i++) - buffer[i] = f(i, 0, 0); - else if (dimension == 2) - for (int i = 0; i < size; i++) - for (int j = 0; j < size; j++) - buffer[i*size + j] = f(j, i, 0); - else if (dimension == 3) - for (int i = 0; i < size; i++) - for (int j = 0; j < size; j++) - for (int k = 0; k < size; k++) - buffer[i*size*size + j * size + k] = f(k, j, i); - }; - - void generateTextureDataRGB8(TextureData& output, const InputTextureDesc& inputDesc) - { - int arrLen = inputDesc.arrayLength; - if (arrLen == 0) - arrLen = 1; - - output.init(Format::R8G8B8A8_UNORM); - - enum class SimpleScalarType { - kUint, - kInt, - kFloat, - }; - SimpleScalarType type; - const rhi::FormatInfo& formatInfo = getFormatInfo(inputDesc.format); - switch (formatInfo.channelType) - { - case SLANG_SCALAR_TYPE_UINT64: - case SLANG_SCALAR_TYPE_UINT32: - case SLANG_SCALAR_TYPE_UINT16: - case SLANG_SCALAR_TYPE_UINT8: - type = SimpleScalarType::kUint; + case Format::R16_FLOAT: + case Format::R16G16_FLOAT: + case Format::R16G16B16A16_FLOAT: + { + generateTextureDataWithTargetTStorage<uint16_t>( + output, + desc, + formatInfo, + loadDataIntoHalf); break; - case SLANG_SCALAR_TYPE_INT64: - case SLANG_SCALAR_TYPE_INT32: - case SLANG_SCALAR_TYPE_INT16: - case SLANG_SCALAR_TYPE_INT8: - type = SimpleScalarType::kInt; + } + case Format::R64_UINT: + { + generateTextureDataWithTargetTStorage<uint64_t>( + output, + desc, + formatInfo, + loadDataIntoUint<uint64_t>); break; - case SLANG_SCALAR_TYPE_FLOAT64: - case SLANG_SCALAR_TYPE_FLOAT32: - case SLANG_SCALAR_TYPE_FLOAT16: - type = SimpleScalarType::kFloat; + } + case Format::R32_FLOAT: + case Format::R32G32_FLOAT: + case Format::R32G32B32_FLOAT: + case Format::R32G32B32A32_FLOAT: + case Format::D32_FLOAT: + { + generateTextureDataWithTargetTStorage<float>( + output, + desc, + formatInfo, + loadDataIntoFloat); break; - default: - type = SimpleScalarType::kUint; + } + case Format::R32_UINT: + case Format::R32G32_UINT: + case Format::R32G32B32_UINT: + case Format::R32G32B32A32_UINT: + { + generateTextureDataWithTargetTStorage<uint32_t>( + output, + desc, + formatInfo, + loadDataIntoUint<uint32_t>); + break; + } + case Format::R16_UINT: + case Format::R16G16_UINT: + case Format::R16G16B16A16_UINT: + { + generateTextureDataWithTargetTStorage<uint16_t>( + output, + desc, + formatInfo, + loadDataIntoUint<uint16_t>); + break; + } + case Format::R8_UINT: + case Format::R8G8_UINT: + case Format::R8G8B8A8_UINT: + { + generateTextureDataWithTargetTStorage<uint8_t>( + output, + desc, + formatInfo, + loadDataIntoUint<uint8_t>); + break; + } + case Format::R64_SINT: + { + generateTextureDataWithTargetTStorage<int64_t>( + output, + desc, + formatInfo, + loadDataIntoInt<int64_t>); break; } - //List<List<unsigned int>>& dataBuffer = output.dataBuffer; - int arraySize = arrLen; - if (inputDesc.isCube) - arraySize *= 6; - output.m_arraySize = arraySize; - output.m_textureSize = inputDesc.size; + case Format::R32_SINT: + case Format::R32G32_SINT: + case Format::R32G32B32_SINT: + case Format::R32G32B32A32_SINT: + { + generateTextureDataWithTargetTStorage<int32_t>( + output, + desc, + formatInfo, + loadDataIntoInt<int32_t>); + break; + } + case Format::R16_SINT: + case Format::R16G16_SINT: + case Format::R16G16B16A16_SINT: + { + generateTextureDataWithTargetTStorage<int16_t>( + output, + desc, + formatInfo, + loadDataIntoInt<int16_t>); + break; + } + case Format::R8_SINT: + case Format::R8G8_SINT: + case Format::R8G8B8A8_SINT: + { + generateTextureDataWithTargetTStorage<int8_t>( + output, + desc, + formatInfo, + loadDataIntoInt<int8_t>); + break; + } + default: + { + SLANG_ASSERT(!"Unhandled format"); + break; + } + } +} - const Index maxMipLevels = Math::Log2Floor(output.m_textureSize) + 1; - Index mipLevels = (inputDesc.mipMapCount <= 0) ? maxMipLevels : inputDesc.mipMapCount; - mipLevels = (mipLevels > maxMipLevels) ? maxMipLevels : mipLevels; +template<typename F> +void _iteratePixels(int dimension, int size, unsigned int* buffer, F f) +{ + if (dimension == 1) + for (int i = 0; i < size; i++) + buffer[i] = f(i, 0, 0); + else if (dimension == 2) + for (int i = 0; i < size; i++) + for (int j = 0; j < size; j++) + buffer[i * size + j] = f(j, i, 0); + else if (dimension == 3) + for (int i = 0; i < size; i++) + for (int j = 0; j < size; j++) + for (int k = 0; k < size; k++) + buffer[i * size * size + j * size + k] = f(k, j, i); +}; + +void generateTextureDataRGB8(TextureData& output, const InputTextureDesc& inputDesc) +{ + int arrLen = inputDesc.arrayLength; + if (arrLen == 0) + arrLen = 1; - output.m_mipLevels = int(mipLevels); - output.m_slices.setCount(output.m_mipLevels * output.m_arraySize); + output.init(Format::R8G8B8A8_UNORM); - int slice = 0; - for (int i = 0; i < arraySize; i++) + enum class SimpleScalarType + { + kUint, + kInt, + kFloat, + }; + SimpleScalarType type; + const rhi::FormatInfo& formatInfo = getFormatInfo(inputDesc.format); + switch (formatInfo.channelType) + { + case SLANG_SCALAR_TYPE_UINT64: + case SLANG_SCALAR_TYPE_UINT32: + case SLANG_SCALAR_TYPE_UINT16: + case SLANG_SCALAR_TYPE_UINT8: type = SimpleScalarType::kUint; break; + case SLANG_SCALAR_TYPE_INT64: + case SLANG_SCALAR_TYPE_INT32: + case SLANG_SCALAR_TYPE_INT16: + case SLANG_SCALAR_TYPE_INT8: type = SimpleScalarType::kInt; break; + case SLANG_SCALAR_TYPE_FLOAT64: + case SLANG_SCALAR_TYPE_FLOAT32: + case SLANG_SCALAR_TYPE_FLOAT16: type = SimpleScalarType::kFloat; break; + default: type = SimpleScalarType::kUint; break; + } + // List<List<unsigned int>>& dataBuffer = output.dataBuffer; + int arraySize = arrLen; + if (inputDesc.isCube) + arraySize *= 6; + output.m_arraySize = arraySize; + output.m_textureSize = inputDesc.size; + + const Index maxMipLevels = Math::Log2Floor(output.m_textureSize) + 1; + Index mipLevels = (inputDesc.mipMapCount <= 0) ? maxMipLevels : inputDesc.mipMapCount; + mipLevels = (mipLevels > maxMipLevels) ? maxMipLevels : mipLevels; + + output.m_mipLevels = int(mipLevels); + output.m_slices.setCount(output.m_mipLevels * output.m_arraySize); + + int slice = 0; + for (int i = 0; i < arraySize; i++) + { + for (int j = 0; j < output.m_mipLevels; j++) { - for (int j = 0; j < output.m_mipLevels; j++) - { - int size = output.m_textureSize >> j; - int bufferLen = size; - if (inputDesc.dimension == 2) - bufferLen *= size; - else if (inputDesc.dimension == 3) - bufferLen *= size*size; - - uint32_t* dst = (uint32_t*)output.setSliceCount(slice, bufferLen); - - if (type == SimpleScalarType::kFloat) - _iteratePixels(inputDesc.dimension, size, dst, [&](int x, int y, int z) -> unsigned int + int size = output.m_textureSize >> j; + int bufferLen = size; + if (inputDesc.dimension == 2) + bufferLen *= size; + else if (inputDesc.dimension == 3) + bufferLen *= size * size; + + uint32_t* dst = (uint32_t*)output.setSliceCount(slice, bufferLen); + + if (type == SimpleScalarType::kFloat) + _iteratePixels( + inputDesc.dimension, + size, + dst, + [&](int x, int y, int z) -> unsigned int + { + if (inputDesc.content == InputTextureContent::Zero) { - if (inputDesc.content == InputTextureContent::Zero) - { - return 0x0; - } - else if (inputDesc.content == InputTextureContent::One) - { + return 0x0; + } + else if (inputDesc.content == InputTextureContent::One) + { + return 0xFFFFFFFF; + } + else if (inputDesc.content == InputTextureContent::Gradient) + { + unsigned char r = (unsigned char)(x / (float)(size - 1) * 255.0f); + unsigned char g = (unsigned char)(y / (float)(size - 1) * 255.0f); + unsigned char b = (unsigned char)(z / (float)(size - 1) * 255.0f); + return 0xFF000000 + r + (g << 8) + (b << 16); + } + else if (inputDesc.content == InputTextureContent::ChessBoard) + { + unsigned int xSig = x < (size >> 1) ? 1 : 0; + unsigned int ySig = y < (size >> 1) ? 1 : 0; + unsigned int zSig = z < (size >> 1) ? 1 : 0; + auto sig = xSig ^ ySig ^ zSig; + if (sig) return 0xFFFFFFFF; - } - else if (inputDesc.content == InputTextureContent::Gradient) - { - unsigned char r = (unsigned char)(x / (float)(size - 1) * 255.0f); - unsigned char g = (unsigned char)(y / (float)(size - 1) * 255.0f); - unsigned char b = (unsigned char)(z / (float)(size - 1) * 255.0f); - return 0xFF000000 + r + (g << 8) + (b << 16); - } - else if (inputDesc.content == InputTextureContent::ChessBoard) - { - unsigned int xSig = x < (size >> 1) ? 1 : 0; - unsigned int ySig = y < (size >> 1) ? 1 : 0; - unsigned int zSig = z < (size >> 1) ? 1 : 0; - auto sig = xSig ^ ySig ^ zSig; - if (sig) - return 0xFFFFFFFF; - else - return 0xFF808080; - } + else + return 0xFF808080; + } + return 0x0; + }); + else if (type == SimpleScalarType::kUint || type == SimpleScalarType::kInt) + _iteratePixels( + inputDesc.dimension, + size, + dst, + [&](int x, int y, int z) -> unsigned int + { + if (inputDesc.content == InputTextureContent::Zero) + { return 0x0; - }); - else if (type == SimpleScalarType::kUint || type == SimpleScalarType::kInt) - _iteratePixels(inputDesc.dimension, size, dst, [&](int x, int y, int z) -> unsigned int + } + else if (inputDesc.content == InputTextureContent::One) { - if (inputDesc.content == InputTextureContent::Zero) - { - return 0x0; - } - else if (inputDesc.content == InputTextureContent::One) - { + return 0x01010101; + } + else if (inputDesc.content == InputTextureContent::Gradient) + { + unsigned char r = (unsigned char)(x / (float)(size - 1)); + unsigned char g = (unsigned char)(y / (float)(size - 1)); + unsigned char b = (unsigned char)(z / (float)(size - 1)); + return 0x01000000 + r + (g << 8) + (b << 16); + } + else if (inputDesc.content == InputTextureContent::ChessBoard) + { + unsigned int xSig = x < (size >> 1) ? 1 : 0; + unsigned int ySig = y < (size >> 1) ? 1 : 0; + unsigned int zSig = z < (size >> 1) ? 1 : 0; + auto sig = xSig ^ ySig ^ zSig; + if (sig) return 0x01010101; - } - else if (inputDesc.content == InputTextureContent::Gradient) - { - unsigned char r = (unsigned char)(x / (float)(size - 1)); - unsigned char g = (unsigned char)(y / (float)(size - 1)); - unsigned char b = (unsigned char)(z / (float)(size - 1)); - return 0x01000000 + r + (g << 8) + (b << 16); - } - else if (inputDesc.content == InputTextureContent::ChessBoard) - { - unsigned int xSig = x < (size >> 1) ? 1 : 0; - unsigned int ySig = y < (size >> 1) ? 1 : 0; - unsigned int zSig = z < (size >> 1) ? 1 : 0; - auto sig = xSig ^ ySig ^ zSig; - if (sig) - return 0x01010101; - else - return 0x0; - } - return 0x0; - }); - slice++; - } + else + return 0x0; + } + return 0x0; + }); + slice++; } } } +} // namespace renderer_test diff --git a/tools/render-test/shader-input-layout.h b/tools/render-test/shader-input-layout.h index 9d4b139c8..032e6019d 100644 --- a/tools/render-test/shader-input-layout.h +++ b/tools/render-test/shader-input-layout.h @@ -3,12 +3,12 @@ #include "source/core/slang-basic.h" #include "source/core/slang-random-generator.h" - #include "source/core/slang-writer.h" #include <slang-rhi.h> -namespace renderer_test { +namespace renderer_test +{ using namespace rhi; @@ -28,7 +28,10 @@ enum class ShaderInputType enum class InputTextureContent { - Zero, One, ChessBoard, Gradient + Zero, + One, + ChessBoard, + Gradient }; enum InputTextureSampleCount @@ -49,19 +52,19 @@ struct InputTextureDesc bool isDepthTexture = false; bool isRWTexture = false; int size = 4; - int mipMapCount = 0; ///< 0 means the maximum number of mips will be bound + int mipMapCount = 0; ///< 0 means the maximum number of mips will be bound InputTextureSampleCount sampleCount = InputTextureSampleCount::One; - Format format = Format::R8G8B8A8_UNORM; + Format format = Format::R8G8B8A8_UNORM; InputTextureContent content = InputTextureContent::One; }; enum class InputBufferType { -// ConstantBuffer, + // ConstantBuffer, StorageBuffer, -// RootConstantBuffer, + // RootConstantBuffer, }; struct InputBufferDesc @@ -93,7 +96,7 @@ struct TextureData return slice; } - void* values = nullptr; ///< Values of the type format + void* values = nullptr; ///< Values of the type format size_t valuesCount = 0; }; @@ -111,7 +114,7 @@ struct TextureData return dst; } - /// Set the size of the slice in count of format sized elements + /// Set the size of the slice in count of format sized elements void* setSliceCount(Slang::Index sliceIndex, size_t count) { auto& slice = m_slices[sliceIndex]; @@ -163,7 +166,8 @@ public: public: Val(ShaderInputType kind) : kind(kind) - {} + { + } ShaderInputType kind; bool isOutput = false; @@ -175,7 +179,8 @@ public: public: TextureVal() : Val(ShaderInputType::Texture) - {} + { + } InputTextureDesc textureDesc; }; @@ -185,7 +190,8 @@ public: public: DataValBase(ShaderInputType kind) : Val(kind) - {} + { + } Slang::List<unsigned int> bufferData; }; @@ -195,7 +201,8 @@ public: public: BufferVal() : DataValBase(ShaderInputType::Buffer) - {} + { + } InputBufferDesc bufferDesc; }; @@ -205,7 +212,8 @@ public: public: DataVal() : DataValBase(ShaderInputType::UniformData) - {} + { + } }; class SamplerVal : public Val @@ -213,7 +221,8 @@ public: public: SamplerVal() : Val(ShaderInputType::Sampler) - {} + { + } InputSamplerDesc samplerDesc; }; @@ -223,7 +232,8 @@ public: public: CombinedTextureSamplerVal() : Val(ShaderInputType::CombinedTextureSampler) - {} + { + } Slang::RefPtr<TextureVal> textureVal; Slang::RefPtr<SamplerVal> samplerVal; @@ -234,13 +244,14 @@ public: public: AccelerationStructureVal() : Val(ShaderInputType::AccelerationStructure) - {} + { + } }; struct Field { - Slang::String name; - ValPtr val; + Slang::String name; + ValPtr val; }; typedef Field Entry; @@ -249,7 +260,8 @@ public: public: ParentVal(ShaderInputType kind) : Val(kind) - {} + { + } virtual void addField(Field const& field) = 0; }; @@ -259,7 +271,8 @@ public: public: AggVal(ShaderInputType kind = ShaderInputType::Aggregate) : ParentVal(kind) - {} + { + } Slang::List<Field> fields; @@ -271,7 +284,8 @@ public: public: ObjectVal() : Val(ShaderInputType::Object) - {} + { + } Slang::String typeName; ValPtr contentVal; @@ -284,7 +298,8 @@ public: Slang::List<Slang::String> typeArgs; SpecializeVal() : Val(ShaderInputType::Specialize) - {} + { + } }; class ArrayVal : public ParentVal @@ -292,7 +307,8 @@ public: public: ArrayVal() : ParentVal(ShaderInputType::Array) - {} + { + } Slang::List<ValPtr> vals; @@ -318,14 +334,19 @@ public: void parse(Slang::RandomGenerator* rand, const char* source); - /// Writes a binding, if bindRoot is set, will try to honor the underlying type when outputting. If not will dump as uint32_t hex. - static SlangResult writeBinding(slang::TypeLayoutReflection* typeLayout, const void* data, size_t sizeInBytes, Slang::WriterHelper writer); + /// Writes a binding, if bindRoot is set, will try to honor the underlying type when outputting. + /// If not will dump as uint32_t hex. + static SlangResult writeBinding( + slang::TypeLayoutReflection* typeLayout, + const void* data, + size_t sizeInBytes, + Slang::WriterHelper writer); }; void generateTextureDataRGB8(TextureData& output, const InputTextureDesc& desc); void generateTextureData(TextureData& output, const InputTextureDesc& desc); -} // namespace render_test +} // namespace renderer_test #endif diff --git a/tools/render-test/shader-renderer-util.cpp b/tools/render-test/shader-renderer-util.cpp index 19bbbd2a5..37e5e9e2a 100644 --- a/tools/render-test/shader-renderer-util.cpp +++ b/tools/render-test/shader-renderer-util.cpp @@ -2,7 +2,8 @@ #include "shader-renderer-util.h" -namespace renderer_test { +namespace renderer_test +{ using namespace Slang; using Slang::Result; @@ -27,17 +28,14 @@ inline int calcMaxDimension(Extents size, TextureType type) { switch (type) { - case TextureType::Texture1D: - return size.width; - case TextureType::Texture3D: - return Math::Max(Math::Max(size.width, size.height), size.depth); + case TextureType::Texture1D: return size.width; + case TextureType::Texture3D: return Math::Max(Math::Max(size.width, size.height), size.depth); case TextureType::TextureCube: // fallthru case TextureType::Texture2D: { return Math::Max(size.width, size.height); } - default: - return 0; + default: return 0; } } @@ -69,7 +67,8 @@ inline int calcNumMipLevels(TextureType type, Extents size) TextureDesc textureDesc = {}; // Default to R8G8B8A8_UNORM - const Format format = (inputDesc.format == Format::Unknown) ? Format::R8G8B8A8_UNORM : inputDesc.format; + const Format format = + (inputDesc.format == Format::Unknown) ? Format::R8G8B8A8_UNORM : inputDesc.format; textureDesc.sampleCount = inputDesc.sampleCount; textureDesc.format = format; @@ -78,21 +77,16 @@ inline int calcNumMipLevels(TextureType type, Extents size) textureDesc.usage = TextureUsage::CopyDestination | TextureUsage::CopySource; switch (defaultState) { - case ResourceState::ShaderResource: - textureDesc.usage |= TextureUsage::ShaderResource; - break; - case ResourceState::UnorderedAccess: - textureDesc.usage |= TextureUsage::UnorderedAccess; - break; - default: - return SLANG_FAIL; + case ResourceState::ShaderResource: textureDesc.usage |= TextureUsage::ShaderResource; break; + case ResourceState::UnorderedAccess: textureDesc.usage |= TextureUsage::UnorderedAccess; break; + default: return SLANG_FAIL; } textureDesc.defaultState = defaultState; // It's the same size in all dimensions switch (inputDesc.dimension) { - case 1: + case 1: { textureDesc.type = TextureType::Texture1D; textureDesc.size.width = inputDesc.size; @@ -101,7 +95,7 @@ inline int calcNumMipLevels(TextureType type, Extents size) break; } - case 2: + case 2: { textureDesc.type = inputDesc.isCube ? TextureType::TextureCube : TextureType::Texture2D; textureDesc.size.width = inputDesc.size; @@ -109,7 +103,7 @@ inline int calcNumMipLevels(TextureType type, Extents size) textureDesc.size.depth = 1; break; } - case 3: + case 3: { textureDesc.type = TextureType::Texture3D; textureDesc.size.width = inputDesc.size; @@ -125,11 +119,12 @@ inline int calcNumMipLevels(TextureType type, Extents size) } List<SubresourceData> initSubresources; - int arrayLayerCount = textureDesc.arrayLength * (textureDesc.type == TextureType::TextureCube ? 6 : 1); + int arrayLayerCount = + textureDesc.arrayLength * (textureDesc.type == TextureType::TextureCube ? 6 : 1); int subResourceCounter = 0; - for( int a = 0; a < arrayLayerCount; ++a ) + for (int a = 0; a < arrayLayerCount; ++a) { - for( int m = 0; m < textureDesc.mipLevelCount; ++m ) + for (int m = 0; m < textureDesc.mipLevelCount; ++m) { int subResourceIndex = subResourceCounter++; const int mipWidth = calcMipSize(textureDesc.size.width, m); @@ -163,7 +158,8 @@ inline int calcNumMipLevels(TextureType type, Extents size) bufferDesc.size = bufferSize; bufferDesc.format = inputDesc.format; bufferDesc.elementSize = inputDesc.stride; - bufferDesc.usage = BufferUsage::CopyDestination | BufferUsage::CopySource | BufferUsage::ShaderResource | BufferUsage::UnorderedAccess; + bufferDesc.usage = BufferUsage::CopyDestination | BufferUsage::CopySource | + BufferUsage::ShaderResource | BufferUsage::UnorderedAccess; bufferDesc.defaultState = ResourceState::UnorderedAccess; ComPtr<IBuffer> bufferResource = device->createBuffer(bufferDesc, initData); @@ -187,10 +183,9 @@ static SamplerDesc _calcSamplerDesc(const InputSamplerDesc& srcDesc) return samplerDesc; } -ComPtr<ISampler> _createSampler(IDevice* device, - const InputSamplerDesc& srcDesc) +ComPtr<ISampler> _createSampler(IDevice* device, const InputSamplerDesc& srcDesc) { return device->createSampler(_calcSamplerDesc(srcDesc)); } -} // renderer_test +} // namespace renderer_test diff --git a/tools/render-test/shader-renderer-util.h b/tools/render-test/shader-renderer-util.h index 8d0075f3f..bf0569988 100644 --- a/tools/render-test/shader-renderer-util.h +++ b/tools/render-test/shader-renderer-util.h @@ -1,26 +1,30 @@ // shader-renderer-util.h #pragma once -#include <slang-rhi.h> #include "shader-input-layout.h" -namespace renderer_test { +#include <slang-rhi.h> + +namespace renderer_test +{ using namespace Slang; ComPtr<ISampler> _createSampler(IDevice* device, const InputSamplerDesc& srcDesc); -/// Utility class containing functions that construct items on the renderer using the ShaderInputLayout representation +/// Utility class containing functions that construct items on the renderer using the +/// ShaderInputLayout representation struct ShaderRendererUtil { - /// Generate a texture using the InputTextureDesc and construct a Texture using the Renderer with the contents + /// Generate a texture using the InputTextureDesc and construct a Texture using the Renderer + /// with the contents static Slang::Result generateTexture( const InputTextureDesc& inputDesc, ResourceState defaultState, IDevice* device, ComPtr<ITexture>& textureOut); - /// Create texture resource using inputDesc, and texData to describe format, and contents + /// Create texture resource using inputDesc, and texData to describe format, and contents static Slang::Result createTexture( const InputTextureDesc& inputDesc, const TextureData& texData, @@ -28,7 +32,7 @@ struct ShaderRendererUtil IDevice* device, ComPtr<ITexture>& textureOut); - /// Create the BufferResource using the renderer from the contents of inputDesc + /// Create the BufferResource using the renderer from the contents of inputDesc static Slang::Result createBuffer( const InputBufferDesc& inputDesc, size_t bufferSize, @@ -37,4 +41,4 @@ struct ShaderRendererUtil ComPtr<IBuffer>& bufferOut); }; -} // renderer_test +} // namespace renderer_test diff --git a/tools/render-test/slang-support.cpp b/tools/render-test/slang-support.cpp index 97f163261..924a19104 100644 --- a/tools/render-test/slang-support.cpp +++ b/tools/render-test/slang-support.cpp @@ -4,15 +4,15 @@ #include "slang-support.h" +#include "../../source/core/slang-string-util.h" +#include "../../source/core/slang-test-tool-util.h" #include "options.h" #include <assert.h> #include <stdio.h> -#include "../../source/core/slang-string-util.h" -#include "../../source/core/slang-test-tool-util.h" - -namespace renderer_test { +namespace renderer_test +{ using namespace Slang; // Entry point name to use for vertex/fragment shader @@ -23,8 +23,7 @@ static const char rtEntryPointName[] = "raygenMain"; static const char taskEntryPointName[] = "taskMain"; static const char meshEntryPointName[] = "meshMain"; -void ShaderCompilerUtil::Output::set( - slang::IComponentType* inSlangProgram) +void ShaderCompilerUtil::Output::set(slang::IComponentType* inSlangProgram) { slangProgram = inSlangProgram; desc.slangGlobalScope = inSlangProgram; @@ -41,7 +40,12 @@ void ShaderCompilerUtil::Output::reset() m_extraRequestForReflection = nullptr; } -/* static */ SlangResult ShaderCompilerUtil::_compileProgramImpl(slang::IGlobalSession* globalSession, const Options& options, const Input& input, const ShaderCompileRequest& request, Output& out) +/* static */ SlangResult ShaderCompilerUtil::_compileProgramImpl( + slang::IGlobalSession* globalSession, + const Options& options, + const Input& input, + const ShaderCompileRequest& request, + Output& out) { out.reset(); @@ -72,7 +76,8 @@ void ShaderCompilerUtil::Output::reset() // If there are additional args parse them if (args.getCount()) { - const auto res = slangRequest->processCommandLineArguments(args.getBuffer(), int(args.getCount())); + const auto res = + slangRequest->processCommandLineArguments(args.getBuffer(), int(args.getCount())); // If there is a parse failure and diagnostic, output it if (SLANG_FAILED(res)) { @@ -89,8 +94,11 @@ void ShaderCompilerUtil::Output::reset() if (!hasRepro) { spSetCodeGenTarget(slangRequest, input.target); - if(input.profile.getLength()) // do not set profile unless requested - spSetTargetProfile(slangRequest, 0, spFindProfile(out.session, input.profile.getBuffer())); + if (input.profile.getLength()) // do not set profile unless requested + spSetTargetProfile( + slangRequest, + 0, + spFindProfile(out.session, input.profile.getBuffer())); if (options.generateSPIRVDirectly) spSetTargetFlags(slangRequest, 0, SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY); else @@ -113,9 +121,7 @@ void ShaderCompilerUtil::Output::reset() case SLANG_SOURCE_LANGUAGE_HLSL: spAddPreprocessorDefine(slangRequest, "__HLSL__", "1"); break; - case SLANG_SOURCE_LANGUAGE_C: - spAddPreprocessorDefine(slangRequest, "__C__", "1"); - break; + case SLANG_SOURCE_LANGUAGE_C: spAddPreprocessorDefine(slangRequest, "__C__", "1"); break; case SLANG_SOURCE_LANGUAGE_CPP: spAddPreprocessorDefine(slangRequest, "__CPP__", "1"); break; @@ -126,9 +132,7 @@ void ShaderCompilerUtil::Output::reset() spAddPreprocessorDefine(slangRequest, "__WGSL__", "1"); break; - default: - assert(!"unexpected"); - break; + default: assert(!"unexpected"); break; } if (input.passThrough != SLANG_PASS_THROUGH_NONE) @@ -146,23 +150,35 @@ void ShaderCompilerUtil::Output::reset() int translationUnitIndex = 0; { translationUnitIndex = spAddTranslationUnit(slangRequest, sourceLanguage, nullptr); - spAddTranslationUnitSourceString(slangRequest, translationUnitIndex, request.source.path, request.source.dataBegin); + spAddTranslationUnitSourceString( + slangRequest, + translationUnitIndex, + request.source.path, + request.source.dataBegin); } const int globalSpecializationArgCount = int(request.globalSpecializationArgs.getCount()); for (int ii = 0; ii < globalSpecializationArgCount; ++ii) { - spSetTypeNameForGlobalExistentialTypeParam(slangRequest, ii, request.globalSpecializationArgs[ii].getBuffer()); + spSetTypeNameForGlobalExistentialTypeParam( + slangRequest, + ii, + request.globalSpecializationArgs[ii].getBuffer()); } - const int entryPointSpecializationArgCount = int(request.entryPointSpecializationArgs.getCount()); + const int entryPointSpecializationArgCount = + int(request.entryPointSpecializationArgs.getCount()); auto setEntryPointSpecializationArgs = [&](int entryPoint) + { + for (int ii = 0; ii < entryPointSpecializationArgCount; ++ii) { - for (int ii = 0; ii < entryPointSpecializationArgCount; ++ii) - { - spSetTypeNameForEntryPointExistentialTypeParam(slangRequest, entryPoint, ii, request.entryPointSpecializationArgs[ii].getBuffer()); - } - }; + spSetTypeNameForEntryPointExistentialTypeParam( + slangRequest, + entryPoint, + ii, + request.entryPointSpecializationArgs[ii].getBuffer()); + } + }; Index explicitEntryPointCount = request.entryPoints.getCount(); for (Index ee = 0; ee < explicitEntryPointCount; ++ee) @@ -210,7 +226,7 @@ void ShaderCompilerUtil::Output::reset() ComPtr<slang::IComponentType> linkedSlangProgram; List<ShaderCompileRequest::EntryPoint> actualEntryPoints; - if(input.passThrough == SLANG_PASS_THROUGH_NONE) + if (input.passThrough == SLANG_PASS_THROUGH_NONE) { // In the case where pass-through compilation is not being used, // we can use the Slang reflection information to discover what @@ -218,7 +234,9 @@ void ShaderCompilerUtil::Output::reset() // loading of code. // auto reflection = slang::ProgramLayout::get(slangRequest); - SLANG_RETURN_ON_FAIL(spCompileRequest_getProgramWithEntryPoints(slangRequest, linkedSlangProgram.writeRef())); + SLANG_RETURN_ON_FAIL(spCompileRequest_getProgramWithEntryPoints( + slangRequest, + linkedSlangProgram.writeRef())); // Get the amount of entry points in reflection Index entryPointCount = Index(reflection->getEntryPointCount()); @@ -226,7 +244,7 @@ void ShaderCompilerUtil::Output::reset() // We must have at least one entry point (whether explicit or implicit) SLANG_ASSERT(entryPointCount); - for(Index ee = 0; ee < entryPointCount; ++ee) + for (Index ee = 0; ee < entryPointCount; ++ee) { auto entryPoint = reflection->getEntryPointByIndex(ee); const char* entryPointName = entryPoint->getName(); @@ -281,9 +299,14 @@ void ShaderCompilerUtil::Output::reset() return SLANG_OK; } -/* static */ SlangResult ShaderCompilerUtil::compileProgram(slang::IGlobalSession* globalSession, const Options& options, const Input& input, const ShaderCompileRequest& request, Output& out) +/* static */ SlangResult ShaderCompilerUtil::compileProgram( + slang::IGlobalSession* globalSession, + const Options& options, + const Input& input, + const ShaderCompileRequest& request, + Output& out) { - if( input.passThrough == SLANG_PASS_THROUGH_NONE ) + if (input.passThrough == SLANG_PASS_THROUGH_NONE) { return _compileProgramImpl(globalSession, options, input, request, out); } @@ -293,11 +316,8 @@ void ShaderCompilerUtil::Output::reset() switch (input.passThrough) { case SLANG_PASS_THROUGH_DXC: - case SLANG_PASS_THROUGH_FXC: - canUseSlangForPrecompile = true; - break; - default: - break; + case SLANG_PASS_THROUGH_FXC: canUseSlangForPrecompile = true; break; + default: break; } // If we are doing a HLSL pass-through compilation, then we can't rely // on the downstream compiler for the reflection information that @@ -315,7 +335,8 @@ void ShaderCompilerUtil::Output::reset() // TODO: we want to pass along a flag to skip codegen... - SLANG_RETURN_ON_FAIL(_compileProgramImpl(globalSession, options, slangInput, request, slangOutput)); + SLANG_RETURN_ON_FAIL( + _compileProgramImpl(globalSession, options, slangInput, request, slangOutput)); } // Now we have what we need to be able to do the downstream compile better. @@ -334,7 +355,9 @@ void ShaderCompilerUtil::Output::reset() } } -/* static */SlangResult ShaderCompilerUtil::readSource(const String& inSourcePath, List<char>& outSourceText) +/* static */ SlangResult ShaderCompilerUtil::readSource( + const String& inSourcePath, + List<char>& outSourceText) { // Read in the source code FILE* sourceFile = fopen(inSourcePath.getBuffer(), "rb"); @@ -348,7 +371,7 @@ void ShaderCompilerUtil::Output::reset() fseek(sourceFile, 0, SEEK_SET); outSourceText.setCount(sourceSize + 1); - if(fread(outSourceText.getBuffer(), sourceSize, 1, sourceFile) != 1) + if (fread(outSourceText.getBuffer(), sourceSize, 1, sourceFile) != 1) { fprintf(stderr, "error: failed to read from '%s'\n", inSourcePath.getBuffer()); return SLANG_FAIL; @@ -359,7 +382,7 @@ void ShaderCompilerUtil::Output::reset() return SLANG_OK; } -/* static */SlangResult ShaderCompilerUtil::compileWithLayout( +/* static */ SlangResult ShaderCompilerUtil::compileWithLayout( slang::IGlobalSession* globalSession, const Options& options, const ShaderCompilerUtil::Input& input, @@ -371,7 +394,8 @@ void ShaderCompilerUtil::Output::reset() List<char> sourceText; SLANG_RETURN_ON_FAIL(readSource(sourcePath, sourceText)); - if (input.sourceLanguage == SLANG_SOURCE_LANGUAGE_CPP || input.sourceLanguage == SLANG_SOURCE_LANGUAGE_C) + if (input.sourceLanguage == SLANG_SOURCE_LANGUAGE_CPP || + input.sourceLanguage == SLANG_SOURCE_LANGUAGE_C) { // Add an include of the prelude ComPtr<ISlangBlob> prelude; @@ -379,7 +403,7 @@ void ShaderCompilerUtil::Output::reset() String preludeString = StringUtil::getString(prelude); - // Add the prelude + // Add the prelude StringBuilder builder; builder << preludeString << "\n"; builder << UnownedStringSlice(sourceText.getBuffer(), sourceText.getCount()); @@ -395,14 +419,10 @@ void ShaderCompilerUtil::Output::reset() // Default the amount of renderTargets based on shader type switch (shaderType) { - default: - layout.numRenderTargets = 1; - break; + default: layout.numRenderTargets = 1; break; - case Options::ShaderProgramType::Compute: - case Options::ShaderProgramType::RayTracing: - layout.numRenderTargets = 0; - break; + case Options::ShaderProgramType::Compute: + case Options::ShaderProgramType::RayTracing: layout.numRenderTargets = 0; break; } // Deterministic random generator @@ -429,65 +449,65 @@ void ShaderCompilerUtil::Output::reset() // mechanisms for discovering entry points (e.g., `[shader(...)]` // attributes). // - if( !options.dontAddDefaultEntryPoints ) + if (!options.dontAddDefaultEntryPoints) { - switch(shaderType) + switch (shaderType) { case Options::ShaderProgramType::Graphics: case Options::ShaderProgramType::GraphicsCompute: - { - ShaderCompileRequest::EntryPoint vertexEntryPoint; - vertexEntryPoint.name = vertexEntryPointName; - vertexEntryPoint.slangStage = SLANG_STAGE_VERTEX; - compileRequest.entryPoints.add(vertexEntryPoint); - - ShaderCompileRequest::EntryPoint fragmentEntryPoint; - fragmentEntryPoint.name = fragmentEntryPointName; - fragmentEntryPoint.slangStage = SLANG_STAGE_FRAGMENT; - compileRequest.entryPoints.add(fragmentEntryPoint); - } - break; + { + ShaderCompileRequest::EntryPoint vertexEntryPoint; + vertexEntryPoint.name = vertexEntryPointName; + vertexEntryPoint.slangStage = SLANG_STAGE_VERTEX; + compileRequest.entryPoints.add(vertexEntryPoint); + + ShaderCompileRequest::EntryPoint fragmentEntryPoint; + fragmentEntryPoint.name = fragmentEntryPointName; + fragmentEntryPoint.slangStage = SLANG_STAGE_FRAGMENT; + compileRequest.entryPoints.add(fragmentEntryPoint); + } + break; case Options::ShaderProgramType::GraphicsTaskMeshCompute: - { - ShaderCompileRequest::EntryPoint taskEntryPoint; - taskEntryPoint.name = taskEntryPointName; - taskEntryPoint.slangStage = SLANG_STAGE_AMPLIFICATION; - compileRequest.entryPoints.add(taskEntryPoint); - } - [[fallthrough]]; + { + ShaderCompileRequest::EntryPoint taskEntryPoint; + taskEntryPoint.name = taskEntryPointName; + taskEntryPoint.slangStage = SLANG_STAGE_AMPLIFICATION; + compileRequest.entryPoints.add(taskEntryPoint); + } + [[fallthrough]]; case Options::ShaderProgramType::GraphicsMeshCompute: - { - ShaderCompileRequest::EntryPoint meshEntryPoint; - meshEntryPoint.name = meshEntryPointName; - meshEntryPoint.slangStage = SLANG_STAGE_MESH; - compileRequest.entryPoints.add(meshEntryPoint); - - ShaderCompileRequest::EntryPoint fragmentEntryPoint; - fragmentEntryPoint.name = fragmentEntryPointName; - fragmentEntryPoint.slangStage = SLANG_STAGE_FRAGMENT; - compileRequest.entryPoints.add(fragmentEntryPoint); - } - break; + { + ShaderCompileRequest::EntryPoint meshEntryPoint; + meshEntryPoint.name = meshEntryPointName; + meshEntryPoint.slangStage = SLANG_STAGE_MESH; + compileRequest.entryPoints.add(meshEntryPoint); + + ShaderCompileRequest::EntryPoint fragmentEntryPoint; + fragmentEntryPoint.name = fragmentEntryPointName; + fragmentEntryPoint.slangStage = SLANG_STAGE_FRAGMENT; + compileRequest.entryPoints.add(fragmentEntryPoint); + } + break; case Options::ShaderProgramType::RayTracing: - { - // Note: Current GPU ray tracing pipelines allow for an - // almost arbitrary mix of entry points for different stages - // to be used together (e.g., a single "program" might - // have multiple any-hit shaders, multiple miss shaders, etc.) - // - // Rather than try to define a fixed set of entry point - // names and stages that the testing will support, we will - // instead rely on `[shader(...)]` annotations to tell us - // what entry points are present in the input code. - } - break; + { + // Note: Current GPU ray tracing pipelines allow for an + // almost arbitrary mix of entry points for different stages + // to be used together (e.g., a single "program" might + // have multiple any-hit shaders, multiple miss shaders, etc.) + // + // Rather than try to define a fixed set of entry point + // names and stages that the testing will support, we will + // instead rely on `[shader(...)]` annotations to tell us + // what entry points are present in the input code. + } + break; default: - { - ShaderCompileRequest::EntryPoint computeEntryPoint; - computeEntryPoint.name = computeEntryPointName; - computeEntryPoint.slangStage = SLANG_STAGE_COMPUTE; - compileRequest.entryPoints.add(computeEntryPoint); - } + { + ShaderCompileRequest::EntryPoint computeEntryPoint; + computeEntryPoint.name = computeEntryPointName; + computeEntryPoint.slangStage = SLANG_STAGE_COMPUTE; + compileRequest.entryPoints.add(computeEntryPoint); + } } } compileRequest.globalSpecializationArgs = layout.globalSpecializationArgs; @@ -500,7 +520,12 @@ void ShaderCompilerUtil::Output::reset() c.idOverride = conformance.idOverride; compileRequest.typeConformances.add(c); } - return ShaderCompilerUtil::compileProgram(globalSession, options, input, compileRequest, output.output); + return ShaderCompilerUtil::compileProgram( + globalSession, + options, + input, + compileRequest, + output.output); } -} // renderer_test +} // namespace renderer_test diff --git a/tools/render-test/slang-support.h b/tools/render-test/slang-support.h index c93008999..d52e94b47 100644 --- a/tools/render-test/slang-support.h +++ b/tools/render-test/slang-support.h @@ -1,14 +1,14 @@ // slang-support.h #pragma once -#include <slang-rhi.h> - +#include "options.h" +#include "shader-input-layout.h" #include "slang.h" -#include "shader-input-layout.h" -#include "options.h" +#include <slang-rhi.h> -namespace renderer_test { +namespace renderer_test +{ struct ShaderCompileRequest { @@ -52,36 +52,34 @@ struct ShaderCompilerUtil { struct Input { - SlangCompileTarget target; - SlangSourceLanguage sourceLanguage; - SlangPassThrough passThrough; - Slang::String profile; + SlangCompileTarget target; + SlangSourceLanguage sourceLanguage; + SlangPassThrough passThrough; + Slang::String profile; }; struct Output { - void set( - slang::IComponentType* slangProgram); + void set(slang::IComponentType* slangProgram); void reset(); - ~Output() - { - reset(); - } + ~Output() { reset(); } ComPtr<slang::IComponentType> slangProgram; ShaderProgramDesc desc = {}; - /// Compile request that owns the lifetime of compiled kernel code. + /// Compile request that owns the lifetime of compiled kernel code. ComPtr<SlangCompileRequest> m_requestForKernels = nullptr; - /// Compile request that owns the lifetime of reflection information. + /// Compile request that owns the lifetime of reflection information. ComPtr<SlangCompileRequest> m_extraRequestForReflection = nullptr; SlangCompileRequest* getRequestForKernels() const { return m_requestForKernels; } - SlangCompileRequest* getRequestForReflection() const { return m_extraRequestForReflection ? m_extraRequestForReflection : m_requestForKernels; } + SlangCompileRequest* getRequestForReflection() const + { + return m_extraRequestForReflection ? m_extraRequestForReflection : m_requestForKernels; + } SlangSession* session = nullptr; - }; struct OutputAndLayout @@ -91,13 +89,29 @@ struct ShaderCompilerUtil Slang::String sourcePath; }; - static SlangResult compileWithLayout(slang::IGlobalSession* globalSession, const Options& options, const ShaderCompilerUtil::Input& input, OutputAndLayout& output); - - static SlangResult readSource(const Slang::String& inSourcePath, Slang::List<char>& outSourceText); - - static SlangResult _compileProgramImpl(slang::IGlobalSession* globalSession, const Options& options, const Input& input, const ShaderCompileRequest& request, Output& out); - static SlangResult compileProgram(slang::IGlobalSession* globalSession, const Options& options, const Input& input, const ShaderCompileRequest& request, Output& out); + static SlangResult compileWithLayout( + slang::IGlobalSession* globalSession, + const Options& options, + const ShaderCompilerUtil::Input& input, + OutputAndLayout& output); + + static SlangResult readSource( + const Slang::String& inSourcePath, + Slang::List<char>& outSourceText); + + static SlangResult _compileProgramImpl( + slang::IGlobalSession* globalSession, + const Options& options, + const Input& input, + const ShaderCompileRequest& request, + Output& out); + static SlangResult compileProgram( + slang::IGlobalSession* globalSession, + const Options& options, + const Input& input, + const ShaderCompileRequest& request, + Output& out); }; -} // renderer_test +} // namespace renderer_test |
