summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--premake5.lua6
-rw-r--r--source/slang/compiler.cpp44
-rw-r--r--source/slang/hlsl.meta.slang21
-rw-r--r--source/slang/hlsl.meta.slang.h21
-rw-r--r--source/slang/profile-defs.h13
-rw-r--r--source/slang/slang.vcxproj.filters22
-rw-r--r--tools/copy-hlsl-libs.bat11
-rw-r--r--tools/render-test/d3d-util.cpp4
-rw-r--r--tools/render-test/d3d-util.h4
-rw-r--r--tools/render-test/main.cpp38
-rw-r--r--tools/render-test/options.cpp4
-rw-r--r--tools/render-test/options.h3
-rw-r--r--tools/render-test/render-d3d11.cpp30
-rw-r--r--tools/render-test/render-d3d12.cpp42
-rw-r--r--tools/render-test/render-gl.cpp28
-rw-r--r--tools/render-test/render-test.vcxproj12
-rw-r--r--tools/render-test/render-vk.cpp45
-rw-r--r--tools/render-test/render.h50
-rw-r--r--tools/render-test/slang-support.cpp312
-rw-r--r--tools/render-test/slang-support.h16
20 files changed, 436 insertions, 290 deletions
diff --git a/premake5.lua b/premake5.lua
index 390d67a92..9bb41e71b 100644
--- a/premake5.lua
+++ b/premake5.lua
@@ -366,8 +366,14 @@ tool "render-test"
includedirs { ".", "external", "source" }
links { "core", "slang" }
filter { "system:windows" }
+
systemversion "10.0.14393.0"
+ -- For Windows targets, we want to copy d3dcompiler_47.dll,
+ -- dxcompiler.dll, and dxil.dll from the Windows SDK redistributable
+ -- directory into the output directory.
+ postbuildcommands { '"$(SolutionDir)tools\\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/%{cfg.platform:lower()}/" "%{cfg.targetdir}/"'}
+
--
-- The `slangc` command-line application is just a very thin wrapper
-- around the Slang dynamic library, so its build is extermely simple.
diff --git a/source/slang/compiler.cpp b/source/slang/compiler.cpp
index b7cbc2327..66df01db0 100644
--- a/source/slang/compiler.cpp
+++ b/source/slang/compiler.cpp
@@ -279,13 +279,43 @@ namespace Slang
auto profile = getEffectiveProfile(entryPoint, targetReq);
+ // If we have been invoked in a pass-through mode, then we need to make sure
+ // that the downstream compiler sees whatever options were passed to Slang
+ // via the command line or API.
+ //
+ // TODO: more pieces of information should be added here as needed.
+ //
+ List<D3D_SHADER_MACRO> dxMacrosStorage;
+ D3D_SHADER_MACRO const* dxMacros = nullptr;
+ if( entryPoint->compileRequest->passThrough != PassThroughMode::None )
+ {
+ for( auto& define : entryPoint->compileRequest->preprocessorDefinitions )
+ {
+ D3D_SHADER_MACRO dxMacro;
+ dxMacro.Name = define.Key.Buffer();
+ dxMacro.Definition = define.Value.Buffer();
+ dxMacrosStorage.Add(dxMacro);
+ }
+ for( auto& define : entryPoint->getTranslationUnit()->preprocessorDefinitions )
+ {
+ D3D_SHADER_MACRO dxMacro;
+ dxMacro.Name = define.Key.Buffer();
+ dxMacro.Definition = define.Value.Buffer();
+ dxMacrosStorage.Add(dxMacro);
+ }
+ D3D_SHADER_MACRO nullTerminator = { 0, 0 };
+ dxMacrosStorage.Add(nullTerminator);
+
+ dxMacros = dxMacrosStorage.Buffer();
+ }
+
ID3DBlob* codeBlob;
ID3DBlob* diagnosticsBlob;
HRESULT hr = D3DCompile_(
hlslCode.begin(),
hlslCode.Length(),
"slang",
- nullptr,
+ dxMacros,
nullptr,
getText(entryPoint->name).begin(),
GetHLSLProfileName(profile),
@@ -300,7 +330,17 @@ namespace Slang
data.AddRange((uint8_t const*)codeBlob->GetBufferPointer(), (int)codeBlob->GetBufferSize());
codeBlob->Release();
}
- if (diagnosticsBlob)
+
+ // Note: we will only output diagnostics coming from a downstream
+ // compiler in the event of an error (although in that case we will
+ // end up including any warning diagnostics that are produced as well).
+ //
+ // TODO: some day we should aspire to make Slang's output always compile
+ // cleanly without warnings on downstream compilers (or else suppress those
+ // warnings), but this is difficult to do in practice without a lot of
+ // tailoring for the quirks of each compiler (version).
+ //
+ if (diagnosticsBlob && FAILED(hr))
{
// TODO(tfoley): need a better policy for how we translate diagnostics
// back into the Slang world (although we should always try to generate
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 86f9eb946..10665915d 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -750,6 +750,27 @@ __generic<T : __BuiltinArithmeticType, let R : int, let N : int, let C : int> __
float noise(float x);
__generic<let N : int> float noise(vector<float, N> x);
+/// Indicate that an index may be non-uniform at execution time.
+///
+/// Shader Model 5.1 and 6.x introduce support for dynamic indexing
+/// of arrays of resources, but place the restriction that *by default*
+/// the implementation can assume that any value used as an index into
+/// such arrays will be dynamically uniform across an entire `Draw` or `Dispatch`
+/// (when using instancing, the value must be uniform across all instances;
+/// it does not seem that the restriction extends to draws within a multi-draw).
+///
+/// In order to indicate to the implementation that it cannot make the
+/// uniformity assumption, a shader programmer is required to pass the index
+/// to the `NonUniformResourceIndex` function before using it as an index.
+/// The function superficially acts like an identity function.
+///
+/// Note: a future version of Slang may take responsibility for inserting calls
+/// to this function as necessary in output code, rather than make this
+/// the user's responsibility, so that the default behavior of the language
+/// is more semantically "correct."
+uint NonUniformResourceIndex(uint index);
+int NonUniformResourceIndex(int index);
+
// Normalize a vector
__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> normalize(vector<T,N> x);
diff --git a/source/slang/hlsl.meta.slang.h b/source/slang/hlsl.meta.slang.h
index c05e81cd1..d63f38e47 100644
--- a/source/slang/hlsl.meta.slang.h
+++ b/source/slang/hlsl.meta.slang.h
@@ -783,6 +783,27 @@ SLANG_RAW("// noise (deprecated)\n")
SLANG_RAW("float noise(float x);\n")
SLANG_RAW("__generic<let N : int> float noise(vector<float, N> x);\n")
SLANG_RAW("\n")
+SLANG_RAW("/// Indicate that an index may be non-uniform at execution time.\n")
+SLANG_RAW("///\n")
+SLANG_RAW("/// Shader Model 5.1 and 6.x introduce support for dynamic indexing\n")
+SLANG_RAW("/// of arrays of resources, but place the restriction that *by default*\n")
+SLANG_RAW("/// the implementation can assume that any value used as an index into\n")
+SLANG_RAW("/// such arrays will be dynamically uniform across an entire `Draw` or `Dispatch`\n")
+SLANG_RAW("/// (when using instancing, the value must be uniform across all instances;\n")
+SLANG_RAW("/// it does not seem that the restriction extends to draws within a multi-draw).\n")
+SLANG_RAW("///\n")
+SLANG_RAW("/// In order to indicate to the implementation that it cannot make the\n")
+SLANG_RAW("/// uniformity assumption, a shader programmer is required to pass the index\n")
+SLANG_RAW("/// to the `NonUniformResourceIndex` function before using it as an index.\n")
+SLANG_RAW("/// The function superficially acts like an identity function.\n")
+SLANG_RAW("///\n")
+SLANG_RAW("/// Note: a future version of Slang may take responsibility for inserting calls\n")
+SLANG_RAW("/// to this function as necessary in output code, rather than make this\n")
+SLANG_RAW("/// the user's responsibility, so that the default behavior of the language\n")
+SLANG_RAW("/// is more semantically \"correct.\"\n")
+SLANG_RAW("uint NonUniformResourceIndex(uint index);\n")
+SLANG_RAW("int NonUniformResourceIndex(int index);\n")
+SLANG_RAW("\n")
SLANG_RAW("// Normalize a vector\n")
SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> normalize(vector<T,N> x);\n")
SLANG_RAW("\n")
diff --git a/source/slang/profile-defs.h b/source/slang/profile-defs.h
index 2f029aff0..93703f3b9 100644
--- a/source/slang/profile-defs.h
+++ b/source/slang/profile-defs.h
@@ -205,6 +205,19 @@ PROFILE_ALIAS(DX_None_6_3, DX_Lib_6_3, sm_6_3)
// Define all the GLSL profiles
+PROFILE(GLSL_None_110, glsl_110, Unknown, GLSL_110)
+PROFILE(GLSL_None_120, glsl_120, Unknown, GLSL_120)
+PROFILE(GLSL_None_130, glsl_130, Unknown, GLSL_130)
+PROFILE(GLSL_None_140, glsl_140, Unknown, GLSL_140)
+PROFILE(GLSL_None_150, glsl_150, Unknown, GLSL_150)
+PROFILE(GLSL_None_330, glsl_330, Unknown, GLSL_330)
+PROFILE(GLSL_None_400, glsl_400, Unknown, GLSL_400)
+PROFILE(GLSL_None_410, glsl_410, Unknown, GLSL_410)
+PROFILE(GLSL_None_420, glsl_420, Unknown, GLSL_420)
+PROFILE(GLSL_None_430, glsl_430, Unknown, GLSL_430)
+PROFILE(GLSL_None_440, glsl_440, Unknown, GLSL_440)
+PROFILE(GLSL_None_450, glsl_450, Unknown, GLSL_450)
+
#define P(UPPER, LOWER, VERSION) \
PROFILE(GLSL_##UPPER##_##VERSION, glsl_##LOWER##_##VERSION, UPPER, GLSL_##VERSION)
diff --git a/source/slang/slang.vcxproj.filters b/source/slang/slang.vcxproj.filters
index cb0235e61..f12163f27 100644
--- a/source/slang/slang.vcxproj.filters
+++ b/source/slang/slang.vcxproj.filters
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
@@ -54,6 +54,12 @@
<ClInclude Include="ir-insts.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="ir-restructure-scoping.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ir-restructure.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="ir-ssa.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -153,10 +159,6 @@
<ClInclude Include="vm.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="ir-restructure.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="ir-restructure-scoping.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="bytecode.cpp">
@@ -186,6 +188,12 @@
<ClCompile Include="ir-legalize-types.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="ir-restructure-scoping.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ir-restructure.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="ir-ssa.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -258,10 +266,6 @@
<ClCompile Include="vm.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="ir-restructure.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="ir-restructure-scoping.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="slang.natvis">
diff --git a/tools/copy-hlsl-libs.bat b/tools/copy-hlsl-libs.bat
new file mode 100644
index 000000000..91d5be852
--- /dev/null
+++ b/tools/copy-hlsl-libs.bat
@@ -0,0 +1,11 @@
+@echo off
+setlocal
+
+set SOURCE_DIR=%~1
+set TARGET_DIR=%~2
+
+robocopy "%SOURCE_DIR%" "%TARGET_DIR%" d3dcompiler_47.dll /r:0 >nul
+robocopy "%SOURCE_DIR%" "%TARGET_DIR%" dxcompiler.dll /r:0 >nul
+robocopy "%SOURCE_DIR%" "%TARGET_DIR%" dxil.dll /r:0 >nul
+
+exit /b 0
diff --git a/tools/render-test/d3d-util.cpp b/tools/render-test/d3d-util.cpp
index bef0e6baa..08aa563ca 100644
--- a/tools/render-test/d3d-util.cpp
+++ b/tools/render-test/d3d-util.cpp
@@ -214,6 +214,10 @@ bool D3DUtil::isTypeless(DXGI_FORMAT format)
}
}
+// Note: this subroutine is now only used by D3D11 for generating bytecode to go into input layouts.
+//
+// TODO: we can probably remove that code completely by switching to a PSO-like model across all APIs.
+//
/* static */Result D3DUtil::compileHLSLShader(char const* sourcePath, char const* source, char const* entryPointName, char const* dxProfileName, ComPtr<ID3DBlob>& shaderBlobOut)
{
// Rather than statically link against the `d3dcompile` library, we
diff --git a/tools/render-test/d3d-util.h b/tools/render-test/d3d-util.h
index 6ac39aefb..51eefd151 100644
--- a/tools/render-test/d3d-util.h
+++ b/tools/render-test/d3d-util.h
@@ -36,9 +36,7 @@ class D3DUtil
/// Calculate size taking into account alignment. Alignment must be a power of 2
static UInt calcAligned(UInt size, UInt alignment) { return (size + alignment - 1) & ~(alignment - 1); }
- /// The Slang compiler currently generates HLSL source, so we'll need a utility
- /// routine (defined later) to translate that into D3D11 shader bytecode.
- /// Definition of the HLSL-to-bytecode compilation logic.
+ /// Compile HLSL code to DXBC
static Slang::Result compileHLSLShader(char const* sourcePath, char const* source, char const* entryPointName, char const* dxProfileName, Slang::ComPtr<ID3DBlob>& shaderBlobOut);
/// Given a slang pixel format returns the equivalent DXGI_ pixel format. If the format is not known, will return DXGI_FORMAT_UNKNOWN
diff --git a/tools/render-test/main.cpp b/tools/render-test/main.cpp
index 767c33e14..935b9bc98 100644
--- a/tools/render-test/main.cpp
+++ b/tools/render-test/main.cpp
@@ -96,12 +96,6 @@ static const char vertexEntryPointName[] = "vertexMain";
static const char fragmentEntryPointName[] = "fragmentMain";
static const char computeEntryPointName[] = "computeMain";
-// "Profile" to use when compiling for HLSL targets
-// TODO: does this belong here?
-static const char vertexProfileName[] = "vs_5_0";
-static const char fragmentProfileName[] = "ps_5_0";
-static const char computeProfileName[] = "cs_5_0";
-
SlangResult RenderTestApp::initialize(Renderer* renderer, ShaderCompiler* shaderCompiler)
{
SLANG_RETURN_ON_FAIL(initializeShaders(shaderCompiler));
@@ -201,16 +195,13 @@ Result RenderTestApp::initializeShaders(ShaderCompiler* shaderCompiler)
{
compileRequest.vertexShader.source = sourceInfo;
compileRequest.vertexShader.name = vertexEntryPointName;
- compileRequest.vertexShader.profile = vertexProfileName;
compileRequest.fragmentShader.source = sourceInfo;
compileRequest.fragmentShader.name = fragmentEntryPointName;
- compileRequest.fragmentShader.profile = fragmentProfileName;
}
else
{
compileRequest.computeShader.source = sourceInfo;
compileRequest.computeShader.name = computeEntryPointName;
- compileRequest.computeShader.profile = computeProfileName;
}
compileRequest.entryPointTypeArguments = m_shaderInputLayout.globalTypeArguments;
m_shaderProgram = shaderCompiler->compileProgram(compileRequest);
@@ -412,30 +403,40 @@ SlangResult innerMain(int argc, char** argv)
SlangSourceLanguage nativeLanguage = SLANG_SOURCE_LANGUAGE_UNKNOWN;
SlangCompileTarget slangTarget = SLANG_TARGET_NONE;
+ SlangPassThrough slangPassThrough = SLANG_PASS_THROUGH_NONE;
+ char const* profileName = "";
switch (gOptions.rendererType)
{
case RendererType::DirectX11:
renderer = createD3D11Renderer();
- slangTarget = SLANG_HLSL;
+ slangTarget = SLANG_DXBC;
nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL;
+ slangPassThrough = SLANG_PASS_THROUGH_FXC;
+ profileName = "sm_5_0";
break;
case RendererType::DirectX12:
renderer = createD3D12Renderer();
- slangTarget = SLANG_HLSL;
+ slangTarget = SLANG_DXBC;
nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL;
+ slangPassThrough = SLANG_PASS_THROUGH_FXC;
+ profileName = "sm_5_0";
break;
case RendererType::OpenGl:
renderer = createGLRenderer();
slangTarget = SLANG_GLSL;
nativeLanguage = SLANG_SOURCE_LANGUAGE_GLSL;
+ slangPassThrough = SLANG_PASS_THROUGH_GLSLANG;
+ profileName = "glsl_430";
break;
case RendererType::Vulkan:
renderer = createVKRenderer();
slangTarget = SLANG_SPIRV;
nativeLanguage = SLANG_SOURCE_LANGUAGE_GLSL;
+ slangPassThrough = SLANG_PASS_THROUGH_GLSLANG;
+ profileName = "glsl_430";
break;
default:
@@ -449,15 +450,20 @@ SlangResult innerMain(int argc, char** argv)
SLANG_RETURN_ON_FAIL(renderer->initialize(desc, windowHandle));
- auto shaderCompiler = renderer->getShaderCompiler();
+ ShaderCompiler shaderCompiler;
+ shaderCompiler.renderer = renderer;
+ shaderCompiler.target = slangTarget;
+ shaderCompiler.profile = profileName;
switch (gOptions.inputLanguageID)
{
case Options::InputLanguageID::Slang:
- shaderCompiler = createSlangShaderCompiler(shaderCompiler, SLANG_SOURCE_LANGUAGE_SLANG, slangTarget);
+ shaderCompiler.sourceLanguage = SLANG_SOURCE_LANGUAGE_SLANG;
+ shaderCompiler.passThrough = SLANG_PASS_THROUGH_NONE;
break;
- case Options::InputLanguageID::NativeRewrite:
- shaderCompiler = createSlangShaderCompiler(shaderCompiler, nativeLanguage, slangTarget);
+ case Options::InputLanguageID::Native:
+ shaderCompiler.sourceLanguage = nativeLanguage;
+ shaderCompiler.passThrough = slangPassThrough;
break;
default:
@@ -467,7 +473,7 @@ SlangResult innerMain(int argc, char** argv)
{
RenderTestApp app;
- SLANG_RETURN_ON_FAIL(app.initialize(renderer, shaderCompiler));
+ SLANG_RETURN_ON_FAIL(app.initialize(renderer, &shaderCompiler));
// Once initialization is all complete, we show the window...
ShowWindow(windowHandle, showCommand);
diff --git a/tools/render-test/options.cpp b/tools/render-test/options.cpp
index 1aa72c033..54aa3c429 100644
--- a/tools/render-test/options.cpp
+++ b/tools/render-test/options.cpp
@@ -75,12 +75,12 @@ SlangResult parseOptions(int* argc, char** argv)
else if( strcmp(arg, "-hlsl-rewrite") == 0 )
{
setDefaultRendererType( RendererType::DirectX11);
- gOptions.inputLanguageID = InputLanguageID::NativeRewrite;
+ gOptions.inputLanguageID = InputLanguageID::Slang;
}
else if( strcmp(arg, "-glsl-rewrite") == 0 )
{
setDefaultRendererType(RendererType::OpenGl);
- gOptions.inputLanguageID = InputLanguageID::NativeRewrite;
+ gOptions.inputLanguageID = InputLanguageID::Slang;
}
else if( strcmp(arg, "-slang") == 0 )
{
diff --git a/tools/render-test/options.h b/tools/render-test/options.h
index 630c30d8a..4c0f1098f 100644
--- a/tools/render-test/options.h
+++ b/tools/render-test/options.h
@@ -24,9 +24,6 @@ struct Options
// Raw HLSL or GLSL input, bypassing Slang
Native,
-
- // Raw HLSL or GLSL input, passed through the Slang rewriter
- NativeRewrite
};
diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp
index 0ba2c8dc3..1ca293fad 100644
--- a/tools/render-test/render-d3d11.cpp
+++ b/tools/render-test/render-d3d11.cpp
@@ -42,7 +42,7 @@ using namespace Slang;
namespace renderer_test {
-class D3D11Renderer : public Renderer, public ShaderCompiler
+class D3D11Renderer : public Renderer
{
public:
// Renderer implementation
@@ -55,7 +55,7 @@ public:
virtual SlangResult captureScreenSurface(Surface& surfaceOut) override;
virtual InputLayout* createInputLayout( const InputElementDesc* inputElements, UInt inputElementCount) override;
virtual BindingState* createBindingState(const BindingState::Desc& desc) override;
- virtual ShaderCompiler* getShaderCompiler() override;
+ virtual ShaderProgram* createProgram(const ShaderProgram::Desc& desc) override;
virtual void* map(BufferResource* buffer, MapFlavor flavor) override;
virtual void unmap(BufferResource* buffer) override;
virtual void setInputLayout(InputLayout* inputLayout) override;
@@ -69,9 +69,6 @@ public:
virtual void waitForGpu() override {}
virtual RendererType getRendererType() const override { return RendererType::DirectX11; }
- // ShaderCompiler implementation
- virtual ShaderProgram* compileProgram(ShaderCompileRequest const& request) override;
-
protected:
struct BindingDetail
@@ -380,11 +377,6 @@ SlangResult D3D11Renderer::captureScreenSurface(Surface& surfaceOut)
return captureTextureToSurface(m_device, m_immediateContext, m_renderTargetTextures[0], surfaceOut);
}
-ShaderCompiler* D3D11Renderer::getShaderCompiler()
-{
- return this;
-}
-
static D3D11_BIND_FLAG _calcResourceFlag(Resource::BindFlag::Enum bindFlag)
{
typedef Resource::BindFlag BindFlag;
@@ -784,15 +776,14 @@ void D3D11Renderer::draw(UInt vertexCount, UInt startVertex)
m_immediateContext->Draw((UINT)vertexCount, (UINT)startVertex);
}
-ShaderProgram* D3D11Renderer::compileProgram(const ShaderCompileRequest& request)
+ShaderProgram* D3D11Renderer::createProgram(const ShaderProgram::Desc& desc)
{
- if (request.computeShader.name)
+ if (desc.pipelineType == PipelineType::Compute)
{
- ComPtr<ID3DBlob> computeShaderBlob;
- SLANG_RETURN_NULL_ON_FAIL(D3DUtil::compileHLSLShader(request.computeShader.source.path, request.computeShader.source.dataBegin, request.computeShader.name, request.computeShader.profile, computeShaderBlob));
+ auto computeKernel = desc.findKernel(StageType::Compute);
ComPtr<ID3D11ComputeShader> computeShader;
- SLANG_RETURN_NULL_ON_FAIL(m_device->CreateComputeShader(computeShaderBlob->GetBufferPointer(), computeShaderBlob->GetBufferSize(), nullptr, computeShader.writeRef()));
+ SLANG_RETURN_NULL_ON_FAIL(m_device->CreateComputeShader(computeKernel->codeBegin, computeKernel->getCodeSize(), nullptr, computeShader.writeRef()));
ShaderProgramImpl* shaderProgram = new ShaderProgramImpl();
shaderProgram->m_computeShader.swap(computeShader);
@@ -800,15 +791,14 @@ ShaderProgram* D3D11Renderer::compileProgram(const ShaderCompileRequest& request
}
else
{
- ComPtr<ID3DBlob> vertexShaderBlob, fragmentShaderBlob;
- SLANG_RETURN_NULL_ON_FAIL(D3DUtil::compileHLSLShader(request.vertexShader.source.path, request.vertexShader.source.dataBegin, request.vertexShader.name, request.vertexShader.profile, vertexShaderBlob));
- SLANG_RETURN_NULL_ON_FAIL(D3DUtil::compileHLSLShader(request.fragmentShader.source.path, request.fragmentShader.source.dataBegin, request.fragmentShader.name, request.fragmentShader.profile, fragmentShaderBlob));
+ auto vertexKernel = desc.findKernel(StageType::Vertex);
+ auto fragmentKernel = desc.findKernel(StageType::Fragment);
ComPtr<ID3D11VertexShader> vertexShader;
ComPtr<ID3D11PixelShader> pixelShader;
- SLANG_RETURN_NULL_ON_FAIL(m_device->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, vertexShader.writeRef()));
- SLANG_RETURN_NULL_ON_FAIL(m_device->CreatePixelShader(fragmentShaderBlob->GetBufferPointer(), fragmentShaderBlob->GetBufferSize(), nullptr, pixelShader.writeRef()));
+ SLANG_RETURN_NULL_ON_FAIL(m_device->CreateVertexShader(vertexKernel->codeBegin, vertexKernel->getCodeSize(), nullptr, vertexShader.writeRef()));
+ SLANG_RETURN_NULL_ON_FAIL(m_device->CreatePixelShader(fragmentKernel->codeBegin, fragmentKernel->getCodeSize(), nullptr, pixelShader.writeRef()));
ShaderProgramImpl* shaderProgram = new ShaderProgramImpl();
shaderProgram->m_vertexShader.swap(vertexShader);
diff --git a/tools/render-test/render-d3d12.cpp b/tools/render-test/render-d3d12.cpp
index 430a273ef..593991205 100644
--- a/tools/render-test/render-d3d12.cpp
+++ b/tools/render-test/render-d3d12.cpp
@@ -49,7 +49,7 @@
namespace renderer_test {
using namespace Slang;
-class D3D12Renderer : public Renderer, public ShaderCompiler
+class D3D12Renderer : public Renderer
{
public:
// Renderer implementation
@@ -62,7 +62,7 @@ public:
virtual SlangResult captureScreenSurface(Surface& surfaceOut) override;
virtual InputLayout* createInputLayout(const InputElementDesc* inputElements, UInt inputElementCount) override;
virtual BindingState* createBindingState(const BindingState::Desc& bindingStateDesc) override;
- virtual ShaderCompiler* getShaderCompiler() override;
+ virtual ShaderProgram* createProgram(const ShaderProgram::Desc& desc) override;
virtual void* map(BufferResource* buffer, MapFlavor flavor) override;
virtual void unmap(BufferResource* buffer) override;
virtual void setInputLayout(InputLayout* inputLayout) override;
@@ -76,9 +76,6 @@ public:
virtual void waitForGpu() override;
virtual RendererType getRendererType() const override { return RendererType::DirectX12; }
- // ShaderCompiler implementation
- virtual ShaderProgram* compileProgram(const ShaderCompileRequest& request) override;
-
~D3D12Renderer();
protected:
@@ -1685,11 +1682,6 @@ SlangResult D3D12Renderer::captureScreenSurface(Surface& surfaceOut)
return captureTextureToSurface(*m_renderTargets[m_renderTargetIndex], surfaceOut);
}
-ShaderCompiler* D3D12Renderer::getShaderCompiler()
-{
- return this;
-}
-
static D3D12_RESOURCE_STATES _calcResourceState(Resource::Usage usage)
{
typedef Resource::Usage Usage;
@@ -2343,6 +2335,10 @@ BindingState* D3D12Renderer::createBindingState(const BindingState::Desc& bindin
uavDesc.Buffer.StructureByteStride = 0;
}
+ else if( bufferDesc.format != Format::Unknown )
+ {
+ uavDesc.Buffer.StructureByteStride = 0;
+ }
m_device->CreateUnorderedAccessView(bufferResource->m_resource, nullptr, &uavDesc, bindingState->m_viewHeap.getCpuHandle(dstDetail.m_uavIndex));
}
@@ -2445,29 +2441,23 @@ void D3D12Renderer::setBindingState(BindingState* state)
m_boundBindingState = static_cast<BindingStateImpl*>(state);
}
-// ShaderCompiler interface
-
-ShaderProgram* D3D12Renderer::compileProgram(const ShaderCompileRequest& request)
+ShaderProgram* D3D12Renderer::createProgram(const ShaderProgram::Desc& desc)
{
- RefPtr<ShaderProgramImpl> program(new ShaderProgramImpl);
+ RefPtr<ShaderProgramImpl> program(new ShaderProgramImpl());
+ program->m_pipelineType = desc.pipelineType;
- if (request.computeShader.name)
+ if (desc.pipelineType == PipelineType::Compute)
{
- program->m_pipelineType = PipelineType::Compute;
- ComPtr<ID3DBlob> computeShaderBlob;
- SLANG_RETURN_NULL_ON_FAIL(D3DUtil::compileHLSLShader(request.computeShader.source.path, request.computeShader.source.dataBegin, request.computeShader.name, request.computeShader.profile, computeShaderBlob));
-
- program->m_computeShader.InsertRange(0, (const uint8_t*)computeShaderBlob->GetBufferPointer(), UInt(computeShaderBlob->GetBufferSize()));
+ auto computeKernel = desc.findKernel(StageType::Compute);
+ program->m_computeShader.InsertRange(0, (const uint8_t*) computeKernel->codeBegin, computeKernel->getCodeSize());
}
else
{
- program->m_pipelineType = PipelineType::Graphics;
- ComPtr<ID3DBlob> vertexShaderBlob, fragmentShaderBlob;
- SLANG_RETURN_NULL_ON_FAIL(D3DUtil::compileHLSLShader(request.vertexShader.source.path, request.vertexShader.source.dataBegin, request.vertexShader.name, request.vertexShader.profile, vertexShaderBlob));
- SLANG_RETURN_NULL_ON_FAIL(D3DUtil::compileHLSLShader(request.fragmentShader.source.path, request.fragmentShader.source.dataBegin, request.fragmentShader.name, request.fragmentShader.profile, fragmentShaderBlob));
+ auto vertexKernel = desc.findKernel(StageType::Vertex);
+ auto fragmentKernel = desc.findKernel(StageType::Fragment);
- program->m_vertexShader.InsertRange(0, (const uint8_t*)vertexShaderBlob->GetBufferPointer(), UInt(vertexShaderBlob->GetBufferSize()));
- program->m_pixelShader.InsertRange(0, (const uint8_t*)fragmentShaderBlob->GetBufferPointer(), UInt(fragmentShaderBlob->GetBufferSize()));
+ program->m_vertexShader.InsertRange(0, (const uint8_t*) vertexKernel->codeBegin, vertexKernel->getCodeSize());
+ program->m_pixelShader.InsertRange(0, (const uint8_t*) fragmentKernel->codeBegin, fragmentKernel->getCodeSize());
}
return program.detach();
diff --git a/tools/render-test/render-gl.cpp b/tools/render-test/render-gl.cpp
index 00e4427b8..dc9f0c43a 100644
--- a/tools/render-test/render-gl.cpp
+++ b/tools/render-test/render-gl.cpp
@@ -75,7 +75,7 @@ using namespace Slang;
namespace renderer_test {
-class GLRenderer : public Renderer, public ShaderCompiler
+class GLRenderer : public Renderer
{
public:
@@ -89,7 +89,7 @@ public:
virtual SlangResult captureScreenSurface(Surface& surfaceOut) override;
virtual InputLayout* createInputLayout(const InputElementDesc* inputElements, UInt inputElementCount) override;
virtual BindingState* createBindingState(const BindingState::Desc& bindingStateDesc) override;
- virtual ShaderCompiler* getShaderCompiler() override;
+ virtual ShaderProgram* createProgram(const ShaderProgram::Desc& desc) override;
virtual void* map(BufferResource* buffer, MapFlavor flavor) override;
virtual void unmap(BufferResource* buffer) override;
virtual void setInputLayout(InputLayout* inputLayout) override;
@@ -103,9 +103,6 @@ public:
virtual void waitForGpu() override {}
virtual RendererType getRendererType() const override { return RendererType::OpenGl; }
- // ShaderCompiler implementation
- virtual ShaderProgram* compileProgram(const ShaderCompileRequest& request) override;
-
protected:
enum
{
@@ -592,11 +589,6 @@ SlangResult GLRenderer::captureScreenSurface(Surface& surfaceOut)
return SLANG_OK;
}
-ShaderCompiler* GLRenderer::getShaderCompiler()
-{
- return this;
-}
-
TextureResource* GLRenderer::createTextureResource(Resource::Usage initialUsage, const TextureResource::Desc& descIn, const TextureResource::Data* initData)
{
TextureResource::Desc srcDesc(descIn);
@@ -999,22 +991,24 @@ void GLRenderer::setBindingState(BindingState* stateIn)
}
}
-// ShaderCompiler interface
-
-ShaderProgram* GLRenderer::compileProgram(const ShaderCompileRequest& request)
+ShaderProgram* GLRenderer::createProgram(const ShaderProgram::Desc& desc)
{
auto programID = glCreateProgram();
- if (request.computeShader.name)
+ if(desc.pipelineType == PipelineType::Compute )
{
- auto computeShaderID = loadShader(GL_COMPUTE_SHADER, request.computeShader.source.dataBegin);
+ auto computeKernel = desc.findKernel(StageType::Compute);
+ auto computeShaderID = loadShader(GL_COMPUTE_SHADER, (char const*) computeKernel->codeBegin);
glAttachShader(programID, computeShaderID);
glLinkProgram(programID);
glDeleteShader(computeShaderID);
}
else
{
- auto vertexShaderID = loadShader(GL_VERTEX_SHADER, request.vertexShader.source.dataBegin);
- auto fragmentShaderID = loadShader(GL_FRAGMENT_SHADER, request.fragmentShader.source.dataBegin);
+ auto vertexKernel = desc.findKernel(StageType::Vertex);
+ auto fragmentKernel = desc.findKernel(StageType::Fragment);
+
+ auto vertexShaderID = loadShader(GL_VERTEX_SHADER, (char const*) vertexKernel->codeBegin);
+ auto fragmentShaderID = loadShader(GL_FRAGMENT_SHADER, (char const*) fragmentKernel->codeBegin);
glAttachShader(programID, vertexShaderID);
glAttachShader(programID, fragmentShaderID);
diff --git a/tools/render-test/render-test.vcxproj b/tools/render-test/render-test.vcxproj
index eabb11615..915d0d753 100644
--- a/tools/render-test/render-test.vcxproj
+++ b/tools/render-test/render-test.vcxproj
@@ -108,6 +108,9 @@
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
+ <PostBuildEvent>
+ <Command>"$(SolutionDir)tools\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/x86/" "../../bin/windows-x86/debug/"</Command>
+ </PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
@@ -123,6 +126,9 @@
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
+ <PostBuildEvent>
+ <Command>"$(SolutionDir)tools\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/x64/" "../../bin/windows-x64/debug/"</Command>
+ </PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
@@ -142,6 +148,9 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
+ <PostBuildEvent>
+ <Command>"$(SolutionDir)tools\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/x86/" "../../bin/windows-x86/release/"</Command>
+ </PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
@@ -161,6 +170,9 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
+ <PostBuildEvent>
+ <Command>"$(SolutionDir)tools\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/x64/" "../../bin/windows-x64/release/"</Command>
+ </PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="circular-resource-heap-d3d12.h" />
diff --git a/tools/render-test/render-vk.cpp b/tools/render-test/render-vk.cpp
index 5be1f5684..bbdc2f08c 100644
--- a/tools/render-test/render-vk.cpp
+++ b/tools/render-test/render-vk.cpp
@@ -29,7 +29,7 @@
namespace renderer_test {
using namespace Slang;
-class VKRenderer : public Renderer, public ShaderCompiler
+class VKRenderer : public Renderer
{
public:
enum { kMaxRenderTargets = 8, kMaxAttachments = kMaxRenderTargets + 1 };
@@ -44,7 +44,7 @@ public:
virtual SlangResult captureScreenSurface(Surface& surface) override;
virtual InputLayout* createInputLayout(const InputElementDesc* inputElements, UInt inputElementCount) override;
virtual BindingState* createBindingState(const BindingState::Desc& bindingStateDesc) override;
- virtual ShaderCompiler* getShaderCompiler() override;
+ virtual ShaderProgram* createProgram(const ShaderProgram::Desc& desc) override;
virtual void* map(BufferResource* buffer, MapFlavor flavor) override;
virtual void unmap(BufferResource* buffer) override;
virtual void setInputLayout(InputLayout* inputLayout) override;
@@ -58,9 +58,6 @@ public:
virtual void waitForGpu() override;
virtual RendererType getRendererType() const override { return RendererType::Vulkan; }
- // ShaderCompiler implementation
- virtual ShaderProgram* compileProgram(const ShaderCompileRequest& request) override;
-
/// Dtor
~VKRenderer();
@@ -267,7 +264,10 @@ public:
VkBool32 handleDebugMessage(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject,
size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg);
- VkPipelineShaderStageCreateInfo compileEntryPoint(const ShaderCompileRequest::EntryPoint& entryPointRequest, VkShaderStageFlagBits stage, List<char>& bufferOut);
+ VkPipelineShaderStageCreateInfo compileEntryPoint(
+ ShaderProgram::KernelDesc const& kernelDesc,
+ VkShaderStageFlagBits stage,
+ List<char>& bufferOut);
static VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject,
size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData);
@@ -922,10 +922,13 @@ VkBool32 VKRenderer::handleDebugMessage(VkDebugReportFlagsEXT flags, VkDebugRepo
return ((VKRenderer*)pUserData)->handleDebugMessage(flags, objType, srcObject, location, msgCode, pLayerPrefix, pMsg);
}
-VkPipelineShaderStageCreateInfo VKRenderer::compileEntryPoint(const ShaderCompileRequest::EntryPoint& entryPointRequest, VkShaderStageFlagBits stage, List<char>& bufferOut)
+VkPipelineShaderStageCreateInfo VKRenderer::compileEntryPoint(
+ ShaderProgram::KernelDesc const& kernelDesc,
+ VkShaderStageFlagBits stage,
+ List<char>& bufferOut)
{
- char const* dataBegin = entryPointRequest.source.dataBegin;
- char const* dataEnd = entryPointRequest.source.dataEnd;
+ char const* dataBegin = (char const*) kernelDesc.codeBegin;
+ char const* dataEnd = (char const*) kernelDesc.codeEnd;
// We need to make a copy of the code, since the Slang compiler
// will free the memory after a compile request is closed.
@@ -1192,11 +1195,6 @@ SlangResult VKRenderer::captureScreenSurface(Surface& surfaceOut)
return SLANG_FAIL;
}
-ShaderCompiler* VKRenderer::getShaderCompiler()
-{
- return this;
-}
-
static VkBufferUsageFlagBits _calcBufferUsageFlags(Resource::BindFlag::Enum bind)
{
typedef Resource::BindFlag BindFlag;
@@ -1999,20 +1997,21 @@ void VKRenderer::setBindingState(BindingState* state)
m_currentBindingState = static_cast<BindingStateImpl*>(state);
}
-// ShaderCompiler interface
-ShaderProgram* VKRenderer::compileProgram(const ShaderCompileRequest& request)
+ShaderProgram* VKRenderer::createProgram(const ShaderProgram::Desc& desc)
{
- const PipelineType pipelineType = request.computeShader.name ? PipelineType::Compute : PipelineType::Graphics;
-
- ShaderProgramImpl* impl = new ShaderProgramImpl(pipelineType);
- if (request.computeShader.name)
+ ShaderProgramImpl* impl = new ShaderProgramImpl(desc.pipelineType);
+ if( desc.pipelineType == PipelineType::Compute)
{
- impl->m_compute = compileEntryPoint(request.computeShader, VK_SHADER_STAGE_COMPUTE_BIT, impl->m_buffers[0]);
+ auto computeKernel = desc.findKernel(StageType::Compute);
+ impl->m_compute = compileEntryPoint(*computeKernel, VK_SHADER_STAGE_COMPUTE_BIT, impl->m_buffers[0]);
}
else
{
- impl->m_vertex = compileEntryPoint(request.vertexShader, VK_SHADER_STAGE_VERTEX_BIT, impl->m_buffers[0]);
- impl->m_fragment = compileEntryPoint(request.fragmentShader, VK_SHADER_STAGE_FRAGMENT_BIT, impl->m_buffers[1]);
+ auto vertexKernel = desc.findKernel(StageType::Vertex);
+ auto fragmentKernel = desc.findKernel(StageType::Fragment);
+
+ impl->m_vertex = compileEntryPoint(*vertexKernel, VK_SHADER_STAGE_VERTEX_BIT, impl->m_buffers[0]);
+ impl->m_fragment = compileEntryPoint(*fragmentKernel, VK_SHADER_STAGE_FRAGMENT_BIT, impl->m_buffers[1]);
}
return impl;
}
diff --git a/tools/render-test/render.h b/tools/render-test/render.h
index 807fabf23..2ad736c27 100644
--- a/tools/render-test/render.h
+++ b/tools/render-test/render.h
@@ -32,6 +32,18 @@ enum class PipelineType
CountOf,
};
+enum class StageType
+{
+ Unknown,
+ Vertex,
+ Hull,
+ Domain,
+ Geometry,
+ Fragment,
+ Compute,
+ CountOf,
+};
+
enum class RendererType
{
Unknown,
@@ -63,7 +75,32 @@ enum class BindingStyle
class ShaderProgram: public Slang::RefObject
{
- public:
+public:
+
+ struct KernelDesc
+ {
+ StageType stage;
+ void const* codeBegin;
+ void const* codeEnd;
+
+ UInt getCodeSize() const { return (char const*)codeEnd - (char const*)codeBegin; }
+ };
+
+ struct Desc
+ {
+ PipelineType pipelineType;
+ KernelDesc const* kernels;
+ Int kernelCount;
+
+ /// Find and return the kernel for `stage`, if present.
+ KernelDesc const* findKernel(StageType stage) const
+ {
+ for(Int ii = 0; ii < kernelCount; ++ii)
+ if(kernels[ii].stage == stage)
+ return &kernels[ii];
+ return nullptr;
+ }
+ };
};
struct ShaderCompileRequest
@@ -84,8 +121,6 @@ struct ShaderCompileRequest
struct EntryPoint
{
char const* name = nullptr;
- char const* profile = nullptr;
-
SourceInfo source;
};
@@ -96,12 +131,6 @@ struct ShaderCompileRequest
Slang::List<Slang::String> entryPointTypeArguments;
};
-class ShaderCompiler
-{
-public:
- virtual ShaderProgram* compileProgram(ShaderCompileRequest const& request) = 0;
-};
-
/// Different formats of things like pixels or elements of vertices
/// NOTE! Any change to this type (adding, removing, changing order) - must also be reflected in changes to RendererUtil
enum class Format
@@ -496,7 +525,8 @@ public:
virtual InputLayout* createInputLayout(const InputElementDesc* inputElements, UInt inputElementCount) = 0;
virtual BindingState* createBindingState(const BindingState::Desc& desc) { return nullptr; }
- virtual ShaderCompiler* getShaderCompiler() = 0;
+
+ virtual ShaderProgram* createProgram(const ShaderProgram::Desc& desc) = 0;
virtual void* map(BufferResource* buffer, MapFlavor flavor) = 0;
virtual void unmap(BufferResource* buffer) = 0;
diff --git a/tools/render-test/slang-support.cpp b/tools/render-test/slang-support.cpp
index 342af571c..d69060449 100644
--- a/tools/render-test/slang-support.cpp
+++ b/tools/render-test/slang-support.cpp
@@ -11,167 +11,169 @@
namespace renderer_test {
-struct SlangShaderCompilerWrapper : public ShaderCompiler
+ShaderProgram* ShaderCompiler::compileProgram(
+ ShaderCompileRequest const& request)
{
- ShaderCompiler* innerCompiler;
- SlangCompileTarget target;
- SlangSourceLanguage sourceLanguage;
-
- virtual ShaderProgram* compileProgram(ShaderCompileRequest const& request) override
- {
- SlangSession* slangSession = spCreateSession(NULL);
- SlangCompileRequest* slangRequest = spCreateCompileRequest(slangSession);
-
- spSetCodeGenTarget(slangRequest, target);
-
- // Define a macro so that shader code in a test can detect what language we
- // are nominally working with.
- char const* langDefine = nullptr;
- switch (sourceLanguage)
- {
- case SLANG_SOURCE_LANGUAGE_GLSL: langDefine = "__GLSL__"; break;
- case SLANG_SOURCE_LANGUAGE_HLSL: langDefine = "__HLSL__"; break;
- case SLANG_SOURCE_LANGUAGE_SLANG: langDefine = "__SLANG__"; break;
- default:
- assert(!"unexpected");
- break;
- }
- spAddPreprocessorDefine(slangRequest, langDefine, "1");
-
- // If we are dealing with GLSL input, then we need to set up
- // Slang to pass through to glslang instead of actually running
- // the compiler (this is a workaround to make direct comparisons
- // possible)
- if (sourceLanguage == SLANG_SOURCE_LANGUAGE_GLSL)
+ SlangSession* slangSession = spCreateSession(NULL);
+ SlangCompileRequest* slangRequest = spCreateCompileRequest(slangSession);
+
+ spSetCodeGenTarget(slangRequest, target);
+ spSetTargetProfile(slangRequest, 0,
+ spFindProfile(slangSession, profile));
+
+ // Define a macro so that shader code in a test can detect what language we
+ // are nominally working with.
+ char const* langDefine = nullptr;
+ switch (sourceLanguage)
+ {
+ case SLANG_SOURCE_LANGUAGE_GLSL:
+ spAddPreprocessorDefine(slangRequest, "__GLSL__", "1");
+ break;
+
+ case SLANG_SOURCE_LANGUAGE_SLANG:
+ spAddPreprocessorDefine(slangRequest, "__SLANG__", "1");
+ // fall through
+ case SLANG_SOURCE_LANGUAGE_HLSL:
+ spAddPreprocessorDefine(slangRequest, "__HLSL__", "1");
+ break;
+
+ default:
+ assert(!"unexpected");
+ break;
+ }
+
+ if (passThrough != SLANG_PASS_THROUGH_NONE)
+ {
+ spSetPassThrough(slangRequest, passThrough);
+ }
+
+ // Preocess any additional command-line options specified for Slang using
+ // the `-xslang <arg>` option to `render-test`.
+ spProcessCommandLineArguments(slangRequest, &gOptions.slangArgs[0], gOptions.slangArgCount);
+
+ int computeTranslationUnit = 0;
+ int vertexTranslationUnit = 0;
+ int fragmentTranslationUnit = 0;
+ char const* vertexEntryPointName = request.vertexShader.name;
+ char const* fragmentEntryPointName = request.fragmentShader.name;
+ char const* computeEntryPointName = request.computeShader.name;
+
+ if (sourceLanguage == SLANG_SOURCE_LANGUAGE_GLSL)
+ {
+ // GLSL presents unique challenges because, frankly, it got the whole
+ // compilation model wrong. One aspect of working around this is that
+ // we will compile the same source file multiple times: once per
+ // entry point, and we will have different preprocessor definitions
+ // active in each case.
+
+ vertexTranslationUnit = spAddTranslationUnit(slangRequest, sourceLanguage, nullptr);
+ spAddTranslationUnitSourceString(slangRequest, vertexTranslationUnit, request.source.path, request.source.dataBegin);
+ spTranslationUnit_addPreprocessorDefine(slangRequest, vertexTranslationUnit, "__GLSL_VERTEX__", "1");
+ vertexEntryPointName = "main";
+
+ fragmentTranslationUnit = spAddTranslationUnit(slangRequest, sourceLanguage, nullptr);
+ spAddTranslationUnitSourceString(slangRequest, fragmentTranslationUnit, request.source.path, request.source.dataBegin);
+ spTranslationUnit_addPreprocessorDefine(slangRequest, fragmentTranslationUnit, "__GLSL_FRAGMENT__", "1");
+ fragmentEntryPointName = "main";
+
+ computeTranslationUnit = spAddTranslationUnit(slangRequest, sourceLanguage, nullptr);
+ spAddTranslationUnitSourceString(slangRequest, computeTranslationUnit, request.source.path, request.source.dataBegin);
+ spTranslationUnit_addPreprocessorDefine(slangRequest, computeTranslationUnit, "__GLSL_COMPUTE__", "1");
+ computeEntryPointName = "main";
+ }
+ else
+ {
+ int translationUnit = spAddTranslationUnit(slangRequest, sourceLanguage, nullptr);
+ spAddTranslationUnitSourceString(slangRequest, translationUnit, request.source.path, request.source.dataBegin);
+
+ vertexTranslationUnit = translationUnit;
+ fragmentTranslationUnit = translationUnit;
+ computeTranslationUnit = translationUnit;
+ }
+
+
+ ShaderProgram * result = nullptr;
+ Slang::List<const char*> rawTypeNames;
+ for (auto typeName : request.entryPointTypeArguments)
+ rawTypeNames.Add(typeName.Buffer());
+ if (request.computeShader.name)
+ {
+ int computeEntryPoint = spAddEntryPointEx(slangRequest, computeTranslationUnit,
+ computeEntryPointName,
+ SLANG_STAGE_COMPUTE,
+ (int)rawTypeNames.Count(),
+ rawTypeNames.Buffer());
+
+ spSetLineDirectiveMode(slangRequest, SLANG_LINE_DIRECTIVE_MODE_NONE);
+ int compileErr = spCompile(slangRequest);
+ if (auto diagnostics = spGetDiagnosticOutput(slangRequest))
{
- spSetPassThrough(slangRequest, SLANG_PASS_THROUGH_GLSLANG);
+ fprintf(stderr, "%s", diagnostics);
}
+ if (!compileErr)
+ {
+ size_t codeSize = 0;
+ char const* code = (char const*) spGetEntryPointCode(slangRequest, computeEntryPoint, &codeSize);
+
+ ShaderProgram::KernelDesc kernelDesc;
+ kernelDesc.stage = StageType::Compute;
+ kernelDesc.codeBegin = code;
+ kernelDesc.codeEnd = code + codeSize;
- // Preocess any additional command-line options specified for Slang using
- // the `-xslang <arg>` option to `render-test`.
- spProcessCommandLineArguments(slangRequest, &gOptions.slangArgs[0], gOptions.slangArgCount);
-
- int computeTranslationUnit = 0;
- int vertexTranslationUnit = 0;
- int fragmentTranslationUnit = 0;
- char const* vertexEntryPointName = request.vertexShader.name;
- char const* fragmentEntryPointName = request.fragmentShader.name;
- char const* computeEntryPointName = request.computeShader.name;
-
- if (sourceLanguage == SLANG_SOURCE_LANGUAGE_GLSL)
- {
- // GLSL presents unique challenges because, frankly, it got the whole
- // compilation model wrong. One aspect of working around this is that
- // we will compile the same source file multiple times: once per
- // entry point, and we will have different preprocessor definitions
- // active in each case.
-
- vertexTranslationUnit = spAddTranslationUnit(slangRequest, sourceLanguage, nullptr);
- spAddTranslationUnitSourceString(slangRequest, vertexTranslationUnit, request.source.path, request.source.dataBegin);
- spTranslationUnit_addPreprocessorDefine(slangRequest, vertexTranslationUnit, "__GLSL_VERTEX__", "1");
- vertexEntryPointName = "main";
-
- fragmentTranslationUnit = spAddTranslationUnit(slangRequest, sourceLanguage, nullptr);
- spAddTranslationUnitSourceString(slangRequest, fragmentTranslationUnit, request.source.path, request.source.dataBegin);
- spTranslationUnit_addPreprocessorDefine(slangRequest, fragmentTranslationUnit, "__GLSL_FRAGMENT__", "1");
- fragmentEntryPointName = "main";
-
- computeTranslationUnit = spAddTranslationUnit(slangRequest, sourceLanguage, nullptr);
- spAddTranslationUnitSourceString(slangRequest, computeTranslationUnit, request.source.path, request.source.dataBegin);
- spTranslationUnit_addPreprocessorDefine(slangRequest, computeTranslationUnit, "__GLSL_COMPUTE__", "1");
- computeEntryPointName = "main";
- }
- else
- {
- int translationUnit = spAddTranslationUnit(slangRequest, sourceLanguage, nullptr);
- spAddTranslationUnitSourceString(slangRequest, translationUnit, request.source.path, request.source.dataBegin);
-
- vertexTranslationUnit = translationUnit;
- fragmentTranslationUnit = translationUnit;
- computeTranslationUnit = translationUnit;
- }
-
-
- ShaderProgram * result = nullptr;
- Slang::List<const char*> rawTypeNames;
- for (auto typeName : request.entryPointTypeArguments)
- rawTypeNames.Add(typeName.Buffer());
- if (request.computeShader.name)
- {
- int computeEntryPoint = spAddEntryPointEx(slangRequest, computeTranslationUnit,
- computeEntryPointName,
- spFindProfile(slangSession, request.computeShader.profile),
- (int)rawTypeNames.Count(),
- rawTypeNames.Buffer());
-
- spSetLineDirectiveMode(slangRequest, SLANG_LINE_DIRECTIVE_MODE_NONE);
- int compileErr = spCompile(slangRequest);
- if (auto diagnostics = spGetDiagnosticOutput(slangRequest))
- {
- fprintf(stderr, "%s", diagnostics);
- }
- if (!compileErr)
- {
- ShaderCompileRequest innerRequest = request;
-
- size_t codeSize = 0;
- char const* code = (char const*) spGetEntryPointCode(slangRequest, computeEntryPoint, &codeSize);
- innerRequest.computeShader.source.dataBegin = code;
- innerRequest.computeShader.source.dataEnd = code + codeSize;
- result = innerCompiler->compileProgram(innerRequest);
- }
- }
- else
- {
- int vertexEntryPoint = spAddEntryPointEx(slangRequest, vertexTranslationUnit, vertexEntryPointName, spFindProfile(slangSession, request.vertexShader.profile), (int)rawTypeNames.Count(), rawTypeNames.Buffer());
- int fragmentEntryPoint = spAddEntryPointEx(slangRequest, fragmentTranslationUnit, fragmentEntryPointName, spFindProfile(slangSession, request.fragmentShader.profile), (int)rawTypeNames.Count(), rawTypeNames.Buffer());
-
- int compileErr = spCompile(slangRequest);
- if (auto diagnostics = spGetDiagnosticOutput(slangRequest))
- {
- // TODO(tfoley): re-enable when I get a logging solution in place
- // OutputDebugStringA(diagnostics);
- fprintf(stderr, "%s", diagnostics);
- }
- if (!compileErr)
- {
- ShaderCompileRequest innerRequest = request;
-
- size_t vertexCodeSize = 0;
- char const* vertexCode = (char const*) spGetEntryPointCode(slangRequest, vertexEntryPoint, &vertexCodeSize);
-
- size_t fragmentCodeSize = 0;
- char const* fragmentCode = (char const*) spGetEntryPointCode(slangRequest, fragmentEntryPoint, &fragmentCodeSize);
-
- innerRequest.vertexShader.source.dataBegin = vertexCode;
- innerRequest.vertexShader.source.dataEnd = vertexCode + vertexCodeSize;
-
- innerRequest.fragmentShader.source.dataBegin = fragmentCode;
- innerRequest.fragmentShader.source.dataEnd = fragmentCode + fragmentCodeSize;
-
- result = innerCompiler->compileProgram(innerRequest);
- }
- }
- // We clean up the Slang compilation context and result *after*
- // we have run the downstream compiler, because Slang
- // owns the memory allocation for the generated text, and will
- // free it when we destroy the compilation result.
- spDestroyCompileRequest(slangRequest);
- spDestroySession(slangSession);
-
- return result;
+ ShaderProgram::Desc desc;
+ desc.pipelineType = PipelineType::Compute;
+ desc.kernels = &kernelDesc;
+ desc.kernelCount = 1;
+
+ result = renderer->createProgram(desc);
+ }
}
-};
+ else
+ {
+ int vertexEntryPoint = spAddEntryPointEx(slangRequest, vertexTranslationUnit, vertexEntryPointName, SLANG_STAGE_VERTEX, (int)rawTypeNames.Count(), rawTypeNames.Buffer());
+ int fragmentEntryPoint = spAddEntryPointEx(slangRequest, fragmentTranslationUnit, fragmentEntryPointName, SLANG_STAGE_FRAGMENT, (int)rawTypeNames.Count(), rawTypeNames.Buffer());
-ShaderCompiler* createSlangShaderCompiler(
- ShaderCompiler* innerCompiler,
- SlangSourceLanguage sourceLanguage,
- SlangCompileTarget target)
-{
- auto result = new SlangShaderCompilerWrapper();
- result->innerCompiler = innerCompiler;
- result->sourceLanguage = sourceLanguage;
- result->target = target;
+ int compileErr = spCompile(slangRequest);
+ if (auto diagnostics = spGetDiagnosticOutput(slangRequest))
+ {
+ // TODO(tfoley): re-enable when I get a logging solution in place
+// OutputDebugStringA(diagnostics);
+ fprintf(stderr, "%s", diagnostics);
+ }
+ if (!compileErr)
+ {
+ size_t vertexCodeSize = 0;
+ char const* vertexCode = (char const*) spGetEntryPointCode(slangRequest, vertexEntryPoint, &vertexCodeSize);
+
+ size_t fragmentCodeSize = 0;
+ char const* fragmentCode = (char const*) spGetEntryPointCode(slangRequest, fragmentEntryPoint, &fragmentCodeSize);
+
+ static const int kDescCount = 2;
+
+ ShaderProgram::KernelDesc kernelDescs[kDescCount];
+
+ kernelDescs[0].stage = StageType::Vertex;
+ kernelDescs[0].codeBegin = vertexCode;
+ kernelDescs[0].codeEnd = vertexCode + vertexCodeSize;
+
+ kernelDescs[1].stage = StageType::Fragment;
+ kernelDescs[1].codeBegin = fragmentCode;
+ kernelDescs[1].codeEnd = fragmentCode + fragmentCodeSize;
+
+ ShaderProgram::Desc desc;
+ desc.pipelineType = PipelineType::Graphics;
+ desc.kernels = &kernelDescs[0];
+ desc.kernelCount = kDescCount;
+
+ result = renderer->createProgram(desc);
+ }
+ }
+ // We clean up the Slang compilation context and result *after*
+ // we have run the downstream compiler, because Slang
+ // owns the memory allocation for the generated text, and will
+ // free it when we destroy the compilation result.
+ spDestroyCompileRequest(slangRequest);
+ spDestroySession(slangSession);
return result;
}
diff --git a/tools/render-test/slang-support.h b/tools/render-test/slang-support.h
index c24b0e2e6..8697abcb8 100644
--- a/tools/render-test/slang-support.h
+++ b/tools/render-test/slang-support.h
@@ -9,9 +9,17 @@
namespace renderer_test {
-ShaderCompiler* createSlangShaderCompiler(
- ShaderCompiler* innerCompiler,
- SlangSourceLanguage sourceLanguage,
- SlangCompileTarget target);
+struct ShaderCompiler
+{
+ Renderer* renderer;
+ SlangCompileTarget target;
+ SlangSourceLanguage sourceLanguage;
+ SlangPassThrough passThrough;
+ char const* profile;
+
+ ShaderProgram* compileProgram(
+ ShaderCompileRequest const& request);
+};
+
} // renderer_test