diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2018-03-20 17:14:12 -0400 |
|---|---|---|
| committer | Tim Foley <tfoleyNV@users.noreply.github.com> | 2018-03-20 14:14:12 -0700 |
| commit | 98b8e0c809ceab84cee25389e54f3f37d220d95e (patch) | |
| tree | 7df9954689a6a727c39997c944c86003ce9018c0 /tools/render-test | |
| parent | 72562144254145612c68534c6b7457764c28acf5 (diff) | |
SlangResult and small bug/typos fixes (#448)
* Fixed some small typos in api-users-guide.md
* Fix some small typos in slang-test/main.cpp, render-test/render-d3d11.cpp
* Remove exit() calls from test code. Added Slang::Result, which works in the same way as COM HRESULT.
* FIx bug introduced when moving to Slang::Result - handling E_INVALIDARG on Dx11.
* Fix the testing of feature levels on Dx11 renderer.
* First attempt at README.md for slang-test.
* Tidied up the slang-test README.md file.
* Fix some small typos in tools/slang-test/main.cpp
* Fix spaces -> tabs problems.
Fix some small types.
Diffstat (limited to 'tools/render-test')
| -rw-r--r-- | tools/render-test/main.cpp | 293 | ||||
| -rw-r--r-- | tools/render-test/options.cpp | 13 | ||||
| -rw-r--r-- | tools/render-test/options.h | 11 | ||||
| -rw-r--r-- | tools/render-test/render-d3d11.cpp | 109 | ||||
| -rw-r--r-- | tools/render-test/render-d3d12.cpp | 61 | ||||
| -rw-r--r-- | tools/render-test/render-gl.cpp | 22 | ||||
| -rw-r--r-- | tools/render-test/render-vk.cpp | 50 | ||||
| -rw-r--r-- | tools/render-test/render.h | 6 | ||||
| -rw-r--r-- | tools/render-test/slang-support.cpp | 1 |
9 files changed, 273 insertions, 293 deletions
diff --git a/tools/render-test/main.cpp b/tools/render-test/main.cpp index 3255f4b9b..89aa9a544 100644 --- a/tools/render-test/main.cpp +++ b/tools/render-test/main.cpp @@ -5,7 +5,9 @@ #include "render-d3d11.h" #include "render-gl.h" #include "render-vk.h" + #include "slang-support.h" + #include "shader-input-layout.h" #include <stdio.h> #include <stdlib.h> @@ -22,9 +24,6 @@ namespace renderer_test { -// - - int gWindowWidth = 1024; int gWindowHeight = 768; @@ -71,7 +70,7 @@ static char const* vertexProfileName = "vs_5_0"; static char const* fragmentProfileName = "ps_5_0"; static char const* computeProfileName = "cs_5_0"; -Error initializeShaders( +SlangResult initializeShaders( ShaderCompiler* shaderCompiler) { // Read in the source code @@ -80,7 +79,7 @@ Error initializeShaders( if( !sourceFile ) { fprintf(stderr, "error: failed to open '%s' for reading\n", sourcePath); - exit(1); + return SLANG_FAIL; } fseek(sourceFile, 0, SEEK_END); size_t sourceSize = ftell(sourceFile); @@ -89,7 +88,7 @@ Error initializeShaders( if( !sourceText ) { fprintf(stderr, "error: out of memory"); - exit(1); + return SLANG_FAIL; } fread(sourceText, sourceSize, 1, sourceFile); fclose(sourceFile); @@ -123,23 +122,20 @@ Error initializeShaders( gShaderProgram = shaderCompiler->compileProgram(compileRequest); if( !gShaderProgram ) { - return Error::Unexpected; + return SLANG_FAIL; } - return Error::None; + return SLANG_OK; } // // 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. // -Error initializeInner( +SlangResult initializeInner( Renderer* renderer, ShaderCompiler* shaderCompiler) { - Error err = Error::None; - - err = initializeShaders(shaderCompiler); - if(err != Error::None) return err; + SLANG_RETURN_ON_FAIL(initializeShaders(shaderCompiler)); gBindingState = renderer->createBindingState(gShaderInputLayout); @@ -154,8 +150,8 @@ Error initializeInner( gConstantBuffer = renderer->createBuffer(constantBufferDesc); if(!gConstantBuffer) - return Error::Unexpected; - + return SLANG_FAIL; + // Input Assembler (IA) InputElementDesc inputElements[] = { @@ -166,7 +162,7 @@ Error initializeInner( gInputLayout = renderer->createInputLayout(&inputElements[0], sizeof(inputElements)/sizeof(inputElements[0])); if(!gInputLayout) - return Error::Unexpected; + return SLANG_FAIL; BufferDesc vertexBufferDesc; vertexBufferDesc.size = kVertexCount * sizeof(Vertex); @@ -175,9 +171,9 @@ Error initializeInner( gVertexBuffer = renderer->createBuffer(vertexBufferDesc); if(!gVertexBuffer) - return Error::Unexpected; + return SLANG_FAIL; - return Error::None; + return SLANG_OK; } void renderFrameInner( @@ -248,139 +244,123 @@ static LRESULT CALLBACK windowProc( } -} // renderer_test - - -// - -int main( - int argc, - char** argv) +SlangResult innerMain(int argc, char** argv) { - using namespace renderer_test; - - // Parse command-line options - parseOptions(&argc, argv); - - - // Do initial window-creation stuff here, rather than in the renderer-specific files - - HINSTANCE instance = GetModuleHandleA(0); - int showCommand = SW_SHOW; - - // First we register a window class. - - WNDCLASSEXW windowClassDesc; - windowClassDesc.cbSize = sizeof(windowClassDesc); - windowClassDesc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; - windowClassDesc.lpfnWndProc = &windowProc; - windowClassDesc.cbClsExtra = 0; - windowClassDesc.cbWndExtra = 0; - windowClassDesc.hInstance = instance; - windowClassDesc.hIcon = 0; - windowClassDesc.hCursor = 0; - windowClassDesc.hbrBackground = 0; - windowClassDesc.lpszMenuName = 0; - windowClassDesc.lpszClassName = L"HelloWorld"; - windowClassDesc.hIconSm = 0; - ATOM windowClassAtom = RegisterClassExW(&windowClassDesc); - if(!windowClassAtom) - { - fprintf(stderr, "error: failed to register window class\n"); - return 1; - } + // Parse command-line options + SLANG_RETURN_ON_FAIL(parseOptions(&argc, argv)); + + // Do initial window-creation stuff here, rather than in the renderer-specific files + + HINSTANCE instance = GetModuleHandleA(0); + int showCommand = SW_SHOW; + + // First we register a window class. + + WNDCLASSEXW windowClassDesc; + windowClassDesc.cbSize = sizeof(windowClassDesc); + windowClassDesc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; + windowClassDesc.lpfnWndProc = &windowProc; + windowClassDesc.cbClsExtra = 0; + windowClassDesc.cbWndExtra = 0; + windowClassDesc.hInstance = instance; + windowClassDesc.hIcon = 0; + windowClassDesc.hCursor = 0; + windowClassDesc.hbrBackground = 0; + windowClassDesc.lpszMenuName = 0; + windowClassDesc.lpszClassName = L"HelloWorld"; + windowClassDesc.hIconSm = 0; + ATOM windowClassAtom = RegisterClassExW(&windowClassDesc); + if (!windowClassAtom) + { + fprintf(stderr, "error: failed to register window class\n"); + return SLANG_FAIL; + } - // Next, we create a window using that window class. - - // We will create a borderless window since our screen-capture logic in GL - // seems to get thrown off by having to deal with a window frame. - DWORD windowStyle = WS_POPUP; - DWORD windowExtendedStyle = 0; - - - RECT windowRect = { 0, 0, gWindowWidth, gWindowHeight }; - AdjustWindowRectEx(&windowRect, windowStyle, /*hasMenu=*/false, windowExtendedStyle); - - auto width = windowRect.right - windowRect.left; - auto height = windowRect.bottom - windowRect.top; - - LPWSTR windowName = L"Slang Render Test"; - HWND windowHandle = CreateWindowExW( - windowExtendedStyle, - (LPWSTR)windowClassAtom, - windowName, - windowStyle, - 0, 0, // x, y - width, height, - NULL, // parent - NULL, // menu - instance, - NULL); - if(!windowHandle) - { - fprintf(stderr, "error: failed to create window\n"); - return 1; - } + // Next, we create a window using that window class. + + // We will create a borderless window since our screen-capture logic in GL + // seems to get thrown off by having to deal with a window frame. + DWORD windowStyle = WS_POPUP; + DWORD windowExtendedStyle = 0; + + + RECT windowRect = { 0, 0, gWindowWidth, gWindowHeight }; + AdjustWindowRectEx(&windowRect, windowStyle, /*hasMenu=*/false, windowExtendedStyle); + + auto width = windowRect.right - windowRect.left; + auto height = windowRect.bottom - windowRect.top; + + LPWSTR windowName = L"Slang Render Test"; + HWND windowHandle = CreateWindowExW( + windowExtendedStyle, + (LPWSTR)windowClassAtom, + windowName, + windowStyle, + 0, 0, // x, y + width, height, + NULL, // parent + NULL, // menu + instance, + NULL); + if (!windowHandle) + { + fprintf(stderr, "error: failed to create window\n"); + return SLANG_FAIL; + } - Renderer* renderer = nullptr; - SlangSourceLanguage nativeLanguage = SLANG_SOURCE_LANGUAGE_UNKNOWN; - SlangCompileTarget slangTarget = SLANG_TARGET_NONE; - switch( gOptions.rendererID ) - { - case RendererID::D3D11: - renderer = createD3D11Renderer(); - slangTarget = SLANG_HLSL; - nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL; - break; - - // TODO: `RendererID::D3D12` - - case RendererID::GL: - renderer = createGLRenderer(); - slangTarget = SLANG_GLSL; - nativeLanguage = SLANG_SOURCE_LANGUAGE_GLSL; - break; - - case RendererID::VK: - renderer = createVKRenderer(); - slangTarget = SLANG_SPIRV; - nativeLanguage = SLANG_SOURCE_LANGUAGE_GLSL; - break; - - default: - fprintf(stderr, "error: unexpected\n"); - exit(1); - break; - } + Renderer* renderer = nullptr; + SlangSourceLanguage nativeLanguage = SLANG_SOURCE_LANGUAGE_UNKNOWN; + SlangCompileTarget slangTarget = SLANG_TARGET_NONE; + switch (gOptions.rendererID) + { + case RendererID::D3D11: + renderer = createD3D11Renderer(); + slangTarget = SLANG_HLSL; + nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL; + break; + + // TODO: `RendererID::D3D12` + + case RendererID::GL: + renderer = createGLRenderer(); + slangTarget = SLANG_GLSL; + nativeLanguage = SLANG_SOURCE_LANGUAGE_GLSL; + break; + + case RendererID::VK: + renderer = createVKRenderer(); + slangTarget = SLANG_SPIRV; + nativeLanguage = SLANG_SOURCE_LANGUAGE_GLSL; + break; + + default: + fprintf(stderr, "error: unexpected\n"); + return SLANG_FAIL; + } - renderer->initialize(windowHandle); + SLANG_RETURN_ON_FAIL(renderer->initialize(windowHandle)); - auto shaderCompiler = renderer->getShaderCompiler(); - switch( gOptions.inputLanguageID ) - { - case InputLanguageID::Slang: - shaderCompiler = createSlangShaderCompiler(shaderCompiler, SLANG_SOURCE_LANGUAGE_SLANG, slangTarget); - break; + auto shaderCompiler = renderer->getShaderCompiler(); + switch (gOptions.inputLanguageID) + { + case InputLanguageID::Slang: + shaderCompiler = createSlangShaderCompiler(shaderCompiler, SLANG_SOURCE_LANGUAGE_SLANG, slangTarget); + break; - case InputLanguageID::NativeRewrite: - shaderCompiler = createSlangShaderCompiler(shaderCompiler, nativeLanguage, slangTarget); - break; + case InputLanguageID::NativeRewrite: + shaderCompiler = createSlangShaderCompiler(shaderCompiler, nativeLanguage, slangTarget); + break; - default: - break; - } + default: + break; + } - Error err = initializeInner(renderer, shaderCompiler); - if( err != Error::None ) - { - exit(1); - } + SLANG_RETURN_ON_FAIL(initializeInner(renderer, shaderCompiler)); + // Once initialization is all complete, we show the window... + ShowWindow(windowHandle, showCommand); - // Once initialization is all complete, we show the window... - ShowWindow(windowHandle, showCommand); - // ... and enter the event loop: for (;;) { @@ -391,7 +371,7 @@ int main( { if (message.message == WM_QUIT) { - return (int)message.wParam; + return (int)message.wParam; } TranslateMessage(&message); @@ -399,35 +379,42 @@ int main( } else { - // Whenver we don't have Windows events to process, - // we render a frame. - + // Whenever we don't have Windows events to process, we render a frame. if (gOptions.shaderType == ShaderProgramType::Compute) { runCompute(renderer); } else { - static const float kClearColor[] = { 0.25, 0.25, 0.25, 1.0 }; - renderer->setClearColor(kClearColor); - renderer->clearFrame(); + static const float kClearColor[] = { 0.25, 0.25, 0.25, 1.0 }; + renderer->setClearColor(kClearColor); + renderer->clearFrame(); renderFrameInner(renderer); } // If we are in a mode where output is requested, we need to snapshot the back buffer here if (gOptions.outputPath) { - if (gOptions.shaderType == ShaderProgramType::Compute || gOptions.shaderType == ShaderProgramType::GraphicsCompute) - renderer->serializeOutput(gBindingState, gOptions.outputPath); - else - renderer->captureScreenShot(gOptions.outputPath); - return 0; + if (gOptions.shaderType == ShaderProgramType::Compute || gOptions.shaderType == ShaderProgramType::GraphicsCompute) + renderer->serializeOutput(gBindingState, gOptions.outputPath); + else + SLANG_RETURN_ON_FAIL(renderer->captureScreenShot(gOptions.outputPath)); + return SLANG_OK; } renderer->presentFrame(); } } - return 0; + return SLANG_OK; +} + +} // renderer_test + +int main(int argc, char** argv) +{ + SlangResult res = renderer_test::innerMain(argc, argv); + + return SLANG_FAILED(res) ? 1 : 0; } diff --git a/tools/render-test/options.cpp b/tools/render-test/options.cpp index 45a94e137..30aeca6b0 100644 --- a/tools/render-test/options.cpp +++ b/tools/render-test/options.cpp @@ -10,7 +10,7 @@ namespace renderer_test { Options gOptions; -void parseOptions(int* argc, char** argv) +SlangResult parseOptions(int* argc, char** argv) { int argCount = *argc; char const* const* argCursor = argv; @@ -48,7 +48,7 @@ void parseOptions(int* argc, char** argv) if( argCursor == argEnd ) { fprintf(stderr, "expected argument for '%s' option\n", arg); - exit(1); + return SLANG_FAIL; } gOptions.outputPath = *argCursor++; } @@ -89,12 +89,12 @@ void parseOptions(int* argc, char** argv) if( argCursor == argEnd ) { fprintf(stderr, "expected argument for '%s' option\n", arg); - exit(1); + return SLANG_FAIL; } if( gOptions.slangArgCount == kMaxSlangArgs ) { fprintf(stderr, "maximum number of '%s' options exceeded (%d)\n", arg, kMaxSlangArgs); - exit(1); + return SLANG_FAIL; } gOptions.slangArgs[gOptions.slangArgCount++] = *argCursor++; } @@ -123,7 +123,7 @@ void parseOptions(int* argc, char** argv) else { fprintf(stderr, "unknown option '%s'\n", arg); - exit(1); + return SLANG_FAIL; } } @@ -142,10 +142,11 @@ void parseOptions(int* argc, char** argv) if(argCursor != argEnd) { fprintf(stderr, "unexpected arguments\n"); - exit(1); + return SLANG_FAIL; } *argc = 0; + return SLANG_OK; } } // renderer_test diff --git a/tools/render-test/options.h b/tools/render-test/options.h index b48295878..a33172c6b 100644 --- a/tools/render-test/options.h +++ b/tools/render-test/options.h @@ -3,6 +3,8 @@ #include <stdint.h> +#include "../../source/core/slang-result.h" + namespace renderer_test { typedef intptr_t Int; @@ -61,13 +63,6 @@ extern int gWindowWidth; extern int gWindowHeight; -void parseOptions(int* argc, char** argv); - -enum class Error -{ - None = 0, - InvalidParam, - Unexpected, -}; +SlangResult parseOptions(int* argc, char** argv); } // renderer_test diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index 690e6299f..ba8d9e46d 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -111,14 +111,14 @@ ID3DBlob* compileHLSLShader( if(!d3dcompiler) { fprintf(stderr, "error: failed load 'd3dcompiler_47.dll'\n"); - exit(1); + return nullptr; } D3DCompile_ = (pD3DCompile)GetProcAddress(d3dcompiler, "D3DCompile"); if( !D3DCompile_ ) { fprintf(stderr, "error: failed load symbol 'D3DCompile'\n"); - exit(1); + return nullptr; } } @@ -193,7 +193,7 @@ static HRESULT captureTextureToFile( D3D11_TEXTURE2D_DESC dxTextureDesc; dxTexture->GetDesc(&dxTextureDesc); - // Don't bother supporing MSAA for right now + // Don't bother supporting MSAA for right now if( dxTextureDesc.SampleDesc.Count > 1 ) { fprintf(stderr, "ERROR: cannot capture multisample texture\n"); @@ -261,14 +261,14 @@ static HRESULT captureTextureToFile( class D3D11Renderer : public Renderer, public ShaderCompiler { public: - IDXGISwapChain* dxSwapChain = NULL; - ID3D11Device* dxDevice = NULL; - ID3D11DeviceContext* dxImmediateContext = NULL; - ID3D11Texture2D* dxBackBufferTexture = NULL; + IDXGISwapChain* dxSwapChain = nullptr; + ID3D11Device* dxDevice = nullptr; + ID3D11DeviceContext* dxImmediateContext = nullptr; + ID3D11Texture2D* dxBackBufferTexture = nullptr; List<ID3D11RenderTargetView*> dxRenderTargetViews; List<ID3D11Texture2D *> dxRenderTargetTextures; D3DBindingState * currentBindings = nullptr; - virtual void initialize(void* inWindowHandle) override + virtual SlangResult initialize(void* inWindowHandle) override { auto windowHandle = (HWND) inWindowHandle; // Rather than statically link against D3D, we load it dynamically. @@ -277,18 +277,16 @@ public: if(!d3d11) { fprintf(stderr, "error: failed load 'd3d11.dll'\n"); - exit(1); + return SLANG_FAIL; } PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN D3D11CreateDeviceAndSwapChain_ = - (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress( - d3d11, - "D3D11CreateDeviceAndSwapChain"); + (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress(d3d11, "D3D11CreateDeviceAndSwapChain"); if(!D3D11CreateDeviceAndSwapChain_) { fprintf(stderr, "error: failed load symbol 'D3D11CreateDeviceAndSwapChain'\n"); - exit(1); + return SLANG_FAIL; } // We create our device in debug mode, just so that we can check that the @@ -296,19 +294,7 @@ public: UINT deviceFlags = 0; deviceFlags |= D3D11_CREATE_DEVICE_DEBUG; - // We will ask for the highest feature level that can be supported. - - D3D_FEATURE_LEVEL featureLevels[] = { - D3D_FEATURE_LEVEL_11_1, - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, - D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, - D3D_FEATURE_LEVEL_9_1, - }; - D3D_FEATURE_LEVEL dxFeatureLevel = D3D_FEATURE_LEVEL_9_1; - + // Our swap chain uses RGBA8 with sRGB, with double buffering. DXGI_SWAP_CHAIN_DESC dxSwapChainDesc = { 0 }; @@ -328,6 +314,19 @@ public: dxSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; dxSwapChainDesc.Flags = 0; + // We will ask for the highest feature level that can be supported. + D3D_FEATURE_LEVEL featureLevels[] = { + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_1, + }; + D3D_FEATURE_LEVEL dxFeatureLevel = D3D_FEATURE_LEVEL_9_1; + const int totalNumFeatureLevels = sizeof(featureLevels) / sizeof(featureLevels[0]); + // On a machine that does not have an up-to-date version of D3D installed, // the `D3D11CreateDeviceAndSwapChain` call will fail with `E_INVALIDARG` // if you ask for featuer level 11_1. The workaround is to call @@ -335,17 +334,16 @@ public: // at the start of the list of requested feature levels, and the second // time without it. - HRESULT hr = S_OK; for( int ii = 0; ii < 2; ++ii ) { - hr = D3D11CreateDeviceAndSwapChain_( + const HRESULT hr = D3D11CreateDeviceAndSwapChain_( NULL, // adapter (use default) D3D_DRIVER_TYPE_REFERENCE, //D3D_DRIVER_TYPE_HARDWARE, NULL, // software deviceFlags, &featureLevels[ii], - (sizeof(featureLevels) / sizeof(featureLevels[0])) - 1, + totalNumFeatureLevels - ii, D3D11_SDK_VERSION, &dxSwapChainDesc, &dxSwapChain, @@ -353,16 +351,19 @@ public: &dxFeatureLevel, &dxImmediateContext); - // Failures with `E_INVALIDARG` might be due to feature level 11_1 - // not being supported. Other failures are real, though. - if( hr != E_INVALIDARG ) - break; - } - if( FAILED(hr) ) - { - exit(1); + // Failures with `E_INVALIDARG` might be due to feature level 11_1 + // not being supported. + if (hr == E_INVALIDARG) + { + continue; + } + + // Other failures are real, though. + SLANG_RETURN_ON_FAIL(hr); + // We must have a swap chain + break; } - + // After we've created the swap chain, we can request a pointer to the // back buffer as a D3D11 texture, and create a render-target view from it. @@ -370,35 +371,28 @@ public: 0x6f15aaf2, 0xd208, 0x4e89, 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c }; - dxSwapChain->GetBuffer( - 0, - kIID_ID3D11Texture2D, - (void**)&dxBackBufferTexture); + SLANG_RETURN_ON_FAIL(dxSwapChain->GetBuffer(0, kIID_ID3D11Texture2D, (void**)&dxBackBufferTexture)); for (int i = 0; i < 8; i++) { ID3D11Texture2D* texture; D3D11_TEXTURE2D_DESC textureDesc; dxBackBufferTexture->GetDesc(&textureDesc); - dxDevice->CreateTexture2D(&textureDesc, nullptr, &texture); + SLANG_RETURN_ON_FAIL(dxDevice->CreateTexture2D(&textureDesc, nullptr, &texture)); + ID3D11RenderTargetView * rtv; D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; rtvDesc.Texture2D.MipSlice = 0; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - dxDevice->CreateRenderTargetView( - texture, - &rtvDesc, - &rtv); + SLANG_RETURN_ON_FAIL(dxDevice->CreateRenderTargetView(texture, &rtvDesc, &rtv)); + dxRenderTargetViews.Add(rtv); dxRenderTargetTextures.Add(texture); } - dxImmediateContext->OMSetRenderTargets( - (UINT)dxRenderTargetViews.Count(), - dxRenderTargetViews.Buffer(), - NULL); - + dxImmediateContext->OMSetRenderTargets((UINT)dxRenderTargetViews.Count(), dxRenderTargetViews.Buffer(), nullptr); + // Similarly, we are going to set up a viewport once, and then never // switch, since this is a simple test app. D3D11_VIEWPORT dxViewport; @@ -409,6 +403,8 @@ public: dxViewport.MaxDepth = 1; // TODO(tfoley): use reversed depth dxViewport.MinDepth = 0; dxImmediateContext->RSSetViewports(1, &dxViewport); + + return SLANG_OK; } float clearColor[4] = { 0, 0, 0, 0 }; @@ -431,7 +427,7 @@ public: dxSwapChain->Present(0, 0); } - virtual void captureScreenShot(char const* outputPath) override + virtual SlangResult captureScreenShot(char const* outputPath) override { HRESULT hr = captureTextureToFile( dxDevice, @@ -441,8 +437,9 @@ public: if( FAILED(hr) ) { fprintf(stderr, "error: could not capture screenshot to '%s'\n", outputPath); - exit(1); - } + SLANG_RETURN_ON_FAIL(hr); + } + return SLANG_OK; } virtual ShaderCompiler* getShaderCompiler() override @@ -535,7 +532,7 @@ public: hlslCursor+= sprintf(hlslCursor, ",\n"); } - char const* typeName = "Uknown"; + char const* typeName = "Unknown"; switch(inputElements[ii].format) { case Format::RGB_Float32: diff --git a/tools/render-test/render-d3d12.cpp b/tools/render-test/render-d3d12.cpp index 2308c601a..f0b0eb478 100644 --- a/tools/render-test/render-d3d12.cpp +++ b/tools/render-test/render-d3d12.cpp @@ -39,6 +39,7 @@ namespace renderer_test { // The Slang compiler currently generates HLSL source, so we'll need a utility // routine (defined later) to translate that into D3D11 shader bytecode. +// Returns nullptr if compilation fails. ID3DBlob* compileHLSLShader( char const* sourcePath, char const* source, @@ -53,9 +54,9 @@ static char const* fragmentProfileName = "ps_4_0"; class D3D12Renderer : public Renderer, public ShaderCompiler { public: - IDXGISwapChain* dxSwapChain = NULL; + IDXGISwapChain* dxSwapChain = nullptr; - ID3D12Device* dxDevice = NULL; + ID3D12Device* dxDevice = nullptr; virtual PROC loadProc( HMODULE module, @@ -66,17 +67,12 @@ public: { fprintf(stderr, "error: failed load symbol '%s'\n", name); - exit(1); + return nullptr; } return proc; } - void checkResult(HRESULT result) - { - assert(SUCCEEDED(result)); - } - - virtual void initialize(void* inWindowHandle) override + virtual SlangResult initialize(void* inWindowHandle) override { auto windowHandle = (HWND) inWindowHandle; // Rather than statically link against D3D, we load it dynamically. @@ -85,12 +81,12 @@ public: if(!d3d12) { fprintf(stderr, "error: failed load 'd3d12.dll'\n"); - exit(1); + return SLANG_FAIL; } #define LOAD_PROC(TYPE, NAME) \ - TYPE NAME##_ = (TYPE) loadProc(d3d12, #NAME) - + TYPE NAME##_ = (TYPE) loadProc(d3d12, #NAME); \ + if (NAME##_ == nullptr) return SLANG_FAIL; UINT dxgiFactoryFlags = 0; @@ -107,11 +103,10 @@ public: typedef HRESULT (WINAPI *PFN_DXGI_CREATE_FACTORY_2)(UINT Flags, REFIID riid, _COM_Outptr_ void **ppFactory); - LOAD_PROC(PFN_DXGI_CREATE_FACTORY_2, CreateDXGIFactory2); IDXGIFactory4* dxgiFactory; - checkResult(CreateDXGIFactory2_(dxgiFactoryFlags, IID_PPV_ARGS(&dxgiFactory))); + SLANG_RETURN_ON_FAIL(CreateDXGIFactory2_(dxgiFactoryFlags, IID_PPV_ARGS(&dxgiFactory))); D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0; @@ -135,8 +130,7 @@ public: { // TODO: may want to allow software driver as fallback } - else if( SUCCEEDED(D3D12CreateDevice_( - candidateAdapter, featureLevel, IID_PPV_ARGS(&dxDevice))) ) + else if( SUCCEEDED(D3D12CreateDevice_(candidateAdapter, featureLevel, IID_PPV_ARGS(&dxDevice))) ) { // We found one! adapter = candidateAdapter; @@ -148,20 +142,18 @@ public: if(!adapter) { - return; + // Couldn't find an adapter + return SLANG_FAIL; } // Command Queue - D3D12_COMMAND_QUEUE_DESC queueDesc = {}; queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; ID3D12CommandQueue* commandQueue; - checkResult(dxDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&commandQueue))); + SLANG_RETURN_ON_FAIL(dxDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&commandQueue))); // Swap Chain - - UINT frameCount = 2; // TODO: configure DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; @@ -174,7 +166,7 @@ public: swapChainDesc.SampleDesc.Count = 1; IDXGISwapChain1* swapChain; - checkResult(dxgiFactory->CreateSwapChainForHwnd( + SLANG_RETURN_ON_FAIL(dxgiFactory->CreateSwapChainForHwnd( commandQueue, windowHandle, &swapChainDesc, @@ -183,11 +175,10 @@ public: &swapChain)); // Is this needed? - dxgiFactory->MakeWindowAssociation( - windowHandle, DXGI_MWA_NO_ALT_ENTER); + dxgiFactory->MakeWindowAssociation(windowHandle, DXGI_MWA_NO_ALT_ENTER); IDXGISwapChain3* swapChainEx; - swapChain->QueryInterface(IID_PPV_ARGS(&swapChainEx)); + SLANG_RETURN_ON_FAIL(swapChain->QueryInterface(IID_PPV_ARGS(&swapChainEx))); UINT frameIndex = swapChainEx->GetCurrentBackBufferIndex(); @@ -198,10 +189,9 @@ public: rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; ID3D12DescriptorHeap* rtvHeap; - checkResult(dxDevice->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&rtvHeap))); + SLANG_RETURN_ON_FAIL(dxDevice->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&rtvHeap))); - UINT rtvDescriptorSize = dxDevice->GetDescriptorHandleIncrementSize( - D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + UINT rtvDescriptorSize = dxDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap->GetCPUDescriptorHandleForHeapStart(); @@ -209,18 +199,14 @@ public: ID3D12Resource* backBufferResources[2]; for( UINT ff = 0; ff < frameCount; ++ff ) { - checkResult(swapChainEx->GetBuffer(ff, IID_PPV_ARGS(&backBufferResources[ff]))); - dxDevice->CreateRenderTargetView( - backBufferResources[ff], - nullptr, - rtvHandle); + SLANG_RETURN_ON_FAIL(swapChainEx->GetBuffer(ff, IID_PPV_ARGS(&backBufferResources[ff]))); + dxDevice->CreateRenderTargetView(backBufferResources[ff], nullptr, rtvHandle); rtvHandle.ptr += rtvDescriptorSize; } ID3D12CommandAllocator* commandAllocator; - checkResult(dxDevice->CreateCommandAllocator( - D3D12_COMMAND_LIST_TYPE_DIRECT, - IID_PPV_ARGS(&commandAllocator))); + SLANG_RETURN_ON_FAIL(dxDevice->CreateCommandAllocator( D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&commandAllocator))); + return SLANG_OK; } float clearColor[4] = { 0, 0, 0, 0 }; @@ -237,8 +223,9 @@ public: { } - virtual void captureScreenShot(char const* outputPath) override + virtual SlangResult captureScreenShot(char const* outputPath) override { + return SLANG_FAIL; } virtual ShaderCompiler* getShaderCompiler() override diff --git a/tools/render-test/render-gl.cpp b/tools/render-test/render-gl.cpp index 99b61c03c..c2195f4f0 100644 --- a/tools/render-test/render-gl.cpp +++ b/tools/render-test/render-gl.cpp @@ -86,7 +86,7 @@ public: // Renderer interface - virtual void initialize(void* inWindowHandle) override + virtual SlangResult initialize(void* inWindowHandle) override { auto windowHandle = (HWND) inWindowHandle; @@ -127,6 +127,8 @@ public: glEnable(GL_DEBUG_OUTPUT); glDebugMessageCallback(staticDebugCallback, this); } + + return SLANG_OK; } void debugCallback( @@ -181,7 +183,7 @@ public: SwapBuffers(deviceContext); } - virtual void captureScreenShot(char const* outputPath) override + virtual SlangResult captureScreenShot(char const* outputPath) override { int width = gWindowWidth; int height = gWindowHeight; @@ -189,7 +191,7 @@ public: int components = 4; int rowStride = width*components; - GLubyte* buffer = (GLubyte*)malloc(components * width * height); + GLubyte* buffer = (GLubyte*)::malloc(components * width * height); glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); @@ -222,12 +224,16 @@ public: components, buffer, rowStride); - if( !stbResult ) + + ::free(buffer); + + if( !stbResult ) { assert(!"unexpected"); + return SLANG_FAIL; } - delete(buffer); + return SLANG_OK; } virtual ShaderCompiler* getShaderCompiler() override @@ -483,7 +489,7 @@ public: int maxSize = 0; glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &maxSize); - auto infoBuffer = (char*) malloc(maxSize); + auto infoBuffer = (char*)::malloc(maxSize); int infoSize = 0; glGetProgramInfoLog(programID, maxSize, &infoSize, infoBuffer); @@ -493,8 +499,10 @@ public: OutputDebugStringA(infoBuffer); } + ::free(infoBuffer); + glDeleteProgram(programID); - return 0; + return nullptr; } return (ShaderProgram*) (uintptr_t) programID; diff --git a/tools/render-test/render-vk.cpp b/tools/render-test/render-vk.cpp index fd080931d..1f8e11aa6 100644 --- a/tools/render-test/render-vk.cpp +++ b/tools/render-test/render-vk.cpp @@ -73,8 +73,11 @@ M(vkCreateShaderModule) \ /* */ + namespace renderer_test { +#define RETURN_ON_VK_FAIL(x) { VkResult _vkRes = x; if (_vkRes != VK_SUCCESS) { SLANG_RETURN_ON_FAIL(toSlangResult(_vkRes)); }} + class VKRenderer : public Renderer, public ShaderCompiler { public: @@ -101,10 +104,14 @@ public: // Renderer interface - void checkResult(VkResult result) - { - assert(result == VK_SUCCESS); - } + static SlangResult toSlangResult(VkResult res) + { + return (res == VK_SUCCESS) ? SLANG_OK : SLANG_FAIL; + } + void checkResult(VkResult result) + { + assert(result == VK_SUCCESS); + } VkBool32 handleDebugMessage( VkDebugReportFlagsEXT flags, @@ -151,22 +158,21 @@ public: flags, objType, srcObject, location, msgCode, pLayerPrefix, pMsg); } - virtual void initialize(void* inWindowHandle) override + virtual SlangResult initialize(void* inWindowHandle) override { char const* dynamicLibraryName = "vulkan-1.dll"; HMODULE vulkan = LoadLibraryA(dynamicLibraryName); if(!vulkan) { fprintf(stderr, "error: failed load '%s'\n", dynamicLibraryName); - exit(1); + return SLANG_FAIL; } vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) GetProcAddress(vulkan, "vkGetInstanceProcAddr"); if(!vkGetInstanceProcAddr) { - fprintf(stderr, - "error: failed load symbol 'vkGetInstanceProcAddr'\n"); - exit(1); + fprintf(stderr, "error: failed load symbol 'vkGetInstanceProcAddr'\n"); + return SLANG_FAIL; } VkApplicationInfo applicationInfo = { VK_STRUCTURE_TYPE_APPLICATION_INFO }; @@ -209,10 +215,7 @@ public: FOREACH_GLOBAL_PROC(LOAD_INSTANCE_PROC); - checkResult(vkCreateInstance( - &instanceCreateInfo, - nullptr, - &instance)); + RETURN_ON_VK_FAIL(vkCreateInstance(&instanceCreateInfo, nullptr, &instance)); FOREACH_INSTANCE_PROC(LOAD_INSTANCE_PROC); @@ -227,18 +230,16 @@ public: debugCreateInfo.pUserData = this; debugCreateInfo.flags = debugFlags; - checkResult(vkCreateDebugReportCallbackEXT( - instance, &debugCreateInfo, nullptr, &debugReportCallback)); + RETURN_ON_VK_FAIL(vkCreateDebugReportCallbackEXT(instance, &debugCreateInfo, nullptr, &debugReportCallback)); #endif uint32_t physicalDeviceCount = 0; - checkResult(vkEnumeratePhysicalDevices( - instance, &physicalDeviceCount, nullptr)); + RETURN_ON_VK_FAIL(vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr)); VkPhysicalDevice* physicalDevices = (VkPhysicalDevice*)alloca( physicalDeviceCount * sizeof(VkPhysicalDevice)); - checkResult(vkEnumeratePhysicalDevices( + RETURN_ON_VK_FAIL(vkEnumeratePhysicalDevices( instance, &physicalDeviceCount, physicalDevices)); uint32_t selectedDeviceIndex = 0; @@ -293,7 +294,7 @@ public: deviceCreateInfo.enabledExtensionCount = sizeof(deviceExtensions) / sizeof(deviceExtensions[0]); deviceCreateInfo.ppEnabledExtensionNames = &deviceExtensions[0]; - checkResult(vkCreateDevice( + RETURN_ON_VK_FAIL(vkCreateDevice( physicalDevice, &deviceCreateInfo, nullptr, &device)); #define LOAD_DEVICE_PROC(NAME) NAME = (PFN_##NAME) vkGetDeviceProcAddr(device, #NAME); @@ -306,7 +307,7 @@ public: commandPoolCreateInfo.queueFamilyIndex = queueFamilyIndex; commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - checkResult(vkCreateCommandPool( + RETURN_ON_VK_FAIL(vkCreateCommandPool( device, &commandPoolCreateInfo, nullptr, &commandPool)); vkGetDeviceQueue( @@ -317,6 +318,8 @@ public: // set up swap chain + + // create command buffers // depth/stencil? @@ -329,9 +332,9 @@ public: -// create semaphores for sync - + // create semaphores for sync + return SLANG_OK; } float clearColor[4]; @@ -349,8 +352,9 @@ public: { } - virtual void captureScreenShot(char const* outputPath) override + virtual SlangResult captureScreenShot(char const* outputPath) override { + return SLANG_FAIL; } virtual ShaderCompiler* getShaderCompiler() override diff --git a/tools/render-test/render.h b/tools/render-test/render.h index 5eb0c967d..902067d62 100644 --- a/tools/render-test/render.h +++ b/tools/render-test/render.h @@ -5,6 +5,8 @@ #include "window.h" #include "shader-input-layout.h" +#include "../../source/core/slang-result.h" + namespace renderer_test { typedef struct Buffer Buffer; @@ -90,14 +92,14 @@ enum class PrimitiveTopology class Renderer { public: - virtual void initialize(void* inWindowHandle) = 0; + virtual SlangResult initialize(void* inWindowHandle) = 0; virtual void setClearColor(float const* color) = 0; virtual void clearFrame() = 0; virtual void presentFrame() = 0; - virtual void captureScreenShot(char const* outputPath) = 0; + virtual SlangResult captureScreenShot(char const* outputPath) = 0; virtual void serializeOutput(BindingState * state, char const* outputPath) = 0; virtual Buffer* createBuffer(BufferDesc const& desc) = 0; diff --git a/tools/render-test/slang-support.cpp b/tools/render-test/slang-support.cpp index 5599a3396..aa097bb44 100644 --- a/tools/render-test/slang-support.cpp +++ b/tools/render-test/slang-support.cpp @@ -170,7 +170,6 @@ ShaderCompiler* createSlangShaderCompiler( result->target = target; return result; - } |
