diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2018-06-13 15:39:04 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-06-13 15:39:04 -0700 |
| commit | 77562ef82bcbab569ebbbd769957948d825c92ad (patch) | |
| tree | c948f9ac09a9388b579c5aa011d98e203c3f5546 /tools | |
| parent | a4dd936ce05f4aa1342b4ce98dd0ac8c4272e331 (diff) | |
Make render-test use Slang for all shader compilation (#597)
* Make render-test use Slang for all shader compilation
This streamlines the code for render-test by having all its shader compilation go through the Slang API, so that it doesn't have to deal with custom logic to compile HLSL->DXBC and HLSL->DXIL. We were already leaning on Slang to generate SPIR-V for Vulkan, so this makes all the paths more consistent.
My original plan with this change was to make the D3D12 render path start using DXIL at this point, since the change would make that easy, but it turns out that some aspects of how we handle parameter binding are not compatible with that right now, so it would need to come as a later change.
There's a lot of details here, so I will try to walk through the changes, including the incidental ones:
* Add logic to `premake5.lua` so that we copy the necessary libraries for HLSL shader compilation to our target directory from the Windows SDK. This is necessary so that our tests can actually invoke `dxcompiler.dll`
* Re-run Premake to generate new project files. This moves around a few files that I manually added in previous changes without re-running Premake.
* When invoking `fxc` as a pass-through compiler, be sure to pass along any macros defines via API or command-line. This isn't a strictly required change with how things worked out, but it is a positive one anyway, because it makes `slangc -pass-through fxc` more useful.
* Don't print output from a downstream `fxc` invocation if it produces warnings but no errors. The main reason for this is so that our tests don't fail because of `fxc` warnings on Slang's output (which then don't match the baselines), but it can also be rationalized as not wanting to confuse users with warnings that don't come from the "real" compiler they are using. This probably needs fine-tuning as a policy.
* Add the HLSL `NonUniformResourceIndex` function. This was an oversight because it isn't documented as a builtin on MSDN, and only gets mentioned obliquely when they talk about resource indexing.
* Add `glsl_<version>` profiles to match our `sm_<version>` profiles, so that it is easy for a user to use the profile mechanism to request a specific GLSL version without also specifying a stage name.
* Update the render-test logic so that there is a single `ShaderCompiler` implementation that *always* uses Slang, and get rid of all of the renderer-specific `ShaderCompiler` implementations.
* Update logic in render-test `main.cpp` to select the options to use for the eventual Slang compile based on the choice of renderer and input language. I didn't change the options that render-test exposes, even though they are getting increasingly silly (e.g., `-glsl-rewrite` doesn't use GLSL as its input...).
* Note: the D3D12 renderer will still use fxc, DXBC, and SM 5.0 for now, since trying to update it to switch to dxc, DXIL, and SM 6.0 didn't work well at the time.
* Add a bit of supporting D3D12 code to make sure that we don't allocate a structured buffer when a buffer has a format.
* Make sure to *also* define the `__HLSL__` macro when compiling Slang code, because otherwise a bunch of tests don't work (I'm not clear on how it worked before...).
* fixup: missing file
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/copy-hlsl-libs.bat | 11 | ||||
| -rw-r--r-- | tools/render-test/d3d-util.cpp | 4 | ||||
| -rw-r--r-- | tools/render-test/d3d-util.h | 4 | ||||
| -rw-r--r-- | tools/render-test/main.cpp | 38 | ||||
| -rw-r--r-- | tools/render-test/options.cpp | 4 | ||||
| -rw-r--r-- | tools/render-test/options.h | 3 | ||||
| -rw-r--r-- | tools/render-test/render-d3d11.cpp | 30 | ||||
| -rw-r--r-- | tools/render-test/render-d3d12.cpp | 42 | ||||
| -rw-r--r-- | tools/render-test/render-gl.cpp | 28 | ||||
| -rw-r--r-- | tools/render-test/render-test.vcxproj | 12 | ||||
| -rw-r--r-- | tools/render-test/render-vk.cpp | 45 | ||||
| -rw-r--r-- | tools/render-test/render.h | 50 | ||||
| -rw-r--r-- | tools/render-test/slang-support.cpp | 312 | ||||
| -rw-r--r-- | tools/render-test/slang-support.h | 16 |
14 files changed, 320 insertions, 279 deletions
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 |
