summaryrefslogtreecommitdiffstats
path: root/tools/render-test/render-d3d11.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2018-04-02 19:59:33 -0400
committerTim Foley <tfoleyNV@users.noreply.github.com>2018-04-02 16:59:33 -0700
commit38d5ef4764e9271ce2360f42b0759a236cddd9fe (patch)
tree6c8eafb72eb997167dd77e3d1d5abc3582c5789a /tools/render-test/render-d3d11.cpp
parent5a0273848aa4b854bb3c99a81701b044a8929bf8 (diff)
Feature/dx12 (#469)
* Fix signed/unsigned comparison warning. * Split out d3d functions that will work across dx11 and 12. * Improve slang-test/README.md around command line options. * Make Guid comparison honor alignment for comparisons, such that mechanism work on architectures that can only do aligned accesses. * Initial setup of D3D12 Renderer, with presentFrame and clearFrame. * More support for D3D12 * Added FreeList * Added D3D12CircularResourceHeap * First attempt at createBuffer * First pass at map/unmap. * First pass binding vertex/constant buffers, and setting up InputLayout. Note that memory is not kept in scope on binding yet. * First pass of D3DDescriptorHeap * Small tidy up in render-d3d11. Added D3DDescriptorHeap to project. * First pass at D3D12 bind state. * Fix typos in D3D12Resource * Tidy up Dx11 render binding a little to match more with Dx12 style. * First pass at Dx12 BindingState * Handling of the command list d3d12. Support for submitGpuWork and waitForGpu. * First attempt at Dx12 capture of backbuffer to file. * First attempt at D3D12 binding for graphics. * D3D12 setup viewport etc - does now render triangle in render0.hlsl. * First pass at support for compute on D3D12Renderer * Use spaces over tabs in D3DUtil * Tabs to spaces in D3D12DescriptorHeap * Convert tab->spaces on render-d3d12.cpp
Diffstat (limited to 'tools/render-test/render-d3d11.cpp')
-rw-r--r--tools/render-test/render-d3d11.cpp168
1 files changed, 39 insertions, 129 deletions
diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp
index fb3d44f4d..e65b12b2c 100644
--- a/tools/render-test/render-d3d11.cpp
+++ b/tools/render-test/render-d3d11.cpp
@@ -3,6 +3,7 @@
#include "options.h"
#include "render.h"
+#include "d3d-util.h"
// In order to use the Slang API, we need to include its header
@@ -66,7 +67,9 @@ public:
virtual void setConstantBuffers(UInt startSlot, UInt slotCount, Buffer*const* buffers, const UInt* offsets) override;
virtual void draw(UInt vertexCount, UInt startVertex) override;
virtual void dispatchCompute(int x, int y, int z) override;
-
+ virtual void submitGpuWork() override {}
+ virtual void waitForGpu() override {}
+
// ShaderCompiler implementation
virtual ShaderProgram* compileProgram(ShaderCompileRequest const& request) override;
@@ -111,22 +114,13 @@ public:
ComPtr<ID3D11InputLayout> m_layout;
};
- /// 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.
- /// Definition of the HLSL-to-bytecode compilation logic.
- static Result compileHLSLShader(char const* sourcePath, char const* source, char const* entryPointName, char const* dxProfileName, ComPtr<ID3DBlob>& shaderBlobOut);
/// Capture a texture to a file
static HRESULT captureTextureToFile(ID3D11Device* device, ID3D11DeviceContext* context, ID3D11Texture2D* texture, char const* outputPath);
void* map(ID3D11Buffer* buffer, MapFlavor flavor);
void unmap(ID3D11Buffer* buffer);
- Result createInputBuffer(InputBufferDesc& bufferDesc, const List<unsigned int>& bufferData,
+ Result createInputBuffer(const InputBufferDesc& bufferDesc, const List<unsigned int>& bufferData,
ComPtr<ID3D11Buffer>& bufferOut, ComPtr<ID3D11UnorderedAccessView>& viewOut, ComPtr<ID3D11ShaderResourceView>& srvOut);
Result createInputTexture(const InputTextureDesc& inputDesc, ComPtr<ID3D11ShaderResourceView>& viewOut);
@@ -153,84 +147,6 @@ 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 */Result D3D11Renderer::compileHLSLShader(char const* sourcePath, char const* source, char const* entryPointName, char const* dxProfileName, ComPtr<ID3DBlob>& shaderBlobOut)
-{
- // Rather than statically link against the `d3dcompile` library, we
- // dynamically load it.
- //
- // Note: A more realistic application would compile from HLSL text to D3D
- // shader bytecode as part of an offline process, rather than doing it
- // on-the-fly like this
- //
- static pD3DCompile compileFunc = nullptr;
- if (!compileFunc)
- {
- // TODO(tfoley): maybe want to search for one of a few versions of the DLL
- HMODULE compilerModule = LoadLibraryA("d3dcompiler_47.dll");
- if (!compilerModule)
- {
- fprintf(stderr, "error: failed load 'd3dcompiler_47.dll'\n");
- return SLANG_FAIL;
- }
-
- compileFunc = (pD3DCompile)GetProcAddress(compilerModule, "D3DCompile");
- if (!compileFunc)
- {
- fprintf(stderr, "error: failed load symbol 'D3DCompile'\n");
- return SLANG_FAIL;
- }
- }
-
- // For this example, we turn on debug output, and turn off all
- // optimization. A real application would only use these flags
- // when shader debugging is needed.
- UINT flags = 0;
- flags |= D3DCOMPILE_DEBUG;
- flags |= D3DCOMPILE_OPTIMIZATION_LEVEL0 | D3DCOMPILE_SKIP_OPTIMIZATION;
-
- // We will always define `__HLSL__` when compiling here, so that
- // input code can react differently to being compiled as pure HLSL.
- D3D_SHADER_MACRO defines[] = {
- { "__HLSL__", "1" },
- { nullptr, nullptr },
- };
-
- // The `D3DCompile` entry point takes a bunch of parameters, but we
- // don't really need most of them for Slang-generated code.
- ComPtr<ID3DBlob> shaderBlob;
- ComPtr<ID3DBlob> errorBlob;
-
- HRESULT hr = compileFunc(source, strlen(source), sourcePath, &defines[0], nullptr, entryPointName, dxProfileName, flags, 0,
- shaderBlob.writeRef(), errorBlob.writeRef());
-
- // If the HLSL-to-bytecode compilation produced any diagnostic messages
- // then we will print them out (whether or not the compilation failed).
- if (errorBlob)
- {
- ::fputs((const char*)errorBlob->GetBufferPointer(), stderr);
- ::fflush(stderr);
- ::OutputDebugStringA((const char*)errorBlob->GetBufferPointer());
- return SLANG_FAIL;
- }
-
- SLANG_RETURN_ON_FAIL(hr);
- shaderBlobOut.swap(shaderBlob);
- return SLANG_OK;
-}
-
/* static */HRESULT D3D11Renderer::captureTextureToFile(ID3D11Device* device, ID3D11DeviceContext* context,
ID3D11Texture2D* texture, char const* outputPath)
{
@@ -474,7 +390,7 @@ ShaderCompiler* D3D11Renderer::getShaderCompiler()
Buffer* D3D11Renderer::createBuffer(const BufferDesc& desc)
{
D3D11_BUFFER_DESC bufferDesc = { 0 };
- bufferDesc.ByteWidth = (UINT)calcAligned(desc.size, 256);
+ bufferDesc.ByteWidth = (UINT)D3DUtil::calcAligned(desc.size, 256);
switch (desc.flavor)
{
@@ -517,7 +433,7 @@ InputLayout* D3D11Renderer::createInputLayout(const InputElementDesc* inputEleme
{
inputElements[ii].SemanticName = inputElementsIn[ii].semanticName;
inputElements[ii].SemanticIndex = (UINT)inputElementsIn[ii].semanticIndex;
- inputElements[ii].Format = getMapFormat(inputElementsIn[ii].format);
+ inputElements[ii].Format = D3DUtil::getMapFormat(inputElementsIn[ii].format);
inputElements[ii].InputSlot = 0;
inputElements[ii].AlignedByteOffset = (UINT)inputElementsIn[ii].offset;
inputElements[ii].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
@@ -551,10 +467,10 @@ InputLayout* D3D11Renderer::createInputLayout(const InputElementDesc* inputEleme
hlslCursor += sprintf(hlslCursor, "\n) : SV_Position { return 0; }");
ComPtr<ID3DBlob> vertexShaderBlob;
- SLANG_RETURN_NULL_ON_FAIL(compileHLSLShader("inputLayout", hlslBuffer, "main", "vs_5_0", vertexShaderBlob));
+ SLANG_RETURN_NULL_ON_FAIL(D3DUtil::compileHLSLShader("inputLayout", hlslBuffer, "main", "vs_5_0", vertexShaderBlob));
ComPtr<ID3D11InputLayout> inputLayout;
- SLANG_RETURN_NULL_ON_FAIL(m_device->CreateInputLayout(&inputElements[0], (UINT)inputElementCount, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(),
+ SLANG_RETURN_NULL_ON_FAIL(m_device->CreateInputLayout(&inputElements[0], (UINT)inputElementCount, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(),
inputLayout.writeRef()));
InputLayoutImpl* impl = new InputLayoutImpl;
@@ -613,18 +529,7 @@ void D3D11Renderer::setInputLayout(InputLayout* inputLayoutIn)
void D3D11Renderer::setPrimitiveTopology(PrimitiveTopology topology)
{
- D3D11_PRIMITIVE_TOPOLOGY primTopology;
- switch (topology)
- {
- case PrimitiveTopology::TriangleList:
- primTopology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
- break;
-
- default:
- return;
- }
-
- m_immediateContext->IASetPrimitiveTopology(primTopology);
+ m_immediateContext->IASetPrimitiveTopology(D3DUtil::getPrimitiveTopology(topology));
}
void D3D11Renderer::setVertexBuffers(UInt startSlot, UInt slotCount, Buffer*const* buffersIn, const UInt* stridesIn, const UInt* offsetsIn)
@@ -687,7 +592,7 @@ ShaderProgram* D3D11Renderer::compileProgram(const ShaderCompileRequest& request
if (request.computeShader.name)
{
ComPtr<ID3DBlob> computeShaderBlob;
- SLANG_RETURN_NULL_ON_FAIL(compileHLSLShader(request.computeShader.source.path, request.computeShader.source.dataBegin, request.computeShader.name, request.computeShader.profile, computeShaderBlob));
+ SLANG_RETURN_NULL_ON_FAIL(D3DUtil::compileHLSLShader(request.computeShader.source.path, request.computeShader.source.dataBegin, request.computeShader.name, request.computeShader.profile, computeShaderBlob));
ComPtr<ID3D11ComputeShader> computeShader;
SLANG_RETURN_NULL_ON_FAIL(m_device->CreateComputeShader(computeShaderBlob->GetBufferPointer(), computeShaderBlob->GetBufferSize(), nullptr, computeShader.writeRef()));
@@ -699,8 +604,8 @@ ShaderProgram* D3D11Renderer::compileProgram(const ShaderCompileRequest& request
else
{
ComPtr<ID3DBlob> vertexShaderBlob, fragmentShaderBlob;
- SLANG_RETURN_NULL_ON_FAIL(compileHLSLShader(request.vertexShader.source.path, request.vertexShader.source.dataBegin, request.vertexShader.name, request.vertexShader.profile, vertexShaderBlob));
- SLANG_RETURN_NULL_ON_FAIL(compileHLSLShader(request.fragmentShader.source.path, request.fragmentShader.source.dataBegin, request.fragmentShader.name, request.fragmentShader.profile, fragmentShaderBlob));
+ SLANG_RETURN_NULL_ON_FAIL(D3DUtil::compileHLSLShader(request.vertexShader.source.path, request.vertexShader.source.dataBegin, request.vertexShader.name, request.vertexShader.profile, vertexShaderBlob));
+ SLANG_RETURN_NULL_ON_FAIL(D3DUtil::compileHLSLShader(request.fragmentShader.source.path, request.fragmentShader.source.dataBegin, request.fragmentShader.name, request.fragmentShader.profile, fragmentShaderBlob));
ComPtr<ID3D11VertexShader> vertexShader;
ComPtr<ID3D11PixelShader> pixelShader;
@@ -721,12 +626,12 @@ void D3D11Renderer::dispatchCompute(int x, int y, int z)
m_immediateContext->Dispatch(x, y, z);
}
-Result D3D11Renderer::createInputBuffer(InputBufferDesc& bufferDesc, const List<unsigned int>& bufferData,
+Result D3D11Renderer::createInputBuffer(const InputBufferDesc& bufferDesc, const List<unsigned int>& bufferData,
ComPtr<ID3D11Buffer>& bufferOut, ComPtr<ID3D11UnorderedAccessView>& viewOut, ComPtr<ID3D11ShaderResourceView>& srvOut)
{
D3D11_BUFFER_DESC desc = { 0 };
List<unsigned int> newBuffer;
- desc.ByteWidth = (UINT)calcAligned((bufferData.Count() * sizeof(unsigned int)), 256);
+ desc.ByteWidth = (UINT)D3DUtil::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];
@@ -939,32 +844,42 @@ Result D3D11Renderer::createInputSampler(const InputSamplerDesc& inputDesc, ComP
BindingState* D3D11Renderer::createBindingState(const ShaderInputLayout& layout)
{
- List<Binding> bindings;
+ RefPtr<BindingStateImpl> bindingState(new BindingStateImpl);
+
+ const List<ShaderInputLayoutEntry>& srcBindings = layout.entries;
+ const int numBindings = int(srcBindings.Count());
- for (auto & entry : layout.entries)
+ List<Binding>& dstBindings = bindingState->m_bindings;
+ dstBindings.SetSize(numBindings);
+
+ bindingState->m_numRenderTargets = layout.numRenderTargets;
+
+ for (int i = 0; i < numBindings; ++i)
{
- Binding rsEntry;
- rsEntry.type = entry.type;
- rsEntry.binding = entry.hlslBinding;
- rsEntry.isOutput = entry.isOutput;
- switch (entry.type)
+ Binding& dstBinding = dstBindings[i];
+ const ShaderInputLayoutEntry& srcBinding = srcBindings[i];
+
+ dstBinding.type = srcBinding.type;
+ dstBinding.binding = srcBinding.hlslBinding;
+ dstBinding.isOutput = srcBinding.isOutput;
+ switch (srcBinding.type)
{
case ShaderInputType::Buffer:
{
- SLANG_RETURN_NULL_ON_FAIL(createInputBuffer(entry.bufferDesc, entry.bufferData, rsEntry.buffer, rsEntry.uav, rsEntry.srv));
+ SLANG_RETURN_NULL_ON_FAIL(createInputBuffer(srcBinding.bufferDesc, srcBinding.bufferData, dstBinding.buffer, dstBinding.uav, dstBinding.srv));
- rsEntry.bufferLength = (int)(entry.bufferData.Count() * sizeof(unsigned int));
- rsEntry.bufferType = entry.bufferDesc.type;
+ dstBinding.bufferLength = (int)(srcBinding.bufferData.Count() * sizeof(unsigned int));
+ dstBinding.bufferType = srcBinding.bufferDesc.type;
break;
}
case ShaderInputType::Texture:
{
- SLANG_RETURN_NULL_ON_FAIL(createInputTexture(entry.textureDesc, rsEntry.srv));
+ SLANG_RETURN_NULL_ON_FAIL(createInputTexture(srcBinding.textureDesc, dstBinding.srv));
break;
}
case ShaderInputType::Sampler:
{
- SLANG_RETURN_NULL_ON_FAIL(createInputSampler(entry.samplerDesc, rsEntry.samplerState));
+ SLANG_RETURN_NULL_ON_FAIL(createInputSampler(srcBinding.samplerDesc, dstBinding.samplerState));
break;
}
case ShaderInputType::CombinedTextureSampler:
@@ -975,14 +890,9 @@ BindingState* D3D11Renderer::createBindingState(const ShaderInputLayout& layout)
break;
}
}
- bindings.Add(rsEntry);
}
- BindingStateImpl* rs = new BindingStateImpl;
- rs->m_numRenderTargets = layout.numRenderTargets;
- rs->m_bindings.SwapWith(bindings);
-
- return rs;
+ return bindingState.detach();
}
void D3D11Renderer::applyBindingState(bool isCompute)
@@ -1079,7 +989,7 @@ void D3D11Renderer::serializeOutput(BindingState* stateIn, const char* fileName)
D3D11_BUFFER_DESC bufDesc;
memset(&bufDesc, 0, sizeof(bufDesc));
bufDesc.BindFlags = 0;
- bufDesc.ByteWidth = (UINT)calcAligned(binding.bufferLength, 256);
+ bufDesc.ByteWidth = (UINT)D3DUtil::calcAligned(binding.bufferLength, 256);
bufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
bufDesc.Usage = D3D11_USAGE_STAGING;