From 77562ef82bcbab569ebbbd769957948d825c92ad Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Wed, 13 Jun 2018 15:39:04 -0700 Subject: 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_` profiles to match our `sm_` 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 --- source/slang/compiler.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) (limited to 'source/slang/compiler.cpp') 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 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 -- cgit v1.2.3