diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2018-03-21 14:28:43 -0400 |
|---|---|---|
| committer | Tim Foley <tfoleyNV@users.noreply.github.com> | 2018-03-21 11:28:43 -0700 |
| commit | d421988f91d0d6fda78b9aea4cba763f9c662ffe (patch) | |
| tree | 4207ebec4a744f67df540388133033753cffa359 /tools/render-test/render-d3d11.cpp | |
| parent | 98b8e0c809ceab84cee25389e54f3f37d220d95e (diff) | |
First pass impls on ComPtr and reorganise Renderer (#450)
* 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.
* Refactor Renderer implementations such that:
* Class definition does not contain long implementation/s
* Removed unused globals
* Ordered implementation after class definition
* Made renderer specific classes child classes, and use Impl postfix to differentiate
* Converted tabs into spaces
* First pass at Slang::ComPtr. Added slang-defines.h which sets up some fairly commonly used defines such as SLANG_FORCE_INLINE, compiler detection, os detection, and some other cross platform features.
Diffstat (limited to 'tools/render-test/render-d3d11.cpp')
| -rw-r--r-- | tools/render-test/render-d3d11.cpp | 1508 |
1 files changed, 750 insertions, 758 deletions
diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index ba8d9e46d..dc86e2e44 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -1,4 +1,4 @@ -// render-d3d11.cpp +// render-d3d11.cpp #include "render-d3d11.h" #include "options.h" @@ -40,61 +40,124 @@ using namespace Slang; namespace renderer_test { -struct D3DBinding -{ - ShaderInputType type; - InputBufferType bufferType; // Only valid if `type` is `Buffer` - ID3D11ShaderResourceView * srv = nullptr; - ID3D11UnorderedAccessView * uav = nullptr; - ID3D11Buffer * buffer = nullptr; - ID3D11SamplerState * samplerState = nullptr; - int binding = 0; - bool isOutput = false; - int bufferLength = 0; -}; -struct D3DBindingState +//static char const* vertexEntryPointName = "vertexMain"; +//static char const* fragmentEntryPointName = "fragmentMain"; + +//static char const* vertexProfileName = "vs_4_0"; +//static char const* fragmentProfileName = "ps_4_0"; + +class D3D11Renderer : public Renderer, public ShaderCompiler { - List<D3DBinding> bindings; - int numRenderTargets = 0; -}; +public: + // Renderer implementation + virtual SlangResult initialize(void* inWindowHandle) override; + virtual void setClearColor(float const* color) override; + virtual void clearFrame() override; + virtual void presentFrame() override; + virtual SlangResult captureScreenShot(char const* outputPath) override; + virtual void serializeOutput(BindingState* state, const char * fileName) override; + virtual Buffer* createBuffer(BufferDesc const& desc) override; + virtual InputLayout* createInputLayout(InputElementDesc const* inputElements, UInt inputElementCount) override; + virtual BindingState * createBindingState(const ShaderInputLayout& layout) override; + virtual ShaderCompiler* getShaderCompiler() override; + virtual void* map(Buffer* buffer, MapFlavor flavor) override; + virtual void unmap(Buffer* buffer) override; + virtual void setInputLayout(InputLayout* inputLayout) override; + virtual void setPrimitiveTopology(PrimitiveTopology topology) override; + virtual void setBindingState(BindingState * state); + virtual void setVertexBuffers(UInt startSlot, UInt slotCount, Buffer* const* buffers, UInt const* strides, UInt const* offsets) override; + virtual void setShaderProgram(ShaderProgram* inProgram) override; + virtual void setConstantBuffers(UInt startSlot, UInt slotCount, Buffer* const* buffers, UInt const* offsets) override; + virtual void draw(UInt vertexCount, UInt startVertex) override; + virtual void dispatchCompute(int x, int y, int z) override; + + // ShaderCompiler implementation + virtual ShaderProgram* compileProgram(ShaderCompileRequest const& request) override; -// + protected: + struct BindingImpl + { + ShaderInputType type; + InputBufferType bufferType; // Only valid if `type` is `Buffer` + ID3D11ShaderResourceView * srv = nullptr; + ID3D11UnorderedAccessView * uav = nullptr; + ID3D11Buffer * buffer = nullptr; + ID3D11SamplerState * samplerState = nullptr; + int binding = 0; + bool isOutput = false; + int bufferLength = 0; + }; + struct BindingStateImpl + { + List<BindingImpl> bindings; + int numRenderTargets = 0; + }; + struct ShaderProgramImpl + { + ID3D11VertexShader* dxVertexShader = nullptr; + ID3D11PixelShader* dxPixelShader = nullptr; + ID3D11ComputeShader* dxComputeShader = nullptr; + }; -// + struct BufferImpl + { + ID3D11Buffer* buffer = nullptr; + }; -// Global variabels for the various D3D11 API objects to be used for rendering -ID3D11Buffer* dxConstantBuffer; -ID3D11InputLayout* dxInputLayout; -ID3D11Buffer* dxVertexBuffer; -ID3D11VertexShader* dxVertexShader; -ID3D11PixelShader* dxPixelShader; + /// 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); } + + static DXGI_FORMAT getMapFormat(Format format); -// The Slang compiler currently generates HLSL source, so we'll need a utility -// routine (defined later) to translate that into D3D11 shader bytecode. -ID3DBlob* compileHLSLShader( - char const* sourcePath, - char const* source, - char const* entryPointName, - char const* dxProfileName); + /// 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. + static ID3DBlob* compileHLSLShader(char const* sourcePath, char const* source, char const* entryPointName, char const* dxProfileName); + /// Capture a texture to a file + static HRESULT captureTextureToFile(ID3D11Device* dxDevice, ID3D11DeviceContext* dxContext, ID3D11Texture2D* dxTexture, char const* outputPath); -static char const* vertexEntryPointName = "vertexMain"; -static char const* fragmentEntryPointName = "fragmentMain"; + void* map(ID3D11Buffer * buffer, MapFlavor flavor); + void unmap(ID3D11Buffer * buffer); -static char const* vertexProfileName = "vs_4_0"; -static char const* fragmentProfileName = "ps_4_0"; + void createInputBuffer(InputBufferDesc & bufferDesc, List<unsigned int> & bufferData, ID3D11Buffer * &bufferOut, + ID3D11UnorderedAccessView * &viewOut, ID3D11ShaderResourceView * &srvOut); -ID3DBlob* gVertexShaderBlob; -ID3DBlob* gPixelShaderBlob; + void createInputTexture(const InputTextureDesc & inputDesc, ID3D11ShaderResourceView * &viewOut); -// -// Definition of the HLSL-to-bytecode compilation logic. -// -ID3DBlob* compileHLSLShader( - char const* sourcePath, - char const* source, - char const* entryPointName, - char const* dxProfileName ) + void createInputSampler(const InputSamplerDesc & inputDesc, ID3D11SamplerState * & stateOut); + + void applyBindingState(bool isCompute); + + IDXGISwapChain* dxSwapChain = nullptr; + ID3D11Device* dxDevice = nullptr; + ID3D11DeviceContext* dxImmediateContext = nullptr; + ID3D11Texture2D* dxBackBufferTexture = nullptr; + List<ID3D11RenderTargetView*> dxRenderTargetViews; + List<ID3D11Texture2D*> dxRenderTargetTextures; + BindingStateImpl* currentBindings = nullptr; + float clearColor[4] = { 0, 0, 0, 0 }; +}; + +Renderer* createD3D11Renderer() +{ + return new D3D11Renderer(); +} + +/* static */DXGI_FORMAT D3D11Renderer::getMapFormat(Format format) +{ + switch (format) + { + case Format::RGB_Float32: + return DXGI_FORMAT_R32G32B32_FLOAT; + case Format::RG_Float32: + return DXGI_FORMAT_R32G32_FLOAT; + default: + return DXGI_FORMAT_UNKNOWN; + } +} + +/* static */ID3DBlob* D3D11Renderer::compileHLSLShader(char const* sourcePath, char const* source, char const* entryPointName, char const* dxProfileName) { // Rather than statically link against the `d3dcompile` library, we // dynamically load it. @@ -104,21 +167,21 @@ ID3DBlob* compileHLSLShader( // on-the-fly like this // static pD3DCompile D3DCompile_ = nullptr; - if( !D3DCompile_ ) + if (!D3DCompile_) { // TODO(tfoley): maybe want to search for one of a few versions of the DLL HMODULE d3dcompiler = LoadLibraryA("d3dcompiler_47.dll"); - if(!d3dcompiler) + if (!d3dcompiler) { fprintf(stderr, "error: failed load 'd3dcompiler_47.dll'\n"); return nullptr; } D3DCompile_ = (pD3DCompile)GetProcAddress(d3dcompiler, "D3DCompile"); - if( !D3DCompile_ ) + if (!D3DCompile_) { fprintf(stderr, "error: failed load symbol 'D3DCompile'\n"); - return nullptr; + return nullptr; } } @@ -155,7 +218,7 @@ ID3DBlob* compileHLSLShader( // If the HLSL-to-bytecode compilation produced any diagnostic messages // then we will print them out (whether or not the compilation failed). - if( dxErrorBlob ) + if (dxErrorBlob) { fputs( (char const*)dxErrorBlob->GetBufferPointer(), @@ -168,7 +231,7 @@ ID3DBlob* compileHLSLShader( dxErrorBlob->Release(); } - if( FAILED(hr) ) + if (FAILED(hr)) { return nullptr; } @@ -176,34 +239,26 @@ ID3DBlob* compileHLSLShader( return dxShaderBlob; } - - - -// Capture a texture to a file - -static HRESULT captureTextureToFile( - ID3D11Device* dxDevice, - ID3D11DeviceContext* dxContext, - ID3D11Texture2D* dxTexture, - char const* outputPath) +/* static */HRESULT D3D11Renderer::captureTextureToFile(ID3D11Device* dxDevice, ID3D11DeviceContext* dxContext, + ID3D11Texture2D* dxTexture, char const* outputPath) { - if(!dxContext) return E_INVALIDARG; - if(!dxTexture) return E_INVALIDARG; + if (!dxContext) return E_INVALIDARG; + if (!dxTexture) return E_INVALIDARG; D3D11_TEXTURE2D_DESC dxTextureDesc; dxTexture->GetDesc(&dxTextureDesc); // Don't bother supporting MSAA for right now - if( dxTextureDesc.SampleDesc.Count > 1 ) + if (dxTextureDesc.SampleDesc.Count > 1) { - fprintf(stderr, "ERROR: cannot capture multisample texture\n"); + fprintf(stderr, "ERROR: cannot capture multi-sample texture\n"); return E_INVALIDARG; } HRESULT hr = S_OK; ID3D11Texture2D* dxStagingTexture = nullptr; - if( dxTextureDesc.Usage == D3D11_USAGE_STAGING && (dxTextureDesc.CPUAccessFlags & D3D11_CPU_ACCESS_READ) ) + if (dxTextureDesc.Usage == D3D11_USAGE_STAGING && (dxTextureDesc.CPUAccessFlags & D3D11_CPU_ACCESS_READ)) { dxStagingTexture = dxTexture; dxStagingTexture->AddRef(); @@ -217,12 +272,12 @@ static HRESULT captureTextureToFile( dxTextureDesc.Usage = D3D11_USAGE_STAGING; hr = dxDevice->CreateTexture2D(&dxTextureDesc, 0, &dxStagingTexture); - if( FAILED(hr) ) + if (FAILED(hr)) { fprintf(stderr, "ERROR: failed to create staging texture\n"); return hr; } - + dxContext->CopyResource(dxStagingTexture, dxTexture); } @@ -230,240 +285,215 @@ static HRESULT captureTextureToFile( D3D11_MAPPED_SUBRESOURCE dxMappedResource; hr = dxContext->Map(dxStagingTexture, 0, D3D11_MAP_READ, 0, &dxMappedResource); - if( FAILED(hr) ) + if (FAILED(hr)) { fprintf(stderr, "ERROR: failed to map texture for read\n"); return hr; } - int stbResult = stbi_write_png( - outputPath, - dxTextureDesc.Width, - dxTextureDesc.Height, - 4, - dxMappedResource.pData, - dxMappedResource.RowPitch); - if( !stbResult ) + int stbResult = stbi_write_png(outputPath, dxTextureDesc.Width, dxTextureDesc.Height, 4, + dxMappedResource.pData, dxMappedResource.RowPitch); + + // Make sure to unmap + dxContext->Unmap(dxStagingTexture, 0); + dxStagingTexture->Release(); + + if (!stbResult) { fprintf(stderr, "ERROR: failed to write texture to file\n"); return E_UNEXPECTED; } - dxContext->Unmap(dxStagingTexture, 0); - - dxStagingTexture->Release(); - return S_OK; } -// +// !!!!!!!!!!!!!!!!!!!!!!!!!!!! Renderer interface !!!!!!!!!!!!!!!!!!!!!!!!!! -class D3D11Renderer : public Renderer, public ShaderCompiler +SlangResult D3D11Renderer::initialize(void* inWindowHandle) { -public: - IDXGISwapChain* dxSwapChain = nullptr; - ID3D11Device* dxDevice = nullptr; - ID3D11DeviceContext* dxImmediateContext = nullptr; - ID3D11Texture2D* dxBackBufferTexture = nullptr; - List<ID3D11RenderTargetView*> dxRenderTargetViews; - List<ID3D11Texture2D *> dxRenderTargetTextures; - D3DBindingState * currentBindings = nullptr; - virtual SlangResult initialize(void* inWindowHandle) override + auto windowHandle = (HWND)inWindowHandle; + // Rather than statically link against D3D, we load it dynamically. + + HMODULE d3d11 = LoadLibraryA("d3d11.dll"); + if (!d3d11) { - auto windowHandle = (HWND) inWindowHandle; - // Rather than statically link against D3D, we load it dynamically. + fprintf(stderr, "error: failed load 'd3d11.dll'\n"); + return SLANG_FAIL; + } - HMODULE d3d11 = LoadLibraryA("d3d11.dll"); - if(!d3d11) - { - fprintf(stderr, "error: failed load 'd3d11.dll'\n"); - return SLANG_FAIL; - } + PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN D3D11CreateDeviceAndSwapChain_ = + (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress(d3d11, "D3D11CreateDeviceAndSwapChain"); + if (!D3D11CreateDeviceAndSwapChain_) + { + fprintf(stderr, + "error: failed load symbol 'D3D11CreateDeviceAndSwapChain'\n"); + return SLANG_FAIL; + } - PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN D3D11CreateDeviceAndSwapChain_ = - (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress(d3d11, "D3D11CreateDeviceAndSwapChain"); - if(!D3D11CreateDeviceAndSwapChain_) - { - fprintf(stderr, - "error: failed load symbol 'D3D11CreateDeviceAndSwapChain'\n"); - return SLANG_FAIL; - } + // We create our device in debug mode, just so that we can check that the + // example doesn't trigger warnings. + UINT deviceFlags = 0; + deviceFlags |= D3D11_CREATE_DEVICE_DEBUG; + + + // Our swap chain uses RGBA8 with sRGB, with double buffering. + + DXGI_SWAP_CHAIN_DESC dxSwapChainDesc = { 0 }; + dxSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + + // Note(tfoley): Disabling sRGB for DX back buffer for now, so that we + // can get consistent output with OpenGL, where setting up sRGB will + // probably be more involved. + // dxSwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + dxSwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + + dxSwapChainDesc.SampleDesc.Count = 1; + dxSwapChainDesc.SampleDesc.Quality = 0; + dxSwapChainDesc.BufferCount = 2; + dxSwapChainDesc.OutputWindow = windowHandle; + dxSwapChainDesc.Windowed = TRUE; + 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 + // `D3D11CreateDeviceAndSwapChain` up to twice: the first time with 11_1 + // at the start of the list of requested feature levels, and the second + // time without it. - // We create our device in debug mode, just so that we can check that the - // example doesn't trigger warnings. - UINT deviceFlags = 0; - deviceFlags |= D3D11_CREATE_DEVICE_DEBUG; - - - // Our swap chain uses RGBA8 with sRGB, with double buffering. - - DXGI_SWAP_CHAIN_DESC dxSwapChainDesc = { 0 }; - dxSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - - // Note(tfoley): Disabling sRGB for DX back buffer for now, so that we - // can get consistent output with OpenGL, where setting up sRGB will - // probably be more involved. -// dxSwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; - dxSwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - - dxSwapChainDesc.SampleDesc.Count = 1; - dxSwapChainDesc.SampleDesc.Quality = 0; - dxSwapChainDesc.BufferCount = 2; - dxSwapChainDesc.OutputWindow = windowHandle; - dxSwapChainDesc.Windowed = TRUE; - 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 - // `D3D11CreateDeviceAndSwapChain` up to twice: the first time with 11_1 - // at the start of the list of requested feature levels, and the second - // time without it. - - for( int ii = 0; ii < 2; ++ii ) + for (int ii = 0; ii < 2; ++ii) + { + const HRESULT hr = D3D11CreateDeviceAndSwapChain_( + NULL, // adapter (use default) + D3D_DRIVER_TYPE_REFERENCE, + //D3D_DRIVER_TYPE_HARDWARE, + NULL, // software + deviceFlags, + &featureLevels[ii], + totalNumFeatureLevels - ii, + D3D11_SDK_VERSION, + &dxSwapChainDesc, + &dxSwapChain, + &dxDevice, + &dxFeatureLevel, + &dxImmediateContext); + + // Failures with `E_INVALIDARG` might be due to feature level 11_1 + // not being supported. + if (hr == E_INVALIDARG) { - const HRESULT hr = D3D11CreateDeviceAndSwapChain_( - NULL, // adapter (use default) - D3D_DRIVER_TYPE_REFERENCE, - //D3D_DRIVER_TYPE_HARDWARE, - NULL, // software - deviceFlags, - &featureLevels[ii], - totalNumFeatureLevels - ii, - D3D11_SDK_VERSION, - &dxSwapChainDesc, - &dxSwapChain, - &dxDevice, - &dxFeatureLevel, - &dxImmediateContext); - - // 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; + continue; } - - // 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. - static const IID kIID_ID3D11Texture2D = { - 0x6f15aaf2, 0xd208, 0x4e89, 0x9a, 0xb4, 0x48, - 0x95, 0x35, 0xd3, 0x4f, 0x9c }; + // Other failures are real, though. + SLANG_RETURN_ON_FAIL(hr); + // We must have a swap chain + break; + } - SLANG_RETURN_ON_FAIL(dxSwapChain->GetBuffer(0, kIID_ID3D11Texture2D, (void**)&dxBackBufferTexture)); + // 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. - for (int i = 0; i < 8; i++) - { - ID3D11Texture2D* texture; - D3D11_TEXTURE2D_DESC textureDesc; - dxBackBufferTexture->GetDesc(&textureDesc); - 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; - SLANG_RETURN_ON_FAIL(dxDevice->CreateRenderTargetView(texture, &rtvDesc, &rtv)); - - dxRenderTargetViews.Add(rtv); - dxRenderTargetTextures.Add(texture); - } + static const IID kIID_ID3D11Texture2D = { + 0x6f15aaf2, 0xd208, 0x4e89, 0x9a, 0xb4, 0x48, + 0x95, 0x35, 0xd3, 0x4f, 0x9c }; - 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; - dxViewport.TopLeftX = 0; - dxViewport.TopLeftY = 0; - dxViewport.Width = (float) gWindowWidth; - dxViewport.Height = (float) gWindowHeight; - dxViewport.MaxDepth = 1; // TODO(tfoley): use reversed depth - dxViewport.MinDepth = 0; - dxImmediateContext->RSSetViewports(1, &dxViewport); - - return SLANG_OK; - } + SLANG_RETURN_ON_FAIL(dxSwapChain->GetBuffer(0, kIID_ID3D11Texture2D, (void**)&dxBackBufferTexture)); - float clearColor[4] = { 0, 0, 0, 0 }; - virtual void setClearColor(float const* color) override + for (int i = 0; i < 8; i++) { - memcpy(clearColor, color, sizeof(clearColor)); + ID3D11Texture2D* texture; + D3D11_TEXTURE2D_DESC textureDesc; + dxBackBufferTexture->GetDesc(&textureDesc); + 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; + SLANG_RETURN_ON_FAIL(dxDevice->CreateRenderTargetView(texture, &rtvDesc, &rtv)); + + dxRenderTargetViews.Add(rtv); + dxRenderTargetTextures.Add(texture); } - virtual void clearFrame() override - { - for (auto i = 0u; i < dxRenderTargetViews.Count(); i++) - dxImmediateContext->ClearRenderTargetView( - dxRenderTargetViews[i], - clearColor); - } + dxImmediateContext->OMSetRenderTargets((UINT)dxRenderTargetViews.Count(), dxRenderTargetViews.Buffer(), nullptr); - virtual void presentFrame() override - { - dxImmediateContext->CopyResource(dxBackBufferTexture, dxRenderTargetTextures[0]); - dxSwapChain->Present(0, 0); - } + // Similarly, we are going to set up a viewport once, and then never + // switch, since this is a simple test app. + D3D11_VIEWPORT dxViewport; + dxViewport.TopLeftX = 0; + dxViewport.TopLeftY = 0; + dxViewport.Width = (float)gWindowWidth; + dxViewport.Height = (float)gWindowHeight; + dxViewport.MaxDepth = 1; // TODO(tfoley): use reversed depth + dxViewport.MinDepth = 0; + dxImmediateContext->RSSetViewports(1, &dxViewport); - virtual SlangResult captureScreenShot(char const* outputPath) override - { - HRESULT hr = captureTextureToFile( - dxDevice, - dxImmediateContext, - dxRenderTargetTextures[0], - outputPath); - if( FAILED(hr) ) - { - fprintf(stderr, "error: could not capture screenshot to '%s'\n", outputPath); - SLANG_RETURN_ON_FAIL(hr); - } - return SLANG_OK; - } + return SLANG_OK; +} - virtual ShaderCompiler* getShaderCompiler() override - { - return this; - } +void D3D11Renderer::setClearColor(float const* color) +{ + memcpy(clearColor, color, sizeof(clearColor)); +} - struct D3DBuffer - { - ID3D11Buffer * buffer = nullptr; - }; +void D3D11Renderer::clearFrame() +{ + for (auto i = 0u; i < dxRenderTargetViews.Count(); i++) + dxImmediateContext->ClearRenderTargetView( + dxRenderTargetViews[i], + clearColor); +} + +void D3D11Renderer::presentFrame() +{ + dxImmediateContext->CopyResource(dxBackBufferTexture, dxRenderTargetTextures[0]); + dxSwapChain->Present(0, 0); +} - UInt RoundUpToAlignment(UInt size, UInt alignment) +SlangResult D3D11Renderer::captureScreenShot(char const* outputPath) +{ + HRESULT hr = captureTextureToFile( + dxDevice, + dxImmediateContext, + dxRenderTargetTextures[0], + outputPath); + if (FAILED(hr)) { - return ((size + alignment - 1) / alignment) * alignment; + fprintf(stderr, "error: could not capture screen-shot to '%s'\n", outputPath); + SLANG_RETURN_ON_FAIL(hr); } + return SLANG_OK; +} - virtual Buffer* createBuffer(BufferDesc const& desc) override - { - D3D11_BUFFER_DESC dxBufferDesc = { 0 }; - dxBufferDesc.ByteWidth = (UINT)RoundUpToAlignment(desc.size, 256); +ShaderCompiler* D3D11Renderer::getShaderCompiler() +{ + return this; +} - switch( desc.flavor ) - { +Buffer* D3D11Renderer::createBuffer(BufferDesc const& desc) +{ + D3D11_BUFFER_DESC dxBufferDesc = { 0 }; + dxBufferDesc.ByteWidth = (UINT)calcAligned(desc.size, 256); + + switch (desc.flavor) + { case BufferFlavor::Constant: dxBufferDesc.Usage = D3D11_USAGE_DYNAMIC; dxBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; @@ -477,64 +507,47 @@ public: break; default: return nullptr; - } + } - D3D11_SUBRESOURCE_DATA dxInitData = { 0 }; - dxInitData.pSysMem = desc.initData; + D3D11_SUBRESOURCE_DATA dxInitData = { 0 }; + dxInitData.pSysMem = desc.initData; + ID3D11Buffer* dxBuffer = nullptr; + HRESULT hr = dxDevice->CreateBuffer(&dxBufferDesc, desc.initData ? &dxInitData : nullptr, &dxBuffer); + if (FAILED(hr)) return nullptr; - ID3D11Buffer* dxBuffer = nullptr; - HRESULT hr = dxDevice->CreateBuffer( - &dxBufferDesc, - desc.initData ? &dxInitData : nullptr, - &dxBuffer); - if(FAILED(hr)) return nullptr; + BufferImpl* rs = new BufferImpl; + rs->buffer = dxBuffer; + return (Buffer*)rs; +} - D3DBuffer * rs = new D3DBuffer(); - rs->buffer = dxBuffer; - return (Buffer*) rs; - } +InputLayout* D3D11Renderer::createInputLayout(InputElementDesc const* inputElements, UInt inputElementCount) +{ + D3D11_INPUT_ELEMENT_DESC dxInputElements[16] = {}; - static DXGI_FORMAT mapFormat(Format format) + char hlslBuffer[1024]; + char* hlslCursor = &hlslBuffer[0]; + + hlslCursor += sprintf(hlslCursor, "float4 main(\n"); + + for (UInt ii = 0; ii < inputElementCount; ++ii) { - switch( format ) + dxInputElements[ii].SemanticName = inputElements[ii].semanticName; + dxInputElements[ii].SemanticIndex = (UINT)inputElements[ii].semanticIndex; + dxInputElements[ii].Format = getMapFormat(inputElements[ii].format); + dxInputElements[ii].InputSlot = 0; + dxInputElements[ii].AlignedByteOffset = (UINT)inputElements[ii].offset; + dxInputElements[ii].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + dxInputElements[ii].InstanceDataStepRate = 0; + + if (ii != 0) { - case Format::RGB_Float32: - return DXGI_FORMAT_R32G32B32_FLOAT; - case Format::RG_Float32: - return DXGI_FORMAT_R32G32_FLOAT; - default: - return DXGI_FORMAT_UNKNOWN; + hlslCursor += sprintf(hlslCursor, ",\n"); } - } - - virtual InputLayout* createInputLayout(InputElementDesc const* inputElements, UInt inputElementCount) override - { - D3D11_INPUT_ELEMENT_DESC dxInputElements[16] = {}; - - char hlslBuffer[1024]; - char* hlslCursor = &hlslBuffer[0]; - - hlslCursor += sprintf(hlslCursor, "float4 main(\n"); - for( UInt ii = 0; ii < inputElementCount; ++ii ) + char const* typeName = "Unknown"; + switch (inputElements[ii].format) { - dxInputElements[ii].SemanticName = inputElements[ii].semanticName; - dxInputElements[ii].SemanticIndex = (UINT) inputElements[ii].semanticIndex; - dxInputElements[ii].Format = mapFormat(inputElements[ii].format); - dxInputElements[ii].InputSlot = 0; - dxInputElements[ii].AlignedByteOffset = (UINT) inputElements[ii].offset; - dxInputElements[ii].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - dxInputElements[ii].InstanceDataStepRate = 0; - - if(ii != 0) - { - hlslCursor+= sprintf(hlslCursor, ",\n"); - } - - char const* typeName = "Unknown"; - switch(inputElements[ii].format) - { case Format::RGB_Float32: typeName = "float3"; break; @@ -543,46 +556,46 @@ public: break; default: return nullptr; - } - - hlslCursor+= sprintf(hlslCursor, "%s a%d : %s%d", - typeName, - (int) ii, - inputElements[ii].semanticName, - (int) inputElements[ii].semanticIndex); } - hlslCursor += sprintf(hlslCursor, "\n) : SV_Position { return 0; }"); + hlslCursor += sprintf(hlslCursor, "%s a%d : %s%d", + typeName, + (int)ii, + inputElements[ii].semanticName, + (int)inputElements[ii].semanticIndex); + } - auto dxVertexShaderBlob = compileHLSLShader("inputLayout", hlslBuffer, "main", "vs_5_0"); - if(!dxVertexShaderBlob) - return nullptr; + hlslCursor += sprintf(hlslCursor, "\n) : SV_Position { return 0; }"); - ID3D11InputLayout* dxInputLayout = nullptr; - HRESULT hr = dxDevice->CreateInputLayout( - &dxInputElements[0], - (UINT) inputElementCount, - dxVertexShaderBlob->GetBufferPointer(), - dxVertexShaderBlob->GetBufferSize(), - &dxInputLayout); + auto dxVertexShaderBlob = compileHLSLShader("inputLayout", hlslBuffer, "main", "vs_5_0"); + if (!dxVertexShaderBlob) + return nullptr; - dxVertexShaderBlob->Release(); + ID3D11InputLayout* dxInputLayout = nullptr; + HRESULT hr = dxDevice->CreateInputLayout( + &dxInputElements[0], + (UINT)inputElementCount, + dxVertexShaderBlob->GetBufferPointer(), + dxVertexShaderBlob->GetBufferSize(), + &dxInputLayout); - if(FAILED(hr)) - return nullptr; + dxVertexShaderBlob->Release(); - return (InputLayout*) dxInputLayout; - } + if (FAILED(hr)) + return nullptr; - void* map(ID3D11Buffer * buffer, MapFlavor flavor) - { - auto dxContext = dxImmediateContext; + return (InputLayout*)dxInputLayout; +} - auto dxBuffer = buffer; +void* D3D11Renderer::map(ID3D11Buffer * buffer, MapFlavor flavor) +{ + auto dxContext = dxImmediateContext; - D3D11_MAP dxMapFlavor; - switch (flavor) - { + auto dxBuffer = buffer; + + D3D11_MAP dxMapFlavor; + switch (flavor) + { case MapFlavor::WriteDiscard: dxMapFlavor = D3D11_MAP_WRITE_DISCARD; break; @@ -594,395 +607,380 @@ public: break; default: return nullptr; - } + } - // 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 dxMapped; - HRESULT hr = dxContext->Map(dxBuffer, 0, dxMapFlavor, 0, &dxMapped); - if (FAILED(hr)) - return nullptr; + // 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 dxMapped; + HRESULT hr = dxContext->Map(dxBuffer, 0, dxMapFlavor, 0, &dxMapped); + if (FAILED(hr)) + return nullptr; - return dxMapped.pData; - } + return dxMapped.pData; +} - virtual void* map(Buffer* buffer, MapFlavor flavor) override - { - return map(((D3DBuffer*)buffer)->buffer, flavor); - } +void* D3D11Renderer::map(Buffer* buffer, MapFlavor flavor) +{ + return map(((BufferImpl*)buffer)->buffer, flavor); +} - void unmap(ID3D11Buffer * buffer) - { - auto dxContext = dxImmediateContext; - dxContext->Unmap(buffer, 0); - } +void D3D11Renderer::unmap(ID3D11Buffer * buffer) +{ + auto dxContext = dxImmediateContext; + dxContext->Unmap(buffer, 0); +} - virtual void unmap(Buffer* buffer) override - { - auto dxBuffer = ((D3DBuffer*)buffer)->buffer; - unmap(dxBuffer); - } +void D3D11Renderer::unmap(Buffer* buffer) +{ + auto dxBuffer = ((BufferImpl*)buffer)->buffer; + unmap(dxBuffer); +} - virtual void setInputLayout(InputLayout* inputLayout) override - { - auto dxContext = dxImmediateContext; - auto dxInputLayout = (ID3D11InputLayout*) inputLayout; +void D3D11Renderer::setInputLayout(InputLayout* inputLayout) +{ + auto dxContext = dxImmediateContext; + auto dxInputLayout = (ID3D11InputLayout*)inputLayout; - dxContext->IASetInputLayout(dxInputLayout); - } + dxContext->IASetInputLayout(dxInputLayout); +} - virtual void setPrimitiveTopology(PrimitiveTopology topology) override - { - auto dxContext = dxImmediateContext; +void D3D11Renderer::setPrimitiveTopology(PrimitiveTopology topology) +{ + auto dxContext = dxImmediateContext; - D3D11_PRIMITIVE_TOPOLOGY dxTopology; - switch( topology ) - { + D3D11_PRIMITIVE_TOPOLOGY dxTopology; + switch (topology) + { case PrimitiveTopology::TriangleList: dxTopology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; break; default: return; - } - - dxContext->IASetPrimitiveTopology(dxTopology); } - virtual void setVertexBuffers(UInt startSlot, UInt slotCount, Buffer* const* buffers, UInt const* strides, UInt const* offsets) override - { - auto dxContext = dxImmediateContext; - - static const int kMaxVertexBuffers = 16; - - UINT dxVertexStrides[kMaxVertexBuffers]; - UINT dxVertexOffsets[kMaxVertexBuffers]; + dxContext->IASetPrimitiveTopology(dxTopology); +} - for( UInt ii = 0; ii < slotCount; ++ii ) - { - dxVertexStrides[ii] = (UINT) strides[ii]; - dxVertexOffsets[ii] = (UINT) offsets[ii]; - } +void D3D11Renderer::setVertexBuffers(UInt startSlot, UInt slotCount, Buffer* const* buffers, UInt const* strides, UInt const* offsets) +{ + auto dxContext = dxImmediateContext; - auto dxVertexBuffers = (D3DBuffer* const*) buffers; + static const int kMaxVertexBuffers = 16; - dxContext->IASetVertexBuffers( - (UINT) startSlot, - (UINT) slotCount, &(dxVertexBuffers[0])->buffer, &dxVertexStrides[0], &dxVertexOffsets[0]); - } + UINT dxVertexStrides[kMaxVertexBuffers]; + UINT dxVertexOffsets[kMaxVertexBuffers]; - virtual void setShaderProgram(ShaderProgram* inProgram) override + for (UInt ii = 0; ii < slotCount; ++ii) { - auto dxContext = dxImmediateContext; - - auto program = (D3D11ShaderProgram*) inProgram; - dxContext->CSSetShader(program->dxComputeShader, NULL, 0); - dxContext->VSSetShader(program->dxVertexShader, NULL, 0); - dxContext->PSSetShader(program->dxPixelShader, NULL, 0); + dxVertexStrides[ii] = (UINT)strides[ii]; + dxVertexOffsets[ii] = (UINT)offsets[ii]; } - virtual void setConstantBuffers(UInt startSlot, UInt slotCount, Buffer* const* buffers, UInt const* offsets) override - { - auto dxContext = dxImmediateContext; + auto dxVertexBuffers = (BufferImpl* const*)buffers; - // TODO: actually use those offsets + dxContext->IASetVertexBuffers( + (UINT)startSlot, + (UINT)slotCount, &(dxVertexBuffers[0])->buffer, &dxVertexStrides[0], &dxVertexOffsets[0]); +} - auto dxConstantBuffers = (D3DBuffer* const*) buffers; - dxContext->VSSetConstantBuffers( - (UINT) startSlot, (UINT) slotCount, &dxConstantBuffers[0]->buffer); - dxContext->VSSetConstantBuffers( - (UINT) startSlot, (UINT) slotCount, &dxConstantBuffers[0]->buffer); - } +void D3D11Renderer::setShaderProgram(ShaderProgram* inProgram) +{ + auto dxContext = dxImmediateContext; - virtual void draw(UInt vertexCount, UInt startVertex) override - { - auto dxContext = dxImmediateContext; - applyBindingState(false); - dxContext->Draw((UINT) vertexCount, (UINT) startVertex); - } + auto program = (ShaderProgramImpl*)inProgram; + dxContext->CSSetShader(program->dxComputeShader, nullptr, 0); + dxContext->VSSetShader(program->dxVertexShader, nullptr, 0); + dxContext->PSSetShader(program->dxPixelShader, nullptr, 0); +} +void D3D11Renderer::setConstantBuffers(UInt startSlot, UInt slotCount, Buffer* const* buffers, UInt const* offsets) +{ + auto dxContext = dxImmediateContext; - // ShaderCompiler interface + // TODO: actually use those offsets - struct D3D11ShaderProgram - { - ID3D11VertexShader* dxVertexShader = nullptr; - ID3D11PixelShader* dxPixelShader = nullptr; - ID3D11ComputeShader* dxComputeShader = nullptr; - }; + auto dxConstantBuffers = (BufferImpl* const*)buffers; + dxContext->VSSetConstantBuffers((UINT)startSlot, (UINT)slotCount, &dxConstantBuffers[0]->buffer); + dxContext->VSSetConstantBuffers((UINT)startSlot, (UINT)slotCount, &dxConstantBuffers[0]->buffer); +} + +void D3D11Renderer::draw(UInt vertexCount, UInt startVertex) +{ + auto dxContext = dxImmediateContext; + applyBindingState(false); + dxContext->Draw((UINT)vertexCount, (UINT)startVertex); +} - virtual ShaderProgram* compileProgram(ShaderCompileRequest const& request) override +ShaderProgram* D3D11Renderer::compileProgram(ShaderCompileRequest const& request) +{ + if (request.computeShader.name) { - if (request.computeShader.name) - { - auto dxComputeShaderBlob = compileHLSLShader(request.computeShader.source.path, request.computeShader.source.dataBegin, request.computeShader.name, request.computeShader.profile); - if (!dxComputeShaderBlob) - return nullptr; + auto dxComputeShaderBlob = compileHLSLShader(request.computeShader.source.path, request.computeShader.source.dataBegin, request.computeShader.name, request.computeShader.profile); + if (!dxComputeShaderBlob) + return nullptr; - ID3D11ComputeShader* dxComputeShader; + ID3D11ComputeShader* dxComputeShader; - HRESULT csResult = dxDevice->CreateComputeShader(dxComputeShaderBlob->GetBufferPointer(), dxComputeShaderBlob->GetBufferSize(), nullptr, &dxComputeShader); + HRESULT csResult = dxDevice->CreateComputeShader(dxComputeShaderBlob->GetBufferPointer(), dxComputeShaderBlob->GetBufferSize(), nullptr, &dxComputeShader); - dxComputeShaderBlob->Release(); + dxComputeShaderBlob->Release(); - if (FAILED(csResult)) return nullptr; + if (FAILED(csResult)) return nullptr; - D3D11ShaderProgram* shaderProgram = new D3D11ShaderProgram(); - shaderProgram->dxComputeShader = dxComputeShader; - return (ShaderProgram*)shaderProgram; - } - else - { - auto dxVertexShaderBlob = compileHLSLShader(request.vertexShader.source.path, request.vertexShader.source.dataBegin, request.vertexShader.name, request.vertexShader.profile); - if (!dxVertexShaderBlob) return nullptr; + ShaderProgramImpl* shaderProgram = new ShaderProgramImpl(); + shaderProgram->dxComputeShader = dxComputeShader; + return (ShaderProgram*)shaderProgram; + } + else + { + auto dxVertexShaderBlob = compileHLSLShader(request.vertexShader.source.path, request.vertexShader.source.dataBegin, request.vertexShader.name, request.vertexShader.profile); + if (!dxVertexShaderBlob) return nullptr; - auto dxFragmentShaderBlob = compileHLSLShader(request.fragmentShader.source.path, request.fragmentShader.source.dataBegin, request.fragmentShader.name, request.fragmentShader.profile); - if (!dxFragmentShaderBlob) return nullptr; + auto dxFragmentShaderBlob = compileHLSLShader(request.fragmentShader.source.path, request.fragmentShader.source.dataBegin, request.fragmentShader.name, request.fragmentShader.profile); + if (!dxFragmentShaderBlob) return nullptr; - ID3D11VertexShader* dxVertexShader; - ID3D11PixelShader* dxPixelShader; + ID3D11VertexShader* dxVertexShader; + ID3D11PixelShader* dxPixelShader; - HRESULT vsResult = dxDevice->CreateVertexShader(dxVertexShaderBlob->GetBufferPointer(), dxVertexShaderBlob->GetBufferSize(), nullptr, &dxVertexShader); - HRESULT psResult = dxDevice->CreatePixelShader(dxFragmentShaderBlob->GetBufferPointer(), dxFragmentShaderBlob->GetBufferSize(), nullptr, &dxPixelShader); + HRESULT vsResult = dxDevice->CreateVertexShader(dxVertexShaderBlob->GetBufferPointer(), dxVertexShaderBlob->GetBufferSize(), nullptr, &dxVertexShader); + HRESULT psResult = dxDevice->CreatePixelShader(dxFragmentShaderBlob->GetBufferPointer(), dxFragmentShaderBlob->GetBufferSize(), nullptr, &dxPixelShader); - dxVertexShaderBlob->Release(); - dxFragmentShaderBlob->Release(); + dxVertexShaderBlob->Release(); + dxFragmentShaderBlob->Release(); - if (FAILED(vsResult)) return nullptr; - if (FAILED(psResult)) return nullptr; + if (FAILED(vsResult)) return nullptr; + if (FAILED(psResult)) return nullptr; - D3D11ShaderProgram* shaderProgram = new D3D11ShaderProgram(); - shaderProgram->dxVertexShader = dxVertexShader; - shaderProgram->dxPixelShader = dxPixelShader; - return (ShaderProgram*)shaderProgram; - } + ShaderProgramImpl* shaderProgram = new ShaderProgramImpl(); + shaderProgram->dxVertexShader = dxVertexShader; + shaderProgram->dxPixelShader = dxPixelShader; + return (ShaderProgram*)shaderProgram; } +} + +void D3D11Renderer::dispatchCompute(int x, int y, int z) +{ + auto dxContext = dxImmediateContext; + applyBindingState(true); + dxContext->Dispatch(x, y, z); +} - virtual void dispatchCompute(int x, int y, int z) override - { - auto dxContext = dxImmediateContext; - applyBindingState(true); - dxContext->Dispatch(x, y, z); - } - - void createInputBuffer( - InputBufferDesc & bufferDesc, - List<unsigned int> & bufferData, - ID3D11Buffer * &bufferOut, - ID3D11UnorderedAccessView * &viewOut, - ID3D11ShaderResourceView * &srvOut) +void D3D11Renderer::createInputBuffer(InputBufferDesc & bufferDesc, List<unsigned int> & bufferData, ID3D11Buffer * &bufferOut, + ID3D11UnorderedAccessView * &viewOut, ID3D11ShaderResourceView * &srvOut) +{ + auto dxContext = dxImmediateContext; + D3D11_BUFFER_DESC desc = { 0 }; + List<unsigned int> newBuffer; + desc.ByteWidth = (UINT)calcAligned((bufferData.Count() * sizeof(unsigned int)), 256); + newBuffer.SetSize(desc.ByteWidth / sizeof(unsigned int)); + for (UInt i = 0; i < bufferData.Count(); i++) + newBuffer[i] = bufferData[i]; + if (bufferDesc.type == InputBufferType::ConstantBuffer) { - auto dxContext = dxImmediateContext; - D3D11_BUFFER_DESC desc = {0}; - List<unsigned int> newBuffer; - desc.ByteWidth = (UINT)RoundUpToAlignment((bufferData.Count() * sizeof(unsigned int)), 256); - newBuffer.SetSize(desc.ByteWidth / sizeof(unsigned int)); - for (UInt i = 0; i < bufferData.Count(); i++) - newBuffer[i] = bufferData[i]; - if (bufferDesc.type == InputBufferType::ConstantBuffer) + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + } + else + { + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; + if (bufferDesc.stride != 0) { - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + desc.StructureByteStride = bufferDesc.stride; + desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; } else { - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; - if (bufferDesc.stride != 0) - { - desc.StructureByteStride = bufferDesc.stride; - desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; - } - else - { - desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; - } + desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; } - D3D11_SUBRESOURCE_DATA data = {0}; - data.pSysMem = newBuffer.Buffer(); - dxDevice->CreateBuffer(&desc, &data, &bufferOut); - int elemSize = bufferDesc.stride <= 0 ? 1 : bufferDesc.stride; - if (bufferDesc.type == InputBufferType::StorageBuffer) + } + D3D11_SUBRESOURCE_DATA data = { 0 }; + data.pSysMem = newBuffer.Buffer(); + dxDevice->CreateBuffer(&desc, &data, &bufferOut); + int elemSize = bufferDesc.stride <= 0 ? 1 : bufferDesc.stride; + if (bufferDesc.type == InputBufferType::StorageBuffer) + { + D3D11_UNORDERED_ACCESS_VIEW_DESC viewDesc; + memset(&viewDesc, 0, sizeof(viewDesc)); + viewDesc.Buffer.FirstElement = 0; + viewDesc.Buffer.NumElements = (UINT)(bufferData.Count() * sizeof(unsigned int) / elemSize); + viewDesc.Buffer.Flags = 0; + viewDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + viewDesc.Format = DXGI_FORMAT_UNKNOWN; + + if (bufferDesc.stride == 0) { - D3D11_UNORDERED_ACCESS_VIEW_DESC viewDesc; - memset(&viewDesc, 0, sizeof(viewDesc)); - viewDesc.Buffer.FirstElement = 0; - viewDesc.Buffer.NumElements = (UINT)(bufferData.Count() * sizeof(unsigned int) / elemSize); - viewDesc.Buffer.Flags = 0; - viewDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; - viewDesc.Format = DXGI_FORMAT_UNKNOWN; - - if( bufferDesc.stride == 0 ) - { - // TODO: are there UAV cases we need to handle that are neither - // raw nor structured? RWBuffer<T> would be one... + // TODO: are there UAV cases we need to handle that are neither + // raw nor structured? RWBuffer<T> would be one... - viewDesc.Buffer.Flags |= D3D11_BUFFER_UAV_FLAG_RAW; - viewDesc.Format = DXGI_FORMAT_R32_TYPELESS; - } - - dxDevice->CreateUnorderedAccessView(bufferOut, &viewDesc, &viewOut); - } - if (bufferDesc.type != InputBufferType::ConstantBuffer) - { - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - memset(&srvDesc, 0, sizeof(srvDesc)); - srvDesc.Buffer.FirstElement = 0; - srvDesc.Buffer.ElementWidth = elemSize; - srvDesc.Buffer.NumElements = (UINT)(bufferData.Count() * sizeof(unsigned int) / elemSize); - srvDesc.Buffer.ElementOffset = 0; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; - srvDesc.Format = DXGI_FORMAT_UNKNOWN; - dxDevice->CreateShaderResourceView(bufferOut, &srvDesc, &srvOut); + viewDesc.Buffer.Flags |= D3D11_BUFFER_UAV_FLAG_RAW; + viewDesc.Format = DXGI_FORMAT_R32_TYPELESS; } + + dxDevice->CreateUnorderedAccessView(bufferOut, &viewDesc, &viewOut); } + if (bufferDesc.type != InputBufferType::ConstantBuffer) + { + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + memset(&srvDesc, 0, sizeof(srvDesc)); + srvDesc.Buffer.FirstElement = 0; + srvDesc.Buffer.ElementWidth = elemSize; + srvDesc.Buffer.NumElements = (UINT)(bufferData.Count() * sizeof(unsigned int) / elemSize); + srvDesc.Buffer.ElementOffset = 0; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + srvDesc.Format = DXGI_FORMAT_UNKNOWN; + dxDevice->CreateShaderResourceView(bufferOut, &srvDesc, &srvOut); + } +} - void createInputTexture(const InputTextureDesc & inputDesc, ID3D11ShaderResourceView * &viewOut) +void D3D11Renderer::createInputTexture(const InputTextureDesc & inputDesc, ID3D11ShaderResourceView * &viewOut) +{ + TextureData texData; + generateTextureData(texData, inputDesc); + List<D3D11_SUBRESOURCE_DATA> subRes; + for (int i = 0; i < texData.arraySize; i++) { - TextureData texData; - generateTextureData(texData, inputDesc); - List<D3D11_SUBRESOURCE_DATA> subRes; - for (int i = 0; i < texData.arraySize; i++) - { - int slice = 0; - for (int j = 0; j < texData.mipLevels; j++) - { - int size = texData.textureSize >> j; - D3D11_SUBRESOURCE_DATA res; - res.pSysMem = texData.dataBuffer[slice].Buffer(); - res.SysMemPitch = sizeof(unsigned int) * size; - res.SysMemSlicePitch = sizeof(unsigned int) * size * size; - subRes.Add(res); - slice++; - } - } - if (inputDesc.dimension == 1) - { - D3D11_TEXTURE1D_DESC desc = { 0 }; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = 0; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.MiscFlags = 0; - desc.MipLevels = texData.mipLevels; - desc.ArraySize = texData.arraySize; - desc.Width = texData.textureSize; - desc.Usage = D3D11_USAGE_DEFAULT; - - ID3D11Texture1D * texture; - dxDevice->CreateTexture1D(&desc, subRes.Buffer(), &texture); - D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; - - viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; - if (inputDesc.arrayLength != 0) - viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; - viewDesc.Texture1D.MipLevels = texData.mipLevels; - viewDesc.Texture1D.MostDetailedMip = 0; - viewDesc.Texture1DArray.ArraySize = texData.arraySize; - viewDesc.Texture1DArray.FirstArraySlice = 0; - viewDesc.Texture1DArray.MipLevels = texData.mipLevels; - viewDesc.Texture1DArray.MostDetailedMip = 0; - viewDesc.Format = desc.Format; - dxDevice->CreateShaderResourceView(texture, &viewDesc, &viewOut); - } - else if (inputDesc.dimension == 2) - { - D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; - D3D11_TEXTURE2D_DESC desc = { 0 }; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = 0; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.MiscFlags = 0; - desc.MipLevels = texData.mipLevels; - desc.ArraySize = texData.arraySize; - if (inputDesc.isCube) - { - desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE; - viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - viewDesc.TextureCube.MipLevels = texData.mipLevels; - viewDesc.TextureCube.MostDetailedMip = 0; - viewDesc.TextureCubeArray.MipLevels = texData.mipLevels; - viewDesc.TextureCubeArray.MostDetailedMip = 0; - viewDesc.TextureCubeArray.First2DArrayFace = 0; - viewDesc.TextureCubeArray.NumCubes = inputDesc.arrayLength; - } - else - { - viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - viewDesc.Texture2D.MipLevels = texData.mipLevels; - viewDesc.Texture2D.MostDetailedMip = 0; - viewDesc.Texture2DArray.ArraySize = texData.arraySize; - viewDesc.Texture2DArray.FirstArraySlice = 0; - viewDesc.Texture2DArray.MipLevels = texData.mipLevels; - viewDesc.Texture2DArray.MostDetailedMip = 0; - } - if (inputDesc.arrayLength != 0) - viewDesc.ViewDimension = (D3D11_SRV_DIMENSION)(int)(viewDesc.ViewDimension + 1); - desc.Width = texData.textureSize; - desc.Height = texData.textureSize; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - viewDesc.Format = desc.Format; - ID3D11Texture2D * texture; - dxDevice->CreateTexture2D(&desc, subRes.Buffer(), &texture); - dxDevice->CreateShaderResourceView(texture, &viewDesc, &viewOut); - } - else if (inputDesc.dimension == 3) + int slice = 0; + for (int j = 0; j < texData.mipLevels; j++) { - D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; - D3D11_TEXTURE3D_DESC desc = { 0 }; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = 0; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.MiscFlags = 0; - desc.MipLevels = 1; - viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; - desc.Width = texData.textureSize; - desc.Height = texData.textureSize; - desc.Depth = texData.textureSize; - desc.Usage = D3D11_USAGE_DEFAULT; - ID3D11Texture3D * texture; - dxDevice->CreateTexture3D(&desc, subRes.Buffer(), &texture); - viewDesc.Texture3D.MipLevels = 1; - viewDesc.Texture3D.MostDetailedMip = 0; - viewDesc.Format = desc.Format; - dxDevice->CreateShaderResourceView(texture, &viewDesc, &viewOut); + int size = texData.textureSize >> j; + D3D11_SUBRESOURCE_DATA res; + res.pSysMem = texData.dataBuffer[slice].Buffer(); + res.SysMemPitch = sizeof(unsigned int) * size; + res.SysMemSlicePitch = sizeof(unsigned int) * size * size; + subRes.Add(res); + slice++; } } - - void createInputSampler(const InputSamplerDesc & inputDesc, ID3D11SamplerState * & stateOut) + if (inputDesc.dimension == 1) + { + D3D11_TEXTURE1D_DESC desc = { 0 }; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.MiscFlags = 0; + desc.MipLevels = texData.mipLevels; + desc.ArraySize = texData.arraySize; + desc.Width = texData.textureSize; + desc.Usage = D3D11_USAGE_DEFAULT; + + ID3D11Texture1D * texture; + dxDevice->CreateTexture1D(&desc, subRes.Buffer(), &texture); + D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; + + viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; + if (inputDesc.arrayLength != 0) + viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; + viewDesc.Texture1D.MipLevels = texData.mipLevels; + viewDesc.Texture1D.MostDetailedMip = 0; + viewDesc.Texture1DArray.ArraySize = texData.arraySize; + viewDesc.Texture1DArray.FirstArraySlice = 0; + viewDesc.Texture1DArray.MipLevels = texData.mipLevels; + viewDesc.Texture1DArray.MostDetailedMip = 0; + viewDesc.Format = desc.Format; + dxDevice->CreateShaderResourceView(texture, &viewDesc, &viewOut); + } + else if (inputDesc.dimension == 2) { - D3D11_SAMPLER_DESC desc; - memset(&desc, 0, sizeof(desc)); - desc.AddressU = desc.AddressV = desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; - if (inputDesc.isCompareSampler) + D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; + D3D11_TEXTURE2D_DESC desc = { 0 }; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.MiscFlags = 0; + desc.MipLevels = texData.mipLevels; + desc.ArraySize = texData.arraySize; + if (inputDesc.isCube) { - desc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL; - desc.Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT; - desc.MinLOD = desc.MaxLOD = 0.0f; + desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE; + viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + viewDesc.TextureCube.MipLevels = texData.mipLevels; + viewDesc.TextureCube.MostDetailedMip = 0; + viewDesc.TextureCubeArray.MipLevels = texData.mipLevels; + viewDesc.TextureCubeArray.MostDetailedMip = 0; + viewDesc.TextureCubeArray.First2DArrayFace = 0; + viewDesc.TextureCubeArray.NumCubes = inputDesc.arrayLength; } else { - desc.Filter = D3D11_FILTER_ANISOTROPIC; - desc.MaxAnisotropy = 8; - desc.MinLOD = 0.0f; - desc.MaxLOD = 100.0f; + viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + viewDesc.Texture2D.MipLevels = texData.mipLevels; + viewDesc.Texture2D.MostDetailedMip = 0; + viewDesc.Texture2DArray.ArraySize = texData.arraySize; + viewDesc.Texture2DArray.FirstArraySlice = 0; + viewDesc.Texture2DArray.MipLevels = texData.mipLevels; + viewDesc.Texture2DArray.MostDetailedMip = 0; } - dxDevice->CreateSamplerState(&desc, &stateOut); + if (inputDesc.arrayLength != 0) + viewDesc.ViewDimension = (D3D11_SRV_DIMENSION)(int)(viewDesc.ViewDimension + 1); + desc.Width = texData.textureSize; + desc.Height = texData.textureSize; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + viewDesc.Format = desc.Format; + ID3D11Texture2D * texture; + dxDevice->CreateTexture2D(&desc, subRes.Buffer(), &texture); + dxDevice->CreateShaderResourceView(texture, &viewDesc, &viewOut); + } + else if (inputDesc.dimension == 3) + { + D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; + D3D11_TEXTURE3D_DESC desc = { 0 }; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.MiscFlags = 0; + desc.MipLevels = 1; + viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + desc.Width = texData.textureSize; + desc.Height = texData.textureSize; + desc.Depth = texData.textureSize; + desc.Usage = D3D11_USAGE_DEFAULT; + ID3D11Texture3D * texture; + dxDevice->CreateTexture3D(&desc, subRes.Buffer(), &texture); + viewDesc.Texture3D.MipLevels = 1; + viewDesc.Texture3D.MostDetailedMip = 0; + viewDesc.Format = desc.Format; + dxDevice->CreateShaderResourceView(texture, &viewDesc, &viewOut); + } +} + +void D3D11Renderer::createInputSampler(const InputSamplerDesc & inputDesc, ID3D11SamplerState * & stateOut) +{ + D3D11_SAMPLER_DESC desc; + memset(&desc, 0, sizeof(desc)); + desc.AddressU = desc.AddressV = desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + if (inputDesc.isCompareSampler) + { + desc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL; + desc.Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT; + desc.MinLOD = desc.MaxLOD = 0.0f; + } + else + { + desc.Filter = D3D11_FILTER_ANISOTROPIC; + desc.MaxAnisotropy = 8; + desc.MinLOD = 0.0f; + desc.MaxLOD = 100.0f; } - virtual BindingState * createBindingState(const ShaderInputLayout & layout) + dxDevice->CreateSamplerState(&desc, &stateOut); +} + +BindingState * D3D11Renderer::createBindingState(const ShaderInputLayout& layout) +{ + BindingStateImpl * rs = new BindingStateImpl(); + rs->numRenderTargets = layout.numRenderTargets; + for (auto & entry : layout.entries) { - D3DBindingState * rs = new D3DBindingState(); - rs->numRenderTargets = layout.numRenderTargets; - for (auto & entry : layout.entries) + BindingImpl rsEntry; + rsEntry.type = entry.type; + rsEntry.binding = entry.hlslBinding; + rsEntry.isOutput = entry.isOutput; + switch (entry.type) { - D3DBinding rsEntry; - rsEntry.type = entry.type; - rsEntry.binding = entry.hlslBinding; - rsEntry.isOutput = entry.isOutput; - switch (entry.type) - { case ShaderInputType::Buffer: { createInputBuffer(entry.bufferDesc, entry.bufferData, rsEntry.buffer, rsEntry.uav, rsEntry.srv); @@ -1005,133 +1003,127 @@ public: throw "not implemented"; } break; - } - rs->bindings.Add(rsEntry); } - - return (BindingState*)rs; + rs->bindings.Add(rsEntry); } - void applyBindingState(bool isCompute) + return (BindingState*)rs; +} + +void D3D11Renderer::applyBindingState(bool isCompute) +{ + auto dxContext = dxImmediateContext; + for (auto & binding : currentBindings->bindings) { - auto dxContext = dxImmediateContext; - for (auto & binding : currentBindings->bindings) + if (binding.type == ShaderInputType::Buffer) { - if (binding.type == ShaderInputType::Buffer) + if (binding.bufferType == InputBufferType::ConstantBuffer) { - if (binding.bufferType == InputBufferType::ConstantBuffer) - { - if (isCompute) - dxContext->CSSetConstantBuffers(binding.binding, 1, &binding.buffer); - else - { - dxContext->VSSetConstantBuffers(binding.binding, 1, &binding.buffer); - dxContext->PSSetConstantBuffers(binding.binding, 1, &binding.buffer); - } - } - else if (binding.uav) - { - if (isCompute) - dxContext->CSSetUnorderedAccessViews(binding.binding, 1, &binding.uav, nullptr); - else - dxContext->OMSetRenderTargetsAndUnorderedAccessViews(currentBindings->numRenderTargets, - dxRenderTargetViews.Buffer(), nullptr, binding.binding, 1, &binding.uav, nullptr); - } + if (isCompute) + dxContext->CSSetConstantBuffers(binding.binding, 1, &binding.buffer); else { - if (isCompute) - dxContext->CSSetShaderResources(binding.binding, 1, &binding.srv); - else - { - dxContext->PSSetShaderResources(binding.binding, 1, &binding.srv); - dxContext->VSSetShaderResources(binding.binding, 1, &binding.srv); - } + dxContext->VSSetConstantBuffers(binding.binding, 1, &binding.buffer); + dxContext->PSSetConstantBuffers(binding.binding, 1, &binding.buffer); } } - else if (binding.type == ShaderInputType::Texture) + else if (binding.uav) { - if (binding.uav) - { - if (isCompute) - dxContext->CSSetUnorderedAccessViews(binding.binding, 1, &binding.uav, nullptr); - else - dxContext->OMSetRenderTargetsAndUnorderedAccessViews(D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, - nullptr, nullptr, binding.binding, 1, &binding.uav, nullptr); - } + if (isCompute) + dxContext->CSSetUnorderedAccessViews(binding.binding, 1, &binding.uav, nullptr); + else + dxContext->OMSetRenderTargetsAndUnorderedAccessViews(currentBindings->numRenderTargets, + dxRenderTargetViews.Buffer(), nullptr, binding.binding, 1, &binding.uav, nullptr); + } + else + { + if (isCompute) + dxContext->CSSetShaderResources(binding.binding, 1, &binding.srv); else { - if (isCompute) - dxContext->CSSetShaderResources(binding.binding, 1, &binding.srv); - else - { - dxContext->PSSetShaderResources(binding.binding, 1, &binding.srv); - dxContext->VSSetShaderResources(binding.binding, 1, &binding.srv); - } + dxContext->PSSetShaderResources(binding.binding, 1, &binding.srv); + dxContext->VSSetShaderResources(binding.binding, 1, &binding.srv); } } - else if (binding.type == ShaderInputType::Sampler) + } + else if (binding.type == ShaderInputType::Texture) + { + if (binding.uav) + { + if (isCompute) + dxContext->CSSetUnorderedAccessViews(binding.binding, 1, &binding.uav, nullptr); + else + dxContext->OMSetRenderTargetsAndUnorderedAccessViews(D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, + nullptr, nullptr, binding.binding, 1, &binding.uav, nullptr); + } + else { if (isCompute) - dxContext->CSSetSamplers(binding.binding, 1, &binding.samplerState); + dxContext->CSSetShaderResources(binding.binding, 1, &binding.srv); else { - dxContext->PSSetSamplers(binding.binding, 1, &binding.samplerState); - dxContext->VSSetSamplers(binding.binding, 1, &binding.samplerState); + dxContext->PSSetShaderResources(binding.binding, 1, &binding.srv); + dxContext->VSSetShaderResources(binding.binding, 1, &binding.srv); } } + } + else if (binding.type == ShaderInputType::Sampler) + { + if (isCompute) + dxContext->CSSetSamplers(binding.binding, 1, &binding.samplerState); else - throw "not implemented"; + { + dxContext->PSSetSamplers(binding.binding, 1, &binding.samplerState); + dxContext->VSSetSamplers(binding.binding, 1, &binding.samplerState); + } } + else + throw "not implemented"; } +} - virtual void setBindingState(BindingState * state) - { - auto dxBindingState = (D3DBindingState*) state; - currentBindings = dxBindingState; - } +void D3D11Renderer::setBindingState(BindingState* state) +{ + auto dxBindingState = (BindingStateImpl*)state; + currentBindings = dxBindingState; +} - virtual void serializeOutput(BindingState* state, const char * fileName) +void D3D11Renderer::serializeOutput(BindingState* state, const char* fileName) +{ + auto dxContext = dxImmediateContext; + auto dxBindingState = (BindingStateImpl*)state; + FILE * f = fopen(fileName, "wb"); + int id = 0; + for (auto & binding : dxBindingState->bindings) { - auto dxContext = dxImmediateContext; - auto dxBindingState = (D3DBindingState*)state; - FILE * f = fopen(fileName, "wb"); - int id = 0; - for (auto & binding : dxBindingState->bindings) + if (binding.isOutput) { - if (binding.isOutput) + if (binding.buffer) { - if (binding.buffer) - { - // create staging buffer - ID3D11Buffer* stageBuf; - D3D11_BUFFER_DESC bufDesc; - memset(&bufDesc, 0, sizeof(bufDesc)); - bufDesc.BindFlags = 0; - bufDesc.ByteWidth = (UINT)RoundUpToAlignment(binding.bufferLength, 256); - bufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - bufDesc.Usage = D3D11_USAGE_STAGING; - dxDevice->CreateBuffer(&bufDesc, nullptr, &stageBuf); - dxContext->CopyResource(stageBuf, binding.buffer); - auto ptr = (unsigned int *)map(stageBuf, MapFlavor::HostRead); - for (auto i = 0u; i < binding.bufferLength / sizeof(unsigned int); i++) - fprintf(f, "%X\n", ptr[i]); - unmap(stageBuf); - stageBuf->Release(); - } - else - { - printf("invalid output type at %d.\n", id); - } + // create staging buffer + ID3D11Buffer* stageBuf; + D3D11_BUFFER_DESC bufDesc; + memset(&bufDesc, 0, sizeof(bufDesc)); + bufDesc.BindFlags = 0; + bufDesc.ByteWidth = (UINT)calcAligned(binding.bufferLength, 256); + bufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + bufDesc.Usage = D3D11_USAGE_STAGING; + dxDevice->CreateBuffer(&bufDesc, nullptr, &stageBuf); + dxContext->CopyResource(stageBuf, binding.buffer); + auto ptr = (unsigned int *)map(stageBuf, MapFlavor::HostRead); + for (auto i = 0u; i < binding.bufferLength / sizeof(unsigned int); i++) + fprintf(f, "%X\n", ptr[i]); + unmap(stageBuf); + stageBuf->Release(); + } + else + { + printf("invalid output type at %d.\n", id); } - id++; } - fclose(f); + id++; } -}; - -Renderer* createD3D11Renderer() -{ - return new D3D11Renderer(); + fclose(f); } } // renderer_test |
