diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-10-16 13:12:11 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-10-16 13:12:11 -0700 |
| commit | f12c2552b3f494cbc8245edb90b32b93ca8a1539 (patch) | |
| tree | 4cd08ad6037067dc70844a4a847fb3228e0176ee /tools | |
| parent | 3e3e2473bf85365593629bd1f6f070d11f0b8ab2 (diff) | |
Implement notion of a "container format" (#213)
The big addition here is that the Slang "bytecode" is no longer treated as just a "code generation target" (`CodeGenTarget`) akin to DX bytecode (DXBC) or SPIR-V, but instead is a `ContainerFormat` that can be used to emit all the results of a compile request (well, currently just the IR-as-BC, but the intention is there).
Getting to this goal involved some prior checkins that eliminated bogus "targets" that weren't really akin to SPIR-V or DXBC: `-target slang-ir-asm` and `-target reflection-json`. Those targets were really in place to support testing, and so they've been made more explicit testing/debug options.
This change eliminates `-target slang-ir` and instead tries to allow the user to specify `-o foo.slang-module` as an output file name, that indicates the intention to output a "container" file that will wrap up all the generated code.
I've also gone ahead and generalized the existing `-target` option so that we are actually building up a *list* of code generation targets. This is largely just a cleanup, since it forces code to be more aware of when it is doing something target-specific vs. target independent. For example, reflection layout information lives on a requested target, and not on the compile request as a whole, and similarly output code is per-target, per-entry-point.
As a cleanup, I eliminated support for per-translation-unit output. This was vestigial code from back when I used to try and do HLSL generation for a whole translation unit instead of per-entry-point (which turned out to be a lot of complexity for little gain), and it was only being used in the `hello` example and the `render-test` test fixture - in both cases fixing it up was easy enough. I've stubbed out the old `spGetTranslationUnitSource` API, but haven't removed it yet.
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/eval-test/main.cpp | 10 | ||||
| -rw-r--r-- | tools/render-test/render-d3d11.cpp | 255 | ||||
| -rw-r--r-- | tools/render-test/slang-support.cpp | 16 |
3 files changed, 13 insertions, 268 deletions
diff --git a/tools/eval-test/main.cpp b/tools/eval-test/main.cpp index 9fb6f94a3..486de7bd9 100644 --- a/tools/eval-test/main.cpp +++ b/tools/eval-test/main.cpp @@ -37,9 +37,13 @@ int main( SlangSession* session = spCreateSession(nullptr); SlangCompileRequest* request = spCreateCompileRequest(session); - spSetCodeGenTarget( + spSetCompileFlags( request, - SLANG_IR); + SLANG_COMPILE_FLAG_USE_IR); + + spSetOutputContainerFormat( + request, + SLANG_CONTAINER_FORMAT_SLANG_MODULE); int translationUnitIndex = spAddTranslationUnit( request, @@ -69,7 +73,7 @@ int main( // Extract the bytecode size_t bytecodeSize = 0; - void const* bytecode = spGetEntryPointCode(request, entryPointIndex, &bytecodeSize); + void const* bytecode = spGetCompileRequestCode(request, &bytecodeSize); // Now we need to create an execution context to go and run the bytecode we got diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index dc8f11438..bc86809e6 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -68,261 +68,6 @@ static char const* fragmentProfileName = "ps_4_0"; ID3DBlob* gVertexShaderBlob; ID3DBlob* gPixelShaderBlob; -// Initialization when using HLSL for shaders -HRESULT initializeHLSLInner(ID3D11Device* dxDevice, char const* sourcePath, char const* sourceText) -{ - // Compile the generated HLSL code - gVertexShaderBlob = compileHLSLShader(sourcePath, sourceText, vertexEntryPointName, vertexProfileName); - if(!gVertexShaderBlob) return E_FAIL; - - gPixelShaderBlob = compileHLSLShader(sourcePath, sourceText, fragmentEntryPointName, fragmentProfileName); - if(!gPixelShaderBlob) return E_FAIL; - - - return S_OK; -} - -// Initialization when using HLSL for shaders -HRESULT initializeHLSL(ID3D11Device* dxDevice, char const* sourceText) -{ - HRESULT hr = initializeHLSLInner(dxDevice, gOptions.sourcePath, sourceText); - if(FAILED(hr)) - return hr; - - // TODO: any reflection stuff to do here? - - return S_OK; -} - -// Initialization when using Slang for shaders -HRESULT initializeSlang(ID3D11Device* dxDevice, char const* sourceText) -{ - // - // First, we will load and compile our Slang source code. - // - - // The argument here is an optional directory where the Slang compiler - // can cache files to speed up compilation of many kernels. - SlangSession* slangSession = spCreateSession(NULL); - - // A compile request represents a single invocation of the compiler, - // to process some inputs and produce outputs (or errors). - SlangCompileRequest* slangRequest = spCreateCompileRequest(slangSession); - - // Instruct Slang to generate code as HLSL - spSetCodeGenTarget(slangRequest, SLANG_HLSL); - - int translationUnitIndex = spAddTranslationUnit(slangRequest, SLANG_SOURCE_LANGUAGE_SLANG, nullptr); - - spAddTranslationUnitSourceString(slangRequest, translationUnitIndex, gOptions.sourcePath, sourceText); - - spAddEntryPoint(slangRequest, translationUnitIndex, vertexEntryPointName, spFindProfile(slangSession, vertexProfileName)); - spAddEntryPoint(slangRequest, translationUnitIndex, fragmentEntryPointName, spFindProfile(slangSession, fragmentProfileName)); - - int compileErr = spCompile(slangRequest); - if(auto diagnostics = spGetDiagnosticOutput(slangRequest)) - { - OutputDebugStringA(diagnostics); - fprintf(stderr, "%s", diagnostics); - } - if(compileErr) - { - return E_FAIL; - } - - char const* translatedCode = spGetTranslationUnitSource(slangRequest, translationUnitIndex); - - // Compile the generated HLSL code - HRESULT hr = initializeHLSLInner(dxDevice, "slangGeneratedCode", translatedCode); - if(FAILED(hr)) - return hr; - - // We clean up the Slang compilation context and result *after* - // we have done the HLSL-to-bytecode compilation, because Slang - // owns the memory allocation for the generated HLSL, and will - // free it when we destroy the compilation result. - spDestroyCompileRequest(slangRequest); - spDestroySession(slangSession); - - return S_OK; -} - -#if 0 - -// -// At initialization time, we are going to load and compile our Slang shader -// code, and then create the D3D11 API objects we need for rendering. -// -HRESULT initializeInner( ID3D11Device* dxDevice ) -{ - HRESULT hr = S_OK; - - // Read in the source code - char const* sourcePath = gOptions.sourcePath; - FILE* sourceFile = fopen(sourcePath, "rb"); - if( !sourceFile ) - { - fprintf(stderr, "error: failed to open '%s' for reading\n", sourcePath); - exit(1); - } - fseek(sourceFile, 0, SEEK_END); - size_t sourceSize = ftell(sourceFile); - fseek(sourceFile, 0, SEEK_SET); - char* sourceText = (char*) malloc(sourceSize + 1); - if( !sourceText ) - { - fprintf(stderr, "error: out of memory"); - exit(1); - } - fread(sourceText, sourceSize, 1, sourceFile); - fclose(sourceFile); - sourceText[sourceSize] = 0; - - switch( gOptions.mode ) - { - case Mode::HLSL: - hr = initializeHLSL(dxDevice, sourceText); - break; - - case Mode::Slang: - hr = initializeSlang(dxDevice, sourceText); - break; - - default: - hr = E_FAIL; - break; - } - if( FAILED(hr) ) - { - return hr; - } - - // Do other initialization that doesn't depend on the source language. - - // TODO(tfoley): use each API's reflection interface to query the constant-buffer size needed - gConstantBufferSize = 16 * sizeof(float); - - - D3D11_BUFFER_DESC dxConstantBufferDesc = { 0 }; - dxConstantBufferDesc.ByteWidth = gConstantBufferSize; - dxConstantBufferDesc.Usage = D3D11_USAGE_DYNAMIC; - dxConstantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - dxConstantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - - hr = dxDevice->CreateBuffer( - &dxConstantBufferDesc, - NULL, - &dxConstantBuffer); - if(FAILED(hr)) return hr; - - - // Input Assembler (IA) - - // In Slang-generated HLSL, all vertex shader inputs have a semantic - // like: `A0`, `A1`, `A2`, etc., rather than trying to do by-name - // matching. The user is thus responsibile for ensuring that the - // order of their "input element descs" here matches the order - // in which inputs are declared in the shader code. - D3D11_INPUT_ELEMENT_DESC dxInputElements[] = { - {"A", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, position), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - {"A", 1, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, color), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }; - hr = dxDevice->CreateInputLayout( - &dxInputElements[0], - 2, - gVertexShaderBlob->GetBufferPointer(), - gVertexShaderBlob->GetBufferSize(), - &dxInputLayout); - if(FAILED(hr)) return hr; - - D3D11_BUFFER_DESC dxVertexBufferDesc = { 0 }; - dxVertexBufferDesc.ByteWidth = kVertexCount * sizeof(Vertex); - dxVertexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE; - dxVertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - - D3D11_SUBRESOURCE_DATA dxVertexBufferInitData = { 0 }; - dxVertexBufferInitData.pSysMem = &kVertexData[0]; - - hr = dxDevice->CreateBuffer( - &dxVertexBufferDesc, - &dxVertexBufferInitData, - &dxVertexBuffer); - if(FAILED(hr)) return hr; - - // Vertex Shader (VS) - - hr = dxDevice->CreateVertexShader( - gVertexShaderBlob->GetBufferPointer(), - gVertexShaderBlob->GetBufferSize(), - NULL, - &dxVertexShader); - gVertexShaderBlob->Release(); - if(FAILED(hr)) return hr; - - // Pixel Shader (PS) - - hr = dxDevice->CreatePixelShader( - gPixelShaderBlob->GetBufferPointer(), - gPixelShaderBlob->GetBufferSize(), - NULL, - &dxPixelShader); - gPixelShaderBlob->Release(); - if(FAILED(hr)) return hr; - - return S_OK; -} - -void renderFrameInner(ID3D11DeviceContext* dxContext) -{ - // We update our constant buffer per-frame, just for the purposes - // of the example, but we don't actually load different data - // per-frame (we always use an identity projection). - D3D11_MAPPED_SUBRESOURCE mapped; - HRESULT hr = dxContext->Map(dxConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); - if(!FAILED(hr)) - { - float* data = (float*) mapped.pData; - - static const float kIdentity[] = - { 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 }; - memcpy(data, kIdentity, sizeof(kIdentity)); - - dxContext->Unmap(dxConstantBuffer, 0); - } - - // Input Assembler (IA) - - dxContext->IASetInputLayout(dxInputLayout); - dxContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - - UINT dxVertexStride = sizeof(Vertex); - UINT dxVertexBufferOffset = 0; - dxContext->IASetVertexBuffers(0, 1, &dxVertexBuffer, &dxVertexStride, &dxVertexBufferOffset); - - // Vertex Shader (VS) - - dxContext->VSSetShader(dxVertexShader, NULL, 0); - dxContext->VSSetConstantBuffers(0, 1, &dxConstantBuffer); - - // Pixel Shader (PS) - - dxContext->PSSetShader(dxPixelShader, NULL, 0); - dxContext->VSSetConstantBuffers(0, 1, &dxConstantBuffer); - - // - - dxContext->Draw(3, 0); -} - -void finalize() -{ -} - -#endif - // // Definition of the HLSL-to-bytecode compilation logic. // diff --git a/tools/render-test/slang-support.cpp b/tools/render-test/slang-support.cpp index dbddd9c4f..bf8b7b9c7 100644 --- a/tools/render-test/slang-support.cpp +++ b/tools/render-test/slang-support.cpp @@ -38,6 +38,8 @@ struct SlangShaderCompilerWrapper : public ShaderCompiler int vertexTranslationUnit = 0; int fragmentTranslationUnit = 0; + char const* vertexEntryPointName = request.vertexShader.name; + char const* fragmentEntryPointName = request.fragmentShader.name; if( sourceLanguage == SLANG_SOURCE_LANGUAGE_GLSL ) { // GLSL presents unique challenges because, frankly, it got the whole @@ -48,13 +50,13 @@ struct SlangShaderCompilerWrapper : public ShaderCompiler vertexTranslationUnit = spAddTranslationUnit(slangRequest, sourceLanguage, nullptr); spAddTranslationUnitSourceString(slangRequest, vertexTranslationUnit, request.source.path, request.source.text); - spTranslationUnit_addPreprocessorDefine(slangRequest, vertexTranslationUnit, "__GLSL_VERTEX__", "1"); + vertexEntryPointName = "main"; fragmentTranslationUnit = spAddTranslationUnit(slangRequest, sourceLanguage, nullptr); spAddTranslationUnitSourceString(slangRequest, fragmentTranslationUnit, request.source.path, request.source.text); - spTranslationUnit_addPreprocessorDefine(slangRequest, fragmentTranslationUnit, "__GLSL_FRAGMENT__", "1"); + fragmentEntryPointName = "main"; } else { @@ -72,8 +74,8 @@ struct SlangShaderCompilerWrapper : public ShaderCompiler spSetCompileFlags(slangRequest, SLANG_COMPILE_FLAG_NO_CHECKING); } - int vertexEntryPoint = spAddEntryPoint(slangRequest, vertexTranslationUnit, request.vertexShader.name, spFindProfile(slangSession, request.vertexShader.profile)); - int fragmentEntryPoint = spAddEntryPoint(slangRequest, fragmentTranslationUnit, request.fragmentShader.name, spFindProfile(slangSession, request.fragmentShader.profile)); + int vertexEntryPoint = spAddEntryPoint(slangRequest, vertexTranslationUnit, vertexEntryPointName, spFindProfile(slangSession, request.vertexShader.profile)); + int fragmentEntryPoint = spAddEntryPoint(slangRequest, fragmentTranslationUnit, fragmentEntryPointName, spFindProfile(slangSession, request.fragmentShader.profile)); int compileErr = spCompile(slangRequest); if(auto diagnostics = spGetDiagnosticOutput(slangRequest)) @@ -90,12 +92,6 @@ struct SlangShaderCompilerWrapper : public ShaderCompiler ShaderCompileRequest innerRequest = request; - if( sourceLanguage != SLANG_SOURCE_LANGUAGE_GLSL ) - { - char const* translatedCode = spGetTranslationUnitSource(slangRequest, 0); - innerRequest.source.text = translatedCode; - } - char const* vertexCode = spGetEntryPointSource(slangRequest, vertexEntryPoint); char const* fragmentCode = spGetEntryPointSource(slangRequest, fragmentEntryPoint); |
