diff options
| author | lbavoil <[email protected]> | 2016-03-25 13:01:54 +0100 |
|---|---|---|
| committer | lbavoil <[email protected]> | 2016-03-25 13:01:54 +0100 |
| commit | 99174e4e5fb4b7079da80b35a6dfd68f3fd56a1c (patch) | |
| tree | fbcd4260d6c953d569a887505336a1c3f202e10f /samples/D3D12/src | |
| download | hbaoplus-99174e4e5fb4b7079da80b35a6dfd68f3fd56a1c.tar.xz hbaoplus-99174e4e5fb4b7079da80b35a6dfd68f3fd56a1c.zip | |
GFSDK_HBAO+_distro_r3.0_cl20573789
Diffstat (limited to 'samples/D3D12/src')
| -rw-r--r-- | samples/D3D12/src/BinMeshReader.h | 60 | ||||
| -rw-r--r-- | samples/D3D12/src/SSAO12_2015.sln | 28 | ||||
| -rw-r--r-- | samples/D3D12/src/SibenikIndices.bin | bin | 0 -> 939564 bytes | |||
| -rw-r--r-- | samples/D3D12/src/SibenikVertices.bin | bin | 0 -> 1189884 bytes | |||
| -rw-r--r-- | samples/D3D12/src/Viewer.cpp | 1216 | ||||
| -rw-r--r-- | samples/D3D12/src/Viewer.hlsl | 40 | ||||
| -rw-r--r-- | samples/D3D12/src/Viewer.vcxproj | 229 | ||||
| -rw-r--r-- | samples/D3D12/src/Viewer.vcxproj.filters | 57 | ||||
| -rw-r--r-- | samples/D3D12/src/WaveFrontReader.h | 541 | ||||
| -rw-r--r-- | samples/D3D12/src/d3dx12.h | 1508 | ||||
| -rw-r--r-- | samples/D3D12/src/d3dx12p.h | 1590 |
11 files changed, 5269 insertions, 0 deletions
diff --git a/samples/D3D12/src/BinMeshReader.h b/samples/D3D12/src/BinMeshReader.h new file mode 100644 index 0000000..2b1679b --- /dev/null +++ b/samples/D3D12/src/BinMeshReader.h @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2008-2016, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#pragma once + +bool LoadVertices(const WCHAR* FileName, std::vector<Vertex>& OutVertices) +{ + FILE* fp = _wfopen(FileName, L"rb"); + if (!fp) return false; + + fseek(fp, 0L, SEEK_END); + UINT FileSize = ftell(fp); + fseek(fp, 0L, SEEK_SET); + + UINT NumVertices = FileSize / sizeof(Vertex::position); + + for (UINT Idx = 0; Idx < NumVertices; ++Idx) + { + Vertex vertex; + fread(&vertex.position, sizeof(XMFLOAT3), 1, fp); + vertex.normal.x = vertex.normal.y = 0; + vertex.normal.z = 1.0; + vertex.textureCoordinate.x = vertex.textureCoordinate.y = 0; + OutVertices.push_back(vertex); + } + + fclose(fp); + return true; +} + +bool LoadIndices(const WCHAR* FileName, std::vector<uint32_t>& OutIndices) +{ + FILE* fp = _wfopen(FileName, L"rb"); + if (!fp) return false; + + fseek(fp, 0L, SEEK_END); + UINT FileSize = ftell(fp); + fseek(fp, 0L, SEEK_SET); + + UINT NumIndices = FileSize / sizeof(uint32_t); + + for (UINT Idx = 0; Idx < NumIndices; ++Idx) + { + uint32_t index; + fread(&index, sizeof(index), 1, fp); + OutIndices.push_back(index); + } + + fclose(fp); + return true; +} + + diff --git a/samples/D3D12/src/SSAO12_2015.sln b/samples/D3D12/src/SSAO12_2015.sln new file mode 100644 index 0000000..d0f2f76 --- /dev/null +++ b/samples/D3D12/src/SSAO12_2015.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Viewer", "Viewer.vcxproj", "{CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Debug|x64.ActiveCfg = Debug|x64 + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Debug|x64.Build.0 = Debug|x64 + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Debug|x86.ActiveCfg = Debug|Win32 + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Debug|x86.Build.0 = Debug|Win32 + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Release|x64.ActiveCfg = Release|x64 + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Release|x64.Build.0 = Release|x64 + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Release|x86.ActiveCfg = Release|Win32 + {CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/samples/D3D12/src/SibenikIndices.bin b/samples/D3D12/src/SibenikIndices.bin Binary files differnew file mode 100644 index 0000000..8775c0c --- /dev/null +++ b/samples/D3D12/src/SibenikIndices.bin diff --git a/samples/D3D12/src/SibenikVertices.bin b/samples/D3D12/src/SibenikVertices.bin Binary files differnew file mode 100644 index 0000000..561d39e --- /dev/null +++ b/samples/D3D12/src/SibenikVertices.bin diff --git a/samples/D3D12/src/Viewer.cpp b/samples/D3D12/src/Viewer.cpp new file mode 100644 index 0000000..e445ffd --- /dev/null +++ b/samples/D3D12/src/Viewer.cpp @@ -0,0 +1,1216 @@ +/* +* Copyright (c) 2008-2016, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include <Windows.h> +#include <tchar.h> +#include <wrl/client.h> +#include <stdexcept> +#include <dxgi1_4.h> +#include <d3d12.h> +#include <d3dcompiler.h> +#include <d3dx12.h> +#include <d3dx12p.h> + +#include <DirectXMath.h> + +// For UI rendering +#include <imgui.h> +#include "imgui_impl_dx12.h" + +#include <string> +#include <vector> + +// Header for HBAO+ +#include "GFSDK_SSAO.h" + +// Library link for HBAO+ +#ifdef _WIN64 +#pragma comment(lib, "GFSDK_SSAO_D3D12.win64.lib") +#else +#pragma comment(lib, "GFSDK_SSAO_D3D12.win32.lib") +#endif + +// Use binary mesh reader or obj reader +#define USE_BIN_MESH_READER 1 + +// MSAA sample count for Viewer application +#define MSAA_SAMPLE_COUNT 1 + +#define SRC_PATH L"..\\src\\" +#define HLSL_FILE_PATH SRC_PATH L"Viewer.hlsl" +#define VERTEX_BIN_FILE_PATH SRC_PATH L"SibenikVertices.bin" +#define INDEX_BIN_FILE_PATH SRC_PATH L"SibenikIndices.bin" + +using namespace std; +using namespace DirectX; +using Microsoft::WRL::ComPtr; + +struct Vertex +{ + DirectX::XMFLOAT3 position; + DirectX::XMFLOAT3 normal; + DirectX::XMFLOAT2 textureCoordinate; +}; + +struct Mesh +{ + std::vector<Vertex> vertices; + std::vector<uint32_t> indices; +}; + +// For mesh loading +#if USE_BIN_MESH_READER +#include "BinMeshReader.h" +#else +#include "WaveFrontReader.h" +#endif + +#pragma comment(lib, "dxgi.lib") +#pragma comment(lib, "d3d12.lib") +#pragma comment(lib, "d3dcompiler.lib") + +namespace +{ + int gWindowWidth = 1280; + int gWindowHeight = 720; + bool gIsWindowed = true; + int gAdapterIndex = -1; + HWND gMainWindowHandle = 0; + float gCameraDistance = 1.0f; + float gModelRotation = 90.0f; + bool gUseSSAO = true; + bool gDrawUI = true; + std::string gSelectedGraphicsAdapter; + DXGI_FORMAT gColorTextureFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + DXGI_FORMAT gNormalTextureFormat = DXGI_FORMAT_R32G32B32A32_FLOAT; + DXGI_FORMAT gDepthTextureFormat = DXGI_FORMAT_D32_FLOAT; +}; + +void CHK(HRESULT hr) +{ + if (FAILED(hr)) + throw runtime_error("HRESULT is failed value."); +} + +class D3D +{ +public: + // Number of swap chains + static const UINT FrameCount = 4; + + ComPtr<IDXGIFactory4> mDxgiFactory; + ComPtr<IDXGISwapChain3> mSwapChain; + + int mBufferWidth, mBufferHeight; + UINT mFrameIndex = 0; + + ID3D12Device* mDev; + ComPtr<ID3D12CommandAllocator> mCmdAllocs[FrameCount]; + ComPtr<ID3D12CommandQueue> mCmdQueue; + + ComPtr<ID3D12GraphicsCommandList> mCmdList; + + ComPtr<ID3D12Fence> mFence; + UINT64 mFenceValues[FrameCount]; + HANDLE mFenceEvent = 0; + + ComPtr<ID3D12DescriptorHeap> mDescHeapRtv; + ComPtr<ID3D12DescriptorHeap> mDescHeapDsv; + ComPtr<ID3D12DescriptorHeap> mDescHeapCbvSrvUav; + ComPtr<ID3D12DescriptorHeap> mDescHeapSampler; + ComPtr<ID3D12DescriptorHeap> mSsaoDescHeapCbvSrvUav; + + ComPtr<ID3D12RootSignature> mRootSignature; + ComPtr<ID3D12PipelineState> mPso; + + ComPtr<ID3D12Resource> mVB; + D3D12_VERTEX_BUFFER_VIEW mVBView = {}; + D3D12_INDEX_BUFFER_VIEW mIBView = {}; + UINT mIndexCount = 0; + UINT mVBIndexOffset = 0; + + ComPtr<ID3D12Resource> mDepthBuffer; + ComPtr<ID3D12Resource> mConstantBuffer; + void* mCBUploadPtr = nullptr; + + // Normal buffer and render target + ComPtr<ID3D12Resource> mNormalBuffer[FrameCount]; + GFSDK_SSAO_RenderTargetView_D3D12 mNormalRTV[FrameCount]; + GFSDK_SSAO_ShaderResourceView_D3D12 mNormalSRV[FrameCount]; + + // Color buffer and render target + ComPtr<ID3D12Resource> mColorBuffer[FrameCount]; + GFSDK_SSAO_RenderTargetView_D3D12 mColorRTV[FrameCount]; + + // HBAO+ context and parameter + GFSDK_SSAO_Context_D3D12* mSSAO; + GFSDK_SSAO_Parameters mAOParams; + +public: + //-------------------------------------------------------------------------------- + D3D(int Width, int Height, HWND hWnd, BOOL IsWindowed, INT AdapterIndex) + : mBufferWidth(Width), mBufferHeight(Height), mDev(nullptr), mFrameIndex(0), mSSAO(nullptr) + { + CHK(CreateDXGIFactory1(IID_PPV_ARGS(mDxgiFactory.ReleaseAndGetAddressOf()))); + +#if _DEBUG + ID3D12Debug* debug = nullptr; + D3D12GetDebugInterface(IID_PPV_ARGS(&debug)); + if (debug) + { + debug->EnableDebugLayer(); + debug->Release(); + debug = nullptr; + } +#endif /* _DEBUG */ + + ZeroMemory(mFenceValues, sizeof(mFenceValues)); + + ID3D12Device* dev = nullptr; + bool UseWarpDevice = false; + + if (UseWarpDevice) + { + ComPtr<IDXGIAdapter> warpAdapter; + CHK(mDxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter))); + + CHK(D3D12CreateDevice( + warpAdapter.Get(), + D3D_FEATURE_LEVEL_11_0, + IID_PPV_ARGS(&dev) + )); + } + else + { + ComPtr<IDXGIAdapter> Adapter; + UINT NumAdapters = 0; + std::vector< ComPtr<IDXGIAdapter> > Adapters; + for (UINT idx = 0; mDxgiFactory->EnumAdapters(idx, Adapter.GetAddressOf()) != DXGI_ERROR_NOT_FOUND; ++idx) + { + DXGI_ADAPTER_DESC AdapterDesc; + Adapter->GetDesc(&AdapterDesc); + // GPU name : adapter_desc.Description + wchar_t buff[1024]; + swprintf(buff, L"Graphics Adapter(%d) : %s\n", idx, &AdapterDesc.Description); + OutputDebugStringW(buff); + Adapters.push_back(Adapter); + NumAdapters++; + } + + if ((AdapterIndex >= 0) && (AdapterIndex < (INT)NumAdapters)) + { + Adapter = Adapters[AdapterIndex]; + } + else + { + Adapter = Adapters[0]; + } + + DXGI_ADAPTER_DESC AdapterDesc; + Adapter->GetDesc(&AdapterDesc); + std::wstring DescW = AdapterDesc.Description; + std::string DescA = std::string(DescW.begin(), DescW.end()); + gSelectedGraphicsAdapter = DescA; + Adapters.push_back(Adapter); + + CHK(D3D12CreateDevice(Adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&dev))); + } + + mDev = dev; + + const UINT NodeMask = 1; + + for (UINT n = 0; n < FrameCount; n++) + { + CHK(mDev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&mCmdAllocs[n]))); + } + + D3D12_COMMAND_QUEUE_DESC queueDesc = {}; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + queueDesc.NodeMask = NodeMask; + CHK(mDev->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(mCmdQueue.ReleaseAndGetAddressOf()))); + + CHK(mDev->CreateCommandList(NodeMask, D3D12_COMMAND_LIST_TYPE_DIRECT, mCmdAllocs[mFrameIndex].Get(), nullptr, IID_PPV_ARGS(&mCmdList))); + +#define SSAO_NUM_DEPTH_SRV 1 +#define SSAO_NUM_NORMAL_SRV FrameCount +#define SSAO_NUM_SRV (SSAO_NUM_DEPTH_SRV + SSAO_NUM_NORMAL_SRV + GFSDK_SSAO_NUM_DESCRIPTORS_CBV_SRV_UAV_HEAP_D3D12) + +#define IMGUI_NUM_CBV 1 +#define IMGUI_NUM_SRV 1 + +#define VIEWER_NUM_CBV 1 +#define VIEWER_NUM_COLOR_RTV FrameCount +#define VIEWER_NUM_NORMAL_RTV FrameCount + +#define VIEWER_NUM_RTV (VIEWER_NUM_COLOR_RTV + VIEWER_NUM_NORMAL_RTV) +#define VIEWER_NUM_DSV 1 +#define VIEWER_NUM_SAMPLER 0 + + { + D3D12_DESCRIPTOR_HEAP_DESC desc = {}; + + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + desc.NumDescriptors = VIEWER_NUM_RTV + GFSDK_SSAO_NUM_DESCRIPTORS_RTV_HEAP_D3D12; + desc.NodeMask = NodeMask; + CHK(mDev->CreateDescriptorHeap(&desc, IID_PPV_ARGS(mDescHeapRtv.ReleaseAndGetAddressOf()))); + mDescHeapRtv->SetName(L"ViewerDescHeapRtv"); + + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; + desc.NumDescriptors = VIEWER_NUM_DSV; + desc.NodeMask = NodeMask; + CHK(mDev->CreateDescriptorHeap(&desc, IID_PPV_ARGS(mDescHeapDsv.ReleaseAndGetAddressOf()))); + mDescHeapDsv->SetName(L"ViewerDescHeapDsv"); + + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + desc.NumDescriptors = VIEWER_NUM_CBV + IMGUI_NUM_CBV + IMGUI_NUM_SRV; + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + desc.NodeMask = NodeMask; + CHK(mDev->CreateDescriptorHeap(&desc, IID_PPV_ARGS(mDescHeapCbvSrvUav.ReleaseAndGetAddressOf()))); + mDescHeapCbvSrvUav->SetName(L"ViewerDescHeapCbvSrvUav"); + + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; + desc.NumDescriptors = VIEWER_NUM_SAMPLER; + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + desc.NodeMask = NodeMask; + if (desc.NumDescriptors > 0) + { + CHK(mDev->CreateDescriptorHeap(&desc, IID_PPV_ARGS(mDescHeapSampler.ReleaseAndGetAddressOf()))); + mDescHeapSampler->SetName(L"ViewerDescHeapSampler"); + } + } + + // Create a desc heap for SSAO + { + D3D12_DESCRIPTOR_HEAP_DESC desc = {}; + + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + desc.NumDescriptors = SSAO_NUM_SRV; + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + desc.NodeMask = NodeMask; + CHK(mDev->CreateDescriptorHeap(&desc, IID_PPV_ARGS(mSsaoDescHeapCbvSrvUav.ReleaseAndGetAddressOf()))); + mSsaoDescHeapCbvSrvUav->SetName(L"ViewerSsaoDescHeapCbvSrvUav"); + } + + CHK(mDev->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(mFence.ReleaseAndGetAddressOf()))); + mFence->SetName(L"ViewerFence"); + + mFenceValues[mFrameIndex]++; + + mFenceEvent = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS); + + ResizeD3D(hWnd, Width, Height, IsWindowed); + + { + CD3DX12_DESCRIPTOR_RANGE descRange1[1]; + descRange1[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); + + CD3DX12_ROOT_PARAMETER rootParam[1]; + rootParam[0].InitAsDescriptorTable(ARRAYSIZE(descRange1), descRange1); + + ID3D10Blob *sig, *info; + auto rootSigDesc = D3D12_ROOT_SIGNATURE_DESC(); + rootSigDesc.NumParameters = 1; + rootSigDesc.NumStaticSamplers = 0; + rootSigDesc.pParameters = rootParam; + rootSigDesc.pStaticSamplers = nullptr; + rootSigDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + CHK(D3D12SerializeRootSignature(&rootSigDesc, D3D_ROOT_SIGNATURE_VERSION_1, &sig, &info)); + mDev->CreateRootSignature( + 0, + sig->GetBufferPointer(), + sig->GetBufferSize(), + IID_PPV_ARGS(mRootSignature.ReleaseAndGetAddressOf())); + mRootSignature->SetName(L"ViewerRS"); + sig->Release(); + } + + ID3D10Blob *vs, *ps; + { + ID3D10Blob *info; + UINT flag = 0; +#if _DEBUG + flag |= D3DCOMPILE_DEBUG; +#endif /* _DEBUG */ + CHK(D3DCompileFromFile(HLSL_FILE_PATH, nullptr, nullptr, "VSMain", "vs_5_0", flag, 0, &vs, &info)); + CHK(D3DCompileFromFile(HLSL_FILE_PATH, nullptr, nullptr, "PSMain", "ps_5_0", flag, 0, &ps, &info)); + } + D3D12_INPUT_ELEMENT_DESC inputLayout[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + }; + + D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; + psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + psoDesc.InputLayout.NumElements = 3; + psoDesc.InputLayout.pInputElementDescs = inputLayout; + psoDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED; + psoDesc.pRootSignature = mRootSignature.Get(); + psoDesc.VS.pShaderBytecode = vs->GetBufferPointer(); + psoDesc.VS.BytecodeLength = vs->GetBufferSize(); + psoDesc.PS.pShaderBytecode = ps->GetBufferPointer(); + psoDesc.PS.BytecodeLength = ps->GetBufferSize(); + psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); + psoDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; + psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); + psoDesc.DepthStencilState.DepthEnable = true; + psoDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL; + psoDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + psoDesc.DepthStencilState.StencilEnable = false; + psoDesc.SampleMask = UINT_MAX; + psoDesc.NumRenderTargets = 1; + psoDesc.RTVFormats[0] = gNormalTextureFormat; + psoDesc.DSVFormat = gDepthTextureFormat; + psoDesc.SampleDesc.Count = MSAA_SAMPLE_COUNT; + CHK(mDev->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(mPso.ReleaseAndGetAddressOf()))); + mPso->SetName(L"ViewerPSO"); + vs->Release(); + ps->Release(); + +#if (USE_BIN_MESH_READER) + Mesh mesh; + LoadVertices(VERTEX_BIN_FILE_PATH, mesh.vertices); + LoadIndices(INDEX_BIN_FILE_PATH, mesh.indices); +#else + WaveFrontReader<uint32_t> mesh; + CHK(mesh.Load(L"sibenik.obj")); +#endif + + mIndexCount = static_cast<UINT>(mesh.indices.size()); + mVBIndexOffset = static_cast<UINT>(sizeof(mesh.vertices[0]) * mesh.vertices.size()); + UINT IBSize = static_cast<UINT>(sizeof(mesh.indices[0]) * mIndexCount); + + void* vbData = mesh.vertices.data(); + void* ibData = mesh.indices.data(); + CHK(mDev->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer(mVBIndexOffset + IBSize), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(mVB.ReleaseAndGetAddressOf()))); + mVB->SetName(L"VertexBuffer"); + + char* vbUploadPtr = nullptr; + CHK(mVB->Map(0, nullptr, reinterpret_cast<void**>(&vbUploadPtr))); + memcpy_s(vbUploadPtr, mVBIndexOffset, vbData, mVBIndexOffset); + memcpy_s(vbUploadPtr + mVBIndexOffset, IBSize, ibData, IBSize); + mVB->Unmap(0, nullptr); + + mVBView.BufferLocation = mVB->GetGPUVirtualAddress(); + mVBView.StrideInBytes = sizeof(mesh.vertices[0]); + mVBView.SizeInBytes = mVBIndexOffset; + mIBView.BufferLocation = mVB->GetGPUVirtualAddress() + mVBIndexOffset; + mIBView.Format = (sizeof(mesh.indices[0]) == 2) ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT; + mIBView.SizeInBytes = IBSize; + + // Constant buffer + CHK(mDev->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer(D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(mConstantBuffer.ReleaseAndGetAddressOf()))); + mConstantBuffer->SetName(L"ViewerConstantBuffer"); + + D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {}; + cbvDesc.BufferLocation = mConstantBuffer->GetGPUVirtualAddress(); + cbvDesc.SizeInBytes = D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT; // must be a multiple of 256 + mDev->CreateConstantBufferView(&cbvDesc, mDescHeapCbvSrvUav->GetCPUDescriptorHandleForHeapStart()); + CHK(mConstantBuffer->Map(0, nullptr, reinterpret_cast<void**>(&mCBUploadPtr))); + + InitSSAO(); + + mAOParams = {}; + mAOParams.Radius = 2.f; + mAOParams.Bias = 0.2f; + mAOParams.PowerExponent = 2.f; + mAOParams.Blur.Enable = true; + mAOParams.Blur.Sharpness = 32.f; + mAOParams.Blur.Radius = GFSDK_SSAO_BLUR_RADIUS_4; + + ImGui_ImplDX12_Init(hWnd, dev, mCmdQueue.Get(), mCmdList.Get(), mDescHeapCbvSrvUav.Get(), VIEWER_NUM_CBV); + } + + //-------------------------------------------------------------------------------- + void Release() + { + ReleaseSSAO(); + ImGui_ImplDX12_Shutdown(); + + mConstantBuffer->Unmap(0, nullptr); + CloseHandle(mFenceEvent); + for (UINT Idx = 0; Idx < FrameCount; ++Idx) + { + mCmdAllocs[Idx].Reset(); + mColorBuffer[Idx].Reset(); + mNormalBuffer[Idx].Reset(); + } + mCmdList.Reset(); + mFence.Reset(); + mCmdQueue.Reset(); + mSsaoDescHeapCbvSrvUav.Reset(); + mDescHeapCbvSrvUav.Reset(); + mDescHeapDsv.Reset(); + mDescHeapRtv.Reset(); + mDescHeapSampler.Reset(); + if (mSwapChain) + { + mSwapChain->SetFullscreenState(FALSE, NULL); + mSwapChain.Reset(); + } + mConstantBuffer.Reset(); + mDepthBuffer.Reset(); + mDxgiFactory.Reset(); + mPso.Reset(); + mRootSignature.Reset(); + mVB.Reset(); + } + + //-------------------------------------------------------------------------------- + ~D3D() + { + Release(); + } + + //-------------------------------------------------------------------------------- + void ResizeD3D(HWND hWnd, int Width, int Height, BOOL IsWindowed) + { + if (!mDev) + { + return; + } + + DXGI_SWAP_CHAIN_DESC scDesc = {}; + scDesc.BufferCount = FrameCount; + scDesc.BufferDesc.Width = Width; + scDesc.BufferDesc.Height = Height; + scDesc.BufferDesc.Format = gColorTextureFormat; + scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + //scDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; // For better framerate in windowed mode, but it won't allow fullscreen switching + scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + scDesc.OutputWindow = hWnd; + scDesc.SampleDesc.Count = 1; + scDesc.SampleDesc.Quality = 0; + scDesc.Windowed = IsWindowed; + + WaitForGpuIdle(); + + // Release color/normal render targets before calling ResizeBuffers(). + // Also reset the frame fence values. + for (UINT Idx = 0; Idx < FrameCount; ++Idx) + { + mColorBuffer[Idx].Reset(); + mNormalBuffer[Idx].Reset(); + mFenceValues[Idx] = mFenceValues[mFrameIndex]; + } + + ComPtr<IDXGISwapChain> swapChain; + if (!mSwapChain) + { + CHK(mDxgiFactory->CreateSwapChain(mCmdQueue.Get(), &scDesc, &swapChain)); + swapChain.As(&mSwapChain); + } + + DXGI_SWAP_CHAIN_DESC desc = {}; + mSwapChain->GetDesc(&desc); + CHK(mSwapChain->ResizeBuffers(FrameCount, Width, Height, gColorTextureFormat, desc.Flags)); + + mBufferWidth = Width; + mBufferHeight = Height; + + mFrameIndex = mSwapChain->GetCurrentBackBufferIndex(); + + for (UINT i = 0; i < FrameCount; i++) + { + CHK(mSwapChain->GetBuffer(i, IID_PPV_ARGS(mColorBuffer[i].ReleaseAndGetAddressOf()))); + mColorBuffer[i]->SetName(L"SwapChain_Buffer"); + } + + for (UINT FrameIndex = 0; FrameIndex < FrameCount; ++FrameIndex) + { + // Create color buffer RTV + { + D3D12_RENDER_TARGET_VIEW_DESC colorRTVDesc = {}; + colorRTVDesc.Format = gColorTextureFormat; + colorRTVDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + + CD3DX12_CPU_DESCRIPTOR_HANDLE ColorRTV( + mDescHeapRtv->GetCPUDescriptorHandleForHeapStart(), + FrameIndex * mDev->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV)); + mDev->CreateRenderTargetView(mColorBuffer[FrameIndex].Get(), &colorRTVDesc, ColorRTV); + + mColorRTV[FrameIndex] = {}; + mColorRTV[FrameIndex].CpuHandle = ColorRTV.ptr; + mColorRTV[FrameIndex].pResource = mColorBuffer[FrameIndex].Get(); + } + } + + // Create depth buffer and SRV + { + // Create depth resource + { + D3D12_RESOURCE_DESC resourceDesc = CD3DX12_RESOURCE_DESC::Tex2D( + DXGI_FORMAT_R32_TYPELESS, mBufferWidth, mBufferHeight, 1, 1, MSAA_SAMPLE_COUNT, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, + D3D12_TEXTURE_LAYOUT_UNKNOWN, 0); + + D3D12_CLEAR_VALUE dsvClearValue; + dsvClearValue.Format = gDepthTextureFormat; + dsvClearValue.DepthStencil.Depth = 1.0f; + dsvClearValue.DepthStencil.Stencil = 0; + + CHK(mDev->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), // No need to read/write by CPU + D3D12_HEAP_FLAG_NONE, + &resourceDesc, + D3D12_RESOURCE_STATE_COMMON, + &dsvClearValue, + IID_PPV_ARGS(mDepthBuffer.ReleaseAndGetAddressOf()))); + mDepthBuffer->SetName(L"DepthTexture"); + } + + // Depth DSV + { + D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {}; +#if MSAA_SAMPLE_COUNT > 1 + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DMS; +#else + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; +#endif + dsvDesc.Format = gDepthTextureFormat; + dsvDesc.Flags = D3D12_DSV_FLAG_NONE; + + CD3DX12_CPU_DESCRIPTOR_HANDLE DepthDSV(mDescHeapDsv->GetCPUDescriptorHandleForHeapStart()); + mDev->CreateDepthStencilView(mDepthBuffer.Get(), &dsvDesc, DepthDSV); + } + + // Depth SRV + { + D3D12_SHADER_RESOURCE_VIEW_DESC depthSRVDesc = {}; + + depthSRVDesc.Format = DXGI_FORMAT_R32_FLOAT; + depthSRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; +#if MSAA_SAMPLE_COUNT > 1 + depthSRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMS; +#else + depthSRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + depthSRVDesc.Texture2D.MipLevels = 1; + depthSRVDesc.Texture2D.MostDetailedMip = 0; // No MIP + depthSRVDesc.Texture2D.PlaneSlice = 0; + depthSRVDesc.Texture2D.ResourceMinLODClamp = 0.0f; +#endif + + CD3DX12_CPU_DESCRIPTOR_HANDLE DepthSRV( + mSsaoDescHeapCbvSrvUav->GetCPUDescriptorHandleForHeapStart()); + mDev->CreateShaderResourceView(mDepthBuffer.Get(), &depthSRVDesc, DepthSRV); + } + } + + // Normal render targets + for (UINT FrameIndex = 0; FrameIndex < FrameCount; ++FrameIndex) + { + D3D12_RESOURCE_DESC NormalRTVDesc = CD3DX12_RESOURCE_DESC::Tex2D( + gNormalTextureFormat, mBufferWidth, mBufferHeight, 1, 1, MSAA_SAMPLE_COUNT, 0, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, + D3D12_TEXTURE_LAYOUT_UNKNOWN, 0); + + FLOAT ClearColor[] = { 0, 0, 0, 1.0f }; + CD3DX12_CLEAR_VALUE NormalClearValue(NormalRTVDesc.Format, ClearColor); + mDev->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, + &NormalRTVDesc, D3D12_RESOURCE_STATE_COMMON, &NormalClearValue, IID_PPV_ARGS(mNormalBuffer[FrameIndex].ReleaseAndGetAddressOf())); + mNormalBuffer[FrameIndex]->SetName(L"NormalBuffer"); + + // SRV + D3D12_SHADER_RESOURCE_VIEW_DESC NormalSRVDesc = {}; + NormalSRVDesc.Format = NormalRTVDesc.Format; + NormalSRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; +#if MSAA_SAMPLE_COUNT > 1 + NormalSRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMS; +#else + NormalSRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + NormalSRVDesc.Texture2D.MipLevels = 1; + NormalSRVDesc.Texture2D.MostDetailedMip = 0; // No MIP + NormalSRVDesc.Texture2D.PlaneSlice = 0; + NormalSRVDesc.Texture2D.ResourceMinLODClamp = 0.0f; +#endif + + mNormalSRV[FrameIndex] = {}; + mNormalSRV[FrameIndex].pResource = mNormalBuffer[FrameIndex].Get(); + CD3DX12_CPU_DESCRIPTOR_HANDLE NormalSRVHandle( + mSsaoDescHeapCbvSrvUav->GetCPUDescriptorHandleForHeapStart(), + SSAO_NUM_DEPTH_SRV + FrameIndex, + mDev->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)); + mDev->CreateShaderResourceView(mNormalBuffer[FrameIndex].Get(), &NormalSRVDesc, NormalSRVHandle); + + // RTV + D3D12_RENDER_TARGET_VIEW_DESC normalRTVDesc = {}; + normalRTVDesc.Format = NormalRTVDesc.Format; +#if MSAA_SAMPLE_COUNT > 1 + normalRTVDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS; +#else + normalRTVDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + normalRTVDesc.Texture2D.MipSlice = 0; +#endif + mNormalRTV[FrameIndex] = {}; + mNormalRTV[FrameIndex].pResource = mNormalBuffer[FrameIndex].Get(); + mNormalRTV[FrameIndex].CpuHandle = CD3DX12_CPU_DESCRIPTOR_HANDLE( + mDescHeapRtv->GetCPUDescriptorHandleForHeapStart(), + VIEWER_NUM_COLOR_RTV + FrameIndex, + mDev->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV)).ptr; + mDev->CreateRenderTargetView(mNormalBuffer[FrameIndex].Get(), &normalRTVDesc, { mNormalRTV[FrameIndex].CpuHandle }); + } + } + + void InitSSAO() + { + const UINT NodeMask = 1; + + GFSDK_SSAO_CustomHeap CustomHeap; + CustomHeap.new_ = ::operator new; + CustomHeap.delete_ = ::operator delete; + + GFSDK_SSAO_DescriptorHeaps_D3D12 DescriptorHeaps; + + DescriptorHeaps.CBV_SRV_UAV.pDescHeap = mSsaoDescHeapCbvSrvUav.Get(); + DescriptorHeaps.CBV_SRV_UAV.BaseIndex = SSAO_NUM_DEPTH_SRV + SSAO_NUM_NORMAL_SRV; + DescriptorHeaps.CBV_SRV_UAV.NumDescriptors = GFSDK_SSAO_NUM_DESCRIPTORS_CBV_SRV_UAV_HEAP_D3D12; + + DescriptorHeaps.RTV.pDescHeap = mDescHeapRtv.Get(); + DescriptorHeaps.RTV.BaseIndex = VIEWER_NUM_RTV; + DescriptorHeaps.RTV.NumDescriptors = GFSDK_SSAO_NUM_DESCRIPTORS_RTV_HEAP_D3D12; + + GFSDK_SSAO_Status status = GFSDK_SSAO_CreateContext_D3D12(mDev, NodeMask, DescriptorHeaps, &mSSAO, &CustomHeap); + assert(status == GFSDK_SSAO_OK); + } + + void ReleaseSSAO() + { + if (mSSAO) + { + mSSAO->Release(); + mSSAO = nullptr; + } + } + + //-------------------------------------------------------------------------------- + ID3D12Device* GetDevice() const + { + return mDev; + } + + void WaitForGpuIdle() + { + // Schedule a Signal command in the queue. + const UINT64 currentFenceValue = mFenceValues[mFrameIndex]; + CHK(mCmdQueue->Signal(mFence.Get(), currentFenceValue)); + + CHK(mFence->SetEventOnCompletion(mFenceValues[mFrameIndex], mFenceEvent)); + WaitForSingleObjectEx(mFenceEvent, INFINITE, FALSE); + } + + //-------------------------------------------------------------------------------- + void Draw() + { + // Upload constant buffer + XMMATRIX ViewMat, ProjMat, WorldMat, ViewProjMat; + { +#if USE_BIN_MESH_READER + ViewMat = XMMatrixIdentity(); + WorldMat = XMMatrixIdentity(); +#else + WorldMat = XMMatrixRotationY(XMConvertToRadians(gModelRotation)); + ViewMat = XMMatrixLookAtLH({ 0, 1, gCameraDistance }, { 0, 0, 0 }, { 0, 1, 0 }); +#endif + + float nearPlane = .01f; + float farPlane = 500.0f; + ProjMat = XMMatrixPerspectiveFovLH(40 * 3.141592f / 180.f, (float)mBufferWidth / mBufferHeight, nearPlane, farPlane); + XMMATRIX MVPTransMat = XMMatrixTranspose(WorldMat * ViewMat * ProjMat); + XMMATRIX WorldTransMat = XMMatrixTranspose(WorldMat); + + ViewProjMat = XMMatrixMultiply(ViewMat, ProjMat); + + // mCBUploadPtr is Write-Combine memory + memcpy_s(mCBUploadPtr, 64, &MVPTransMat, 64); + memcpy_s(reinterpret_cast<char*>(mCBUploadPtr) + 64, 64, &WorldTransMat, 64); + } + + // Get current RTV descriptor + CD3DX12_CPU_DESCRIPTOR_HANDLE descHandleRtv( + mDescHeapRtv->GetCPUDescriptorHandleForHeapStart(), + mFrameIndex, + mDev->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV)); + + // Get current swap chain + ID3D12Resource* ColorBuffer = mColorBuffer[mFrameIndex].Get(); + ID3D12Resource* DepthBuffer = mDepthBuffer.Get(); + + // Get DSV + CD3DX12_CPU_DESCRIPTOR_HANDLE DepthDSV(mDescHeapDsv->GetCPUDescriptorHandleForHeapStart()); + + SetResourceBarrier(mCmdList.Get(), ColorBuffer, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); + SetResourceBarrier(mCmdList.Get(), DepthBuffer, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE); + + // Viewport & Scissor + D3D12_VIEWPORT viewport = {}; + viewport.Width = (float)mBufferWidth; + viewport.Height = (float)mBufferHeight; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + mCmdList->RSSetViewports(1, &viewport); + D3D12_RECT scissor = {}; + scissor.right = (LONG)mBufferWidth; + scissor.bottom = (LONG)mBufferHeight; + mCmdList->RSSetScissorRects(1, &scissor); + + // Clear DepthTexturesh + mCmdList->ClearDepthStencilView(DepthDSV, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); + + // Draw the geometry + D3D12_CPU_DESCRIPTOR_HANDLE RTVs[] = { { mNormalRTV[mFrameIndex].CpuHandle } }; + mCmdList->OMSetRenderTargets(ARRAYSIZE(RTVs), RTVs, false, &DepthDSV); + + mCmdList->SetGraphicsRootSignature(mRootSignature.Get()); + ID3D12DescriptorHeap* descHeaps[] = { mDescHeapCbvSrvUav.Get() }; + mCmdList->SetDescriptorHeaps(ARRAYSIZE(descHeaps), descHeaps); + + mCmdList->SetGraphicsRootDescriptorTable(0, mDescHeapCbvSrvUav->GetGPUDescriptorHandleForHeapStart()); + mCmdList->SetPipelineState(mPso.Get()); + mCmdList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + mCmdList->IASetVertexBuffers(0, 1, &mVBView); + mCmdList->IASetIndexBuffer(&mIBView); + mCmdList->DrawIndexedInstanced(mIndexCount, 1, 0, 0, 0); + + SetResourceBarrier(mCmdList.Get(), DepthBuffer, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + + if (gUseSSAO) + { + // Set input data + GFSDK_SSAO_InputData_D3D12 InputData = {}; + InputData.DepthData.DepthTextureType = GFSDK_SSAO_HARDWARE_DEPTHS; + + // FullResDepthTextureSRV + { + CD3DX12_GPU_DESCRIPTOR_HANDLE DepthSrvGpuHandle( + mSsaoDescHeapCbvSrvUav->GetGPUDescriptorHandleForHeapStart()); + InputData.DepthData.FullResDepthTextureSRV.pResource = DepthBuffer; + InputData.DepthData.FullResDepthTextureSRV.GpuHandle = DepthSrvGpuHandle.ptr; + } + + // DepthData + InputData.DepthData.ProjectionMatrix.Data = GFSDK_SSAO_Float4x4((const GFSDK_SSAO_FLOAT*)&ProjMat); + InputData.DepthData.ProjectionMatrix.Layout = GFSDK_SSAO_ROW_MAJOR_ORDER; + +#if USE_BIN_MESH_READER + InputData.DepthData.MetersToViewSpaceUnits = 0.005f; +#else + InputData.DepthData.MetersToViewSpaceUnits = 1.f; +#endif + + // NormalData + { + CD3DX12_GPU_DESCRIPTOR_HANDLE NormalSrvGpuHandle( + mSsaoDescHeapCbvSrvUav->GetGPUDescriptorHandleForHeapStart(), + SSAO_NUM_DEPTH_SRV + mFrameIndex, + mDev->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)); + + mNormalSRV[mFrameIndex].GpuHandle = NormalSrvGpuHandle.ptr; + +#if USE_BIN_MESH_READER + InputData.NormalData.Enable = false; +#else + InputData.NormalData.Enable = true; +#endif + + if (InputData.NormalData.Enable) + { + InputData.NormalData.WorldToViewMatrix.Data = GFSDK_SSAO_Float4x4((const GFSDK_SSAO_FLOAT*)&ViewMat); + InputData.NormalData.WorldToViewMatrix.Layout = GFSDK_SSAO_ROW_MAJOR_ORDER; + InputData.NormalData.FullResNormalTextureSRV = mNormalSRV[mFrameIndex]; + } + } + + //GFSDK_SSAO_RenderMask RenderMask = GFSDK_SSAO_RENDER_DEBUG_NORMAL; + GFSDK_SSAO_RenderMask RenderMask = GFSDK_SSAO_RENDER_AO; + + // Set SSAO descriptor heap + { + ID3D12DescriptorHeap* descHeaps[] = { mSsaoDescHeapCbvSrvUav.Get() }; + mCmdList->SetDescriptorHeaps(ARRAYSIZE(descHeaps), descHeaps); + } + + GFSDK_SSAO_Output_D3D12 Output; + Output.pRenderTargetView = &mColorRTV[mFrameIndex]; + + GFSDK_SSAO_Status status = mSSAO->RenderAO(mCmdQueue.Get(), mCmdList.Get(), InputData, mAOParams, Output, RenderMask); + assert(status == GFSDK_SSAO_OK); + + // Revert to the original descriptor heap + { + ID3D12DescriptorHeap* descHeaps[] = { mDescHeapCbvSrvUav.Get() }; + mCmdList->SetDescriptorHeaps(ARRAYSIZE(descHeaps), descHeaps); + } + } + + if (gDrawUI) + { + D3D12_CPU_DESCRIPTOR_HANDLE RTVs[] = { mColorRTV[mFrameIndex].CpuHandle }; + + mCmdList->OMSetRenderTargets(ARRAYSIZE(RTVs), RTVs, false, nullptr); + DrawUI(); + } + + // Barrier RenderTarget -> Present + SetResourceBarrier(mCmdList.Get(), ColorBuffer, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); + + // Exec + CHK(mCmdList->Close()); + ID3D12CommandList* const cmdList = mCmdList.Get(); + mCmdQueue->ExecuteCommandLists(1, &cmdList); + + // Present + CHK(mSwapChain->Present(0, 0)); + + // Move to next frame + { + // Schedule a Signal command in the queue. + const UINT64 currentFenceValue = mFenceValues[mFrameIndex]; + CHK(mCmdQueue->Signal(mFence.Get(), currentFenceValue)); + + // Update the frame index. + mFrameIndex = mSwapChain->GetCurrentBackBufferIndex(); + + // If the next frame is not ready to be rendered yet, wait until it is ready. + UINT64 CompletedValue = mFence->GetCompletedValue(); + if (CompletedValue < mFenceValues[mFrameIndex]) + { + CHK(mFence->SetEventOnCompletion(mFenceValues[mFrameIndex], mFenceEvent)); + WaitForSingleObjectEx(mFenceEvent, INFINITE, FALSE); + } + + // Set the fence value for the next frame. + mFenceValues[mFrameIndex] = currentFenceValue + 1; + } + + // Command list allocators can only be reset when the associated + // command lists have finished execution on the GPU; apps should use + // fences to determine GPU execution progress. + CHK(mCmdAllocs[mFrameIndex]->Reset()); + + // However, when ExecuteCommandList() is called on a particular command + // list, that command list can then be reset at any time and must be before + // re-recording. + CHK(mCmdList->Reset(mCmdAllocs[mFrameIndex].Get(), nullptr)); + } + + //-------------------------------------------------------------------------------- + void DrawUI() + { + // Draw UI + ImGui_ImplDX12_NewFrame(); + + bool show_ssao_window = true; + bool show_test_window = false; + + // Show SSAO property window + if (show_ssao_window) + { + ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(400, 300), ImGuiSetCond_FirstUseEver); + ImGui::Begin("HBAO+", &show_ssao_window); + + GFSDK_SSAO_Version Version; + GFSDK_SSAO_Status Status; + Status = GFSDK_SSAO_GetVersion(&Version); + assert(Status == GFSDK_SSAO_OK); + + ImGui::Text("D3D12 HBAO+ %d.%d.%d.%d", Version.Major, Version.Minor, Version.Branch, Version.Revision); + + ImGui::Text("%s", gSelectedGraphicsAdapter.c_str()); +#if MSAA_SAMPLE_COUNT > 1 + ImGui::Text("%dx MSAA", MSAA_SAMPLE_COUNT); +#endif + ImGui::Text("%.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + + float radius = mAOParams.Radius; + ImGui::DragFloat("Radius", &radius, 0.05f, 0.0f, 100.0f); + if (radius != mAOParams.Radius) + { + mAOParams.Radius = radius; + int stop = 0; + stop = stop; + } + ImGui::DragFloat("PowerExponent", &mAOParams.PowerExponent, 0.05f, 1.f, 8.f); + ImGui::DragFloat("Bias", &mAOParams.Bias, 0.001f, 0, 0.5f); + + ImGui::DragFloat("NearAO", &mAOParams.NearAO, 0.01f, 1.f, 2.f); + ImGui::DragFloat("FarAO", &mAOParams.FarAO, 0.01f, 1.f, 2.f); + + bool BlurEnabled = mAOParams.Blur.Enable ? true : false; + ImGui::Checkbox("Blur.Enable", &BlurEnabled); + mAOParams.Blur.Enable = BlurEnabled; + + const char* listbox_items[] = { "GFSDK_SSAO_BLUR_RADIUS_2", "GFSDK_SSAO_BLUR_RADIUS_4" }; + int listbox_item_current = (int)mAOParams.Blur.Radius; + ImGui::ListBox("Blur.Radius", &listbox_item_current, listbox_items, ARRAYSIZE(listbox_items), 2); + mAOParams.Blur.Radius = (GFSDK_SSAO_BlurRadius)(listbox_item_current); + + ImGui::DragFloat("Blur.Sharpness", &mAOParams.Blur.Sharpness, 0.f, 0.f, 32.0f); + + ImGui::End(); + } + + // Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + if (show_test_window) + { + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! + ImGui::ShowTestWindow(&show_test_window); + } + + ImGui::Render(); + } + +private: + void SetResourceBarrier(ID3D12GraphicsCommandList* commandList, + ID3D12Resource* res, + D3D12_RESOURCE_STATES before, + D3D12_RESOURCE_STATES after) + { + D3D12_RESOURCE_BARRIER desc = {}; + desc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + desc.Transition.pResource = res; + desc.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + desc.Transition.StateBefore = before; + desc.Transition.StateAfter = after; + desc.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + commandList->ResourceBarrier(1, &desc); + } +}; + +D3D* gD3D = nullptr; + +extern LRESULT ImGui_ImplDX12_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +//-------------------------------------------------------------------------------- +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + static WORD sLastX = 0, sLastY = 0; + + ImGui_ImplDX12_WndProcHandler(hWnd, message, wParam, lParam); + + switch (message) + { + case WM_SIZE: + { + if (gD3D) + { + BOOL IsFullScreen = FALSE; + if (gD3D->mSwapChain) { + gD3D->mSwapChain->GetFullscreenState(&IsFullScreen, NULL); + } + gD3D->ResizeD3D(hWnd, LOWORD(lParam), HIWORD(lParam), !IsFullScreen); + } + } + break; + case WM_KEYDOWN: + if (wParam == VK_ESCAPE) + { + gDrawUI = !gDrawUI; + //PostMessage(hWnd, WM_DESTROY, 0, 0); + //return 0; + } + if (wParam == VK_F5) + { + gD3D->ReleaseSSAO(); + gD3D->InitSSAO(); + OutputDebugStringA("SSAO Reloaded\n"); + } + if (wParam == 'W') + { + gCameraDistance -= 0.1f; + } + else if (wParam == 'S') + { + gCameraDistance += 0.1f; + } + + break; + + case WM_MOUSEMOVE: + { + WORD x = LOWORD(lParam); + WORD y = HIWORD(lParam); + + if (wParam & MK_RBUTTON) + { + gModelRotation -= float(x - sLastX); + } + sLastX = x; + sLastY = y; + } + break; + case WM_PAINT: + if (gD3D) gD3D->Draw(); + break; + + case WM_DESTROY: + PostQuitMessage(0); + break; + + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + return 0; +} + +//-------------------------------------------------------------------------------- +void FitToDesiredClientSize(HWND hwnd, int Width, int Height, DWORD window_style, bool has_menu) +{ + RECT current_win_rect; + ::GetWindowRect(hwnd, ¤t_win_rect); + RECT desired_rect = current_win_rect; + desired_rect.right = current_win_rect.left + Width; + desired_rect.bottom = current_win_rect.top + Height; + ::AdjustWindowRect(&desired_rect, window_style, (has_menu) ? TRUE : FALSE); + Width = desired_rect.right - desired_rect.left; + Height = desired_rect.bottom - desired_rect.top; + ::SetWindowLongPtr(hwnd, GWL_STYLE, window_style); + ::SetWindowPos(hwnd, HWND_TOP, 0, 0, Width, Height, SWP_SHOWWINDOW); +} + +//-------------------------------------------------------------------------------- +static HWND SetupWindow(int Width, int Height, bool IsWindowed) +{ + WNDCLASSEX wcex; + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = (HMODULE)GetModuleHandle(0); + wcex.hIcon = nullptr; + wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wcex.lpszMenuName = nullptr; + wcex.lpszClassName = _T("WindowClass"); + wcex.hIconSm = nullptr; + if (!RegisterClassEx(&wcex)) + { + throw runtime_error("RegisterClassEx()"); + } + + DWORD windowStyle = WS_OVERLAPPEDWINDOW; + HWND hWnd = CreateWindowEx( + 0, // WS_EX_TOPMOST, + _T("WindowClass"), _T("HBAO+ DX12"), + windowStyle, + 0, 0, Width, Height, + nullptr, nullptr, nullptr, nullptr); + if (!hWnd) + { + throw runtime_error("CreateWindow()"); + } + + if (IsWindowed) + { + FitToDesiredClientSize(hWnd, Width, Height, windowStyle, false); + } + + return hWnd; +} + +//-------------------------------------------------------------------------------- +int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR CmdLine, int) +{ + MSG msg; + ZeroMemory(&msg, sizeof msg); + + ID3D12Device* dev = nullptr; + + std::vector<std::string> arguments; + if (CmdLine) + { + char buff[1024]; + strcpy(buff, CmdLine); + char * pch = strtok(buff, " "); + while (pch != NULL) + { + arguments.push_back(pch); + pch = strtok(NULL, " "); + } + } + + for (size_t idx = 0; idx < arguments.size(); ++idx) + { + std::string arg = arguments[idx]; + if (_stricmp(arg.c_str(), "-width") == 0) + { + gWindowWidth = atoi(arguments[idx + 1].c_str()); + idx++; + } + else if (_stricmp(arg.c_str(), "-height") == 0) + { + gWindowHeight = atoi(arguments[idx + 1].c_str()); + idx++; + } + else if (_stricmp(arg.c_str(), "-window") == 0) + { + gIsWindowed = (atoi(arguments[idx + 1].c_str()) == 1) ? true : false; + idx++; + } + else if (_stricmp(arg.c_str(), "-ui") == 0) + { + gDrawUI = (atoi(arguments[idx + 1].c_str()) == 1) ? true : false; + idx++; + } + else if (_stricmp(arg.c_str(), "-adapter") == 0) + { + gAdapterIndex = (atoi(arguments[idx + 1].c_str()) == 1) ? true : false; + idx++; + } + } + +#ifdef NDEBUG + try +#endif + { + gMainWindowHandle = SetupWindow(gWindowWidth, gWindowHeight, gIsWindowed); + ShowWindow(gMainWindowHandle, SW_SHOW); + UpdateWindow(gMainWindowHandle); + + gD3D = new D3D(gWindowWidth, gWindowHeight, gMainWindowHandle, gIsWindowed, gAdapterIndex); + dev = gD3D->GetDevice(); + + while (msg.message != WM_QUIT) + { + if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } +#ifdef NDEBUG + catch (std::exception &e) + { + MessageBoxA(gMainWindowHandle, e.what(), "Exception occured.", MB_ICONSTOP); + } +#endif + + if (gD3D) + delete gD3D; + + if (dev) + dev->Release(); + + return static_cast<int>(msg.wParam); +} diff --git a/samples/D3D12/src/Viewer.hlsl b/samples/D3D12/src/Viewer.hlsl new file mode 100644 index 0000000..b3b418c --- /dev/null +++ b/samples/D3D12/src/Viewer.hlsl @@ -0,0 +1,40 @@ +struct VSIn +{ + float3 pos : POSITION; + float3 normal : NORMAL; +}; + +struct VSOut +{ + float4 pos : SV_POSITION; + float3 normal : TEXCOORD; +}; + +cbuffer Scene +{ + float4x4 worldViewProjMatrix; + float4x4 worldMatrix; +}; + +VSOut VSMain(VSIn vsIn) +{ + VSOut output; + output.pos = mul(float4(vsIn.pos.xyz, 1), worldViewProjMatrix); + output.normal = mul(vsIn.normal.xyz, (float3x3)(worldMatrix)); + return output; +} + +struct PSOutputDepthTextures +{ + float4 WorldNormal : SV_Target0; +}; + +PSOutputDepthTextures PSMain(VSOut vsOut) +{ + PSOutputDepthTextures OUT; + + float3 worldNormal = normalize(vsOut.normal); + OUT.WorldNormal = float4(worldNormal.xyz, 1.f); + + return OUT; +}
\ No newline at end of file diff --git a/samples/D3D12/src/Viewer.vcxproj b/samples/D3D12/src/Viewer.vcxproj new file mode 100644 index 0000000..afd9721 --- /dev/null +++ b/samples/D3D12/src/Viewer.vcxproj @@ -0,0 +1,229 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CFEEDBA7-74CF-4AF1-9A14-0E890CE94DF8}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>hbaop_dx12</RootNamespace> + <WindowsTargetPlatformVersion>10.0.10240.0</WindowsTargetPlatformVersion> + <ProjectName>SampleApp_D3D12</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <IncludePath>$(ProjectDir)..\..\..\lib;$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\include;$(ProjectDir);$(VC_IncludePath);$(ProjectDir)..\external\imgui\examples\directx12_example;$(ProjectDir)..\external\imgui\</IncludePath> + <LibraryPath>$(ProjectDir)..\..\..\lib;$(WindowsSDK_LibraryPath_x86);$(VC_LibraryPath_x86)</LibraryPath> + <OutDir>..\Bin\</OutDir> + <IntDir>..\Temp\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir> + <TargetName>$(ProjectName).debug.win32</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <IncludePath>$(ProjectDir)..\..\..\lib;$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\include;$(ProjectDir);$(VC_IncludePath);$(ProjectDir)..\external\imgui\examples\directx12_example;$(ProjectDir)..\external\imgui\</IncludePath> + <LibraryPath>$(ProjectDir)..\..\..\lib;$(WindowsSDK_LibraryPath_x64);$(VC_LibraryPath_x64)</LibraryPath> + <OutDir>..\Bin\</OutDir> + <IntDir>..\Temp\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir> + <TargetName>$(ProjectName).debug.win64</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <IncludePath>$(ProjectDir)..\..\..\lib;$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\include;$(ProjectDir);$(VC_IncludePath);$(ProjectDir)..\external\imgui\examples\directx12_example;$(ProjectDir)..\external\imgui\</IncludePath> + <LibraryPath>$(ProjectDir)..\..\..\lib;$(WindowsSDK_LibraryPath_x86);$(VC_LibraryPath_x86)</LibraryPath> + <OutDir>..\Bin\</OutDir> + <IntDir>..\Temp\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir> + <TargetName>$(ProjectName).win32</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <IncludePath>$(ProjectDir)..\..\..\lib;$(WindowsSDK_IncludePath);$(ProjectDir)..\..\..\include;$(ProjectDir);$(VC_IncludePath);$(ProjectDir)..\external\imgui\examples\directx12_example;$(ProjectDir)..\external\imgui\</IncludePath> + <LibraryPath>$(ProjectDir)..\..\..\lib;$(WindowsSDK_LibraryPath_x64);$(VC_LibraryPath_x64)</LibraryPath> + <OutDir>..\Bin\</OutDir> + <IntDir>..\Temp\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir> + <TargetName>$(ProjectName).win64</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_CRT_NON_CONFORMING_SWPRINTFS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <DisableSpecificWarnings>4312</DisableSpecificWarnings> + <AdditionalIncludeDirectories> + </AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PreBuildEvent> + <Command>copy /Y ..\..\..\lib\GFSDK_SSAO_D3D12.win32.dll ..\Bin</Command> + </PreBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_CRT_NON_CONFORMING_SWPRINTFS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <DisableSpecificWarnings>4312</DisableSpecificWarnings> + <AdditionalIncludeDirectories> + </AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PreBuildEvent> + <Command>copy /Y ..\..\..\lib\GFSDK_SSAO_D3D12.win64.dll ..\Bin</Command> + </PreBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_CRT_NON_CONFORMING_SWPRINTFS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <DisableSpecificWarnings>4312</DisableSpecificWarnings> + <AdditionalIncludeDirectories> + </AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PreBuildEvent> + <Command>copy /Y ..\..\..\lib\GFSDK_SSAO_D3D12.win32.dll ..\Bin</Command> + </PreBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_CRT_NON_CONFORMING_SWPRINTFS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <DisableSpecificWarnings>4312</DisableSpecificWarnings> + <AdditionalIncludeDirectories> + </AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PreBuildEvent> + <Command>copy /Y ..\..\..\lib\GFSDK_SSAO_D3D12.win64.dll ..\Bin</Command> + </PreBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\external\imgui\examples\directx12_example\imgui_impl_dx12.cpp" /> + <ClCompile Include="..\external\imgui\imgui.cpp" /> + <ClCompile Include="..\external\imgui\imgui_demo.cpp" /> + <ClCompile Include="..\external\imgui\imgui_draw.cpp" /> + <ClCompile Include="Viewer.cpp" /> + </ItemGroup> + <ItemGroup> + <FxCompile Include="..\bin\Viewer.hlsl"> + <EntryPointName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">PSMain</EntryPointName> + <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType> + <EntryPointName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">PSMain</EntryPointName> + <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Pixel</ShaderType> + <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">5.0</ShaderModel> + <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">5.0</ShaderModel> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </FxCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\external\imgui\examples\directx12_example\imgui_impl_dx12.h" /> + <ClInclude Include="..\external\imgui\imconfig.h" /> + <ClInclude Include="..\external\imgui\imgui.h" /> + <ClInclude Include="..\external\imgui\stb_rect_pack.h" /> + <ClInclude Include="..\external\imgui\stb_textedit.h" /> + <ClInclude Include="..\external\imgui\stb_truetype.h" /> + <ClInclude Include="BinMeshReader.h" /> + <ClInclude Include="WaveFrontReader.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/samples/D3D12/src/Viewer.vcxproj.filters b/samples/D3D12/src/Viewer.vcxproj.filters new file mode 100644 index 0000000..bd01d4e --- /dev/null +++ b/samples/D3D12/src/Viewer.vcxproj.filters @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + <Filter Include="shaders"> + <UniqueIdentifier>{0e1a96a7-3888-4f55-b5b2-5aa8917b7309}</UniqueIdentifier> + </Filter> + <Filter Include="imgui"> + <UniqueIdentifier>{837694ff-54c1-41d9-a277-db25d377c998}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\external\imgui\imgui.cpp"> + <Filter>imgui</Filter> + </ClCompile> + <ClCompile Include="..\external\imgui\examples\directx12_example\imgui_impl_dx12.cpp"> + <Filter>imgui</Filter> + </ClCompile> + <ClCompile Include="..\external\imgui\imgui_draw.cpp"> + <Filter>imgui</Filter> + </ClCompile> + <ClCompile Include="..\external\imgui\imgui_demo.cpp"> + <Filter>imgui</Filter> + </ClCompile> + <ClCompile Include="Viewer.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="WaveFrontReader.h" /> + <ClInclude Include="..\external\imgui\imconfig.h"> + <Filter>imgui</Filter> + </ClInclude> + <ClInclude Include="..\external\imgui\imgui.h"> + <Filter>imgui</Filter> + </ClInclude> + <ClInclude Include="..\external\imgui\stb_rect_pack.h"> + <Filter>imgui</Filter> + </ClInclude> + <ClInclude Include="..\external\imgui\stb_textedit.h"> + <Filter>imgui</Filter> + </ClInclude> + <ClInclude Include="..\external\imgui\stb_truetype.h"> + <Filter>imgui</Filter> + </ClInclude> + <ClInclude Include="..\external\imgui\examples\directx12_example\imgui_impl_dx12.h"> + <Filter>imgui</Filter> + </ClInclude> + <ClInclude Include="BinMeshReader.h" /> + </ItemGroup> + <ItemGroup> + <FxCompile Include="..\bin\Viewer.hlsl"> + <Filter>shaders</Filter> + </FxCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/samples/D3D12/src/WaveFrontReader.h b/samples/D3D12/src/WaveFrontReader.h new file mode 100644 index 0000000..f68f2bf --- /dev/null +++ b/samples/D3D12/src/WaveFrontReader.h @@ -0,0 +1,541 @@ +//-------------------------------------------------------------------------------------- +// File: WaveFrontReader.h +// +// Code for loading basic mesh data from a WaveFront OBJ file +// +// http://en.wikipedia.org/wiki/Wavefront_.obj_file +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// http://go.microsoft.com/fwlink/?LinkID=324981 +//-------------------------------------------------------------------------------------- + +#include <windows.h> + +#include <algorithm> +#include <fstream> +#include <string> +#include <vector> +#include <unordered_map> + +#pragma warning(push) +#pragma warning(disable : 4005) +#include <stdint.h> +#pragma warning(pop) + +#include <directxmath.h> +#include <directxcollision.h> + +template<class index_t> +class WaveFrontReader +{ +public: + typedef index_t index_t; + + struct Vertex + { + DirectX::XMFLOAT3 position; + DirectX::XMFLOAT3 normal; + DirectX::XMFLOAT2 textureCoordinate; + }; + + WaveFrontReader() : hasNormals(false), hasTexcoords(false) {} + + HRESULT Load( _In_z_ const wchar_t* szFileName, bool ccw = true ) + { + Clear(); + + static const size_t MAX_POLY = 64; + + using namespace DirectX; + + std::wifstream InFile( szFileName ); + if( !InFile ) + return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ); + + WCHAR fname[_MAX_FNAME]; + _wsplitpath_s( szFileName, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, nullptr, 0 ); + + name = fname; + + std::vector<XMFLOAT3> positions; + std::vector<XMFLOAT3> normals; + std::vector<XMFLOAT2> texCoords; + + VertexCache vertexCache; + + Material defmat; + + wcscpy_s( defmat.strName, L"default" ); + materials.push_back( defmat ); + + uint32_t curSubset = 0; + + WCHAR strCommand[256] = {0}; + WCHAR strMaterialFilename[MAX_PATH] = {0}; + for( ;; ) + { + InFile >> strCommand; + if( !InFile ) + break; + + if( 0 == wcscmp( strCommand, L"#" ) ) + { + // Comment + } + else if( 0 == wcscmp( strCommand, L"v" ) ) + { + // Vertex Position + float x, y, z; + InFile >> x >> y >> z; + positions.push_back( XMFLOAT3( x, y, z ) ); + } + else if( 0 == wcscmp( strCommand, L"vt" ) ) + { + // Vertex TexCoord + float u, v; + InFile >> u >> v; + texCoords.push_back( XMFLOAT2( u, v ) ); + + hasTexcoords = true; + } + else if( 0 == wcscmp( strCommand, L"vn" ) ) + { + // Vertex Normal + float x, y, z; + InFile >> x >> y >> z; + normals.push_back( XMFLOAT3( x, y, z ) ); + + hasNormals = true; + } + else if( 0 == wcscmp( strCommand, L"f" ) ) + { + // Face + UINT iPosition, iTexCoord, iNormal; + Vertex vertex; + + DWORD faceIndex[ MAX_POLY ]; + size_t iFace = 0; + for(;;) + { + if ( iFace >= MAX_POLY ) + { + // Too many polygon verts for the reader + return E_FAIL; + } + + memset( &vertex, 0, sizeof( vertex ) ); + + // OBJ format uses 1-based arrays + InFile >> iPosition; + if ( iPosition > positions.size() ) + return E_FAIL; + + vertex.position = positions[ iPosition - 1 ]; + + if( '/' == InFile.peek() ) + { + InFile.ignore(); + + if( '/' != InFile.peek() ) + { + // Optional texture coordinate + InFile >> iTexCoord; + if ( iTexCoord > texCoords.size() ) + return E_FAIL; + + vertex.textureCoordinate = texCoords[ iTexCoord - 1 ]; + } + + if( '/' == InFile.peek() ) + { + InFile.ignore(); + + // Optional vertex normal + InFile >> iNormal; + if ( iNormal > normals.size() ) + return E_FAIL; + + vertex.normal = normals[ iNormal - 1 ]; + } + } + + // If a duplicate vertex doesn't exist, add this vertex to the Vertices + // list. Store the index in the Indices array. The Vertices and Indices + // lists will eventually become the Vertex Buffer and Index Buffer for + // the mesh. + DWORD index = AddVertex( iPosition, &vertex, vertexCache ); + if ( index == (DWORD)-1 ) + return E_OUTOFMEMORY; + +#pragma warning( suppress : 4127 ) + if ( sizeof(index_t) == 2 && ( index >= 0xFFFF ) ) + { + // Too many indices for 16-bit IB! + return E_FAIL; + } + else if ( sizeof(index_t) == 4 && ( index >= 0xFFFFFFFF ) ) + { + // Too many indices for 32-bit IB! + return E_FAIL; + } + + faceIndex[ iFace ] = index; + ++iFace; + + // Check for more face data or end of the face statement + bool faceEnd = false; + for(;;) + { + wchar_t p = InFile.peek(); + + if ( '\n' == p || !InFile ) + { + faceEnd = true; + break; + } + else if ( isdigit( p ) ) + break; + + InFile.ignore(); + } + + if ( faceEnd ) + break; + } + + if ( iFace < 3 ) + { + // Need at least 3 points to form a triangle + return E_FAIL; + } + + // Convert polygons to triangles + DWORD i0 = faceIndex[0]; + DWORD i1 = faceIndex[1]; + + for( size_t j = 2; j < iFace; ++ j ) + { + DWORD index = faceIndex[ j ]; + indices.push_back( static_cast<index_t>( i0 ) ); + if ( ccw ) + { + indices.push_back( static_cast<index_t>( i1 ) ); + indices.push_back( static_cast<index_t>( index ) ); + } + else + { + indices.push_back( static_cast<index_t>( index ) ); + indices.push_back( static_cast<index_t>( i1 ) ); + } + + attributes.push_back( curSubset ); + + i1 = index; + } + + assert( attributes.size()*3 == indices.size() ); + } + else if( 0 == wcscmp( strCommand, L"mtllib" ) ) + { + // Material library + InFile >> strMaterialFilename; + } + else if( 0 == wcscmp( strCommand, L"usemtl" ) ) + { + // Material + WCHAR strName[MAX_PATH] = {0}; + InFile >> strName; + + bool bFound = false; + uint32_t count = 0; + for( auto it = materials.cbegin(); it != materials.cend(); ++it, ++count ) + { + if( 0 == wcscmp( it->strName, strName ) ) + { + bFound = true; + curSubset = count; + break; + } + } + + if( !bFound ) + { + Material mat; + curSubset = static_cast<uint32_t>( materials.size() ); + wcscpy_s( mat.strName, MAX_PATH - 1, strName ); + materials.push_back( mat ); + } + } + else + { + // Unimplemented or unrecognized command + //OutputDebugStringW( strCommand ); + } + + InFile.ignore( 1000, '\n' ); + } + + // Cleanup + InFile.close(); + + BoundingBox::CreateFromPoints( bounds, positions.size(), &positions.front(), sizeof(XMFLOAT3) ); + + // If an associated material file was found, read that in as well. + if (0) //@jihoc if( *strMaterialFilename ) + { + WCHAR ext[_MAX_EXT]; + _wsplitpath_s( strMaterialFilename, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, ext, _MAX_EXT ); + + WCHAR drive[_MAX_DRIVE]; + WCHAR dir[_MAX_DIR]; + _wsplitpath_s( szFileName, drive, _MAX_DRIVE, dir, _MAX_DIR, nullptr, 0, nullptr, 0 ); + + WCHAR szPath[ MAX_PATH ]; + _wmakepath_s( szPath, MAX_PATH, drive, dir, fname, ext ); + + HRESULT hr = LoadMTL( szPath ); + if ( FAILED(hr) ) + return hr; + } + + return S_OK; + } + + HRESULT LoadMTL( _In_z_ const wchar_t* szFileName ) + { + // Assumes MTL is in CWD along with OBJ + std::wifstream InFile( szFileName ); + if( !InFile ) + return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ); + + auto curMaterial = materials.end(); + + WCHAR strCommand[256] = {0}; + for( ;; ) + { + InFile >> strCommand; + if( !InFile ) + break; + + if( 0 == wcscmp( strCommand, L"newmtl" ) ) + { + // Switching active materials + WCHAR strName[MAX_PATH] = {0}; + InFile >> strName; + + curMaterial = materials.end(); + for( auto it = materials.begin(); it != materials.end(); ++it ) + { + if( 0 == wcscmp( it->strName, strName ) ) + { + curMaterial = it; + break; + } + } + } + + // The rest of the commands rely on an active material + if( curMaterial == materials.end() ) + continue; + + if( 0 == wcscmp( strCommand, L"#" ) ) + { + // Comment + } + else if( 0 == wcscmp( strCommand, L"Ka" ) ) + { + // Ambient color + float r, g, b; + InFile >> r >> g >> b; + curMaterial->vAmbient = XMFLOAT3( r, g, b ); + } + else if( 0 == wcscmp( strCommand, L"Kd" ) ) + { + // Diffuse color + float r, g, b; + InFile >> r >> g >> b; + curMaterial->vDiffuse = XMFLOAT3( r, g, b ); + } + else if( 0 == wcscmp( strCommand, L"Ks" ) ) + { + // Specular color + float r, g, b; + InFile >> r >> g >> b; + curMaterial->vSpecular = XMFLOAT3( r, g, b ); + } + else if( 0 == wcscmp( strCommand, L"d" ) || + 0 == wcscmp( strCommand, L"Tr" ) ) + { + // Alpha + InFile >> curMaterial->fAlpha; + } + else if( 0 == wcscmp( strCommand, L"Ns" ) ) + { + // Shininess + int nShininess; + InFile >> nShininess; + curMaterial->nShininess = nShininess; + } + else if( 0 == wcscmp( strCommand, L"illum" ) ) + { + // Specular on/off + int illumination; + InFile >> illumination; + curMaterial->bSpecular = ( illumination == 2 ); + } + else if( 0 == wcscmp( strCommand, L"map_Kd" ) ) + { + // Texture + InFile >> curMaterial->strTexture; + } + else + { + // Unimplemented or unrecognized command + } + + InFile.ignore( 1000, L'\n' ); + } + + InFile.close(); + + return S_OK; + } + + void Clear() + { + vertices.clear(); + indices.clear(); + attributes.clear(); + materials.clear(); + name.clear(); + hasNormals = false; + hasTexcoords = false; + + bounds.Center.x = bounds.Center.y = bounds.Center.z = 0.f; + bounds.Extents.x = bounds.Extents.y = bounds.Extents.z = 0.f; + } + + HRESULT LoadVBO( _In_z_ const wchar_t* szFileName ) + { + Clear(); + + WCHAR fname[_MAX_FNAME]; + _wsplitpath_s( szFileName, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, nullptr, 0 ); + + name = fname; + + Material defmat; + wcscpy_s( defmat.strName, L"default" ); + materials.push_back( defmat ); + + std::ifstream vboFile(szFileName, std::ifstream::in | std::ifstream::binary); + if ( !vboFile.is_open() ) + return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ); + + hasNormals = hasTexcoords = true; + + uint32_t numVertices = 0; + uint32_t numIndices = 0; + + vboFile.read( reinterpret_cast<char*>( &numVertices ), sizeof(uint32_t ) ); + if ( !numVertices ) + return E_FAIL; + + vboFile.read( reinterpret_cast<char*>( &numIndices ), sizeof(uint32_t ) ); + if ( !numIndices ) + return E_FAIL; + + vertices.resize( numVertices ); + vboFile.read( reinterpret_cast<char*>( &vertices.front() ), sizeof(Vertex) * numVertices ); + +#pragma warning( suppress : 4127 ) + if ( sizeof( index_t ) == 2 ) + { + indices.resize( numIndices ); + vboFile.read( reinterpret_cast<char*>( &indices.front() ), sizeof(uint16_t) * numIndices ); + } + else + { + std::vector<uint16_t> tmp; + tmp.resize( numIndices ); + vboFile.read( reinterpret_cast<char*>( &tmp.front() ), sizeof(uint16_t) * numIndices ); + + indices.reserve( numIndices ); + for( auto it = tmp.cbegin(); it != tmp.cend(); ++it ) + { + indices.push_back( *it ); + } + } + + BoundingBox::CreateFromPoints( bounds, vertices.size(), reinterpret_cast<const XMFLOAT3*>( &vertices.front() ), sizeof(Vertex) ); + + vboFile.close(); + + return S_OK; + } + + struct Material + { + DirectX::XMFLOAT3 vAmbient; + DirectX::XMFLOAT3 vDiffuse; + DirectX::XMFLOAT3 vSpecular; + uint32_t nShininess; + float fAlpha; + + bool bSpecular; + + WCHAR strName[MAX_PATH]; + WCHAR strTexture[MAX_PATH]; + + Material() : + vAmbient( 0.2f, 0.2f, 0.2f ), + vDiffuse( 0.8f, 0.8f, 0.8f ), + vSpecular( 1.0f, 1.0f, 1.0f ), + nShininess( 0 ), + fAlpha( 1.f ), + bSpecular( false ) + { memset(strName, 0, MAX_PATH); memset(strTexture, 0, MAX_PATH); } + }; + + std::vector<Vertex> vertices; + std::vector<index_t> indices; + std::vector<uint32_t> attributes; + std::vector<Material> materials; + + std::wstring name; + bool hasNormals; + bool hasTexcoords; + + DirectX::BoundingBox bounds; + +private: + typedef std::unordered_multimap<UINT, UINT> VertexCache; + + DWORD AddVertex( UINT hash, Vertex* pVertex, VertexCache& cache ) + { + auto f = cache.equal_range( hash ); + + for( auto it = f.first; it != f.second; ++it ) + { + auto& tv = vertices[ it->second ]; + + if ( 0 == memcmp( pVertex, &tv, sizeof(Vertex) ) ) + { + return it->second; + } + } + + DWORD index = static_cast<UINT>( vertices.size() ); + vertices.push_back( *pVertex ); + + VertexCache::value_type entry( hash, index ); + cache.insert( entry ); + return index; + } +}; diff --git a/samples/D3D12/src/d3dx12.h b/samples/D3D12/src/d3dx12.h new file mode 100644 index 0000000..ba59dfc --- /dev/null +++ b/samples/D3D12/src/d3dx12.h @@ -0,0 +1,1508 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx12.h +// Content: D3DX12 utility library +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DX12_H__ +#define __D3DX12_H__ + +#include "d3d12.h" + +#if defined( __cplusplus ) + +struct CD3DX12_DEFAULT {}; +extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT; + +//------------------------------------------------------------------------------------------------ +inline bool operator==( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) +{ + return l.TopLeftX == r.TopLeftX && l.TopLeftY == r.TopLeftY && l.Width == r.Width && + l.Height == r.Height && l.MinDepth == r.MinDepth && l.MaxDepth == r.MaxDepth; +} + +//------------------------------------------------------------------------------------------------ +inline bool operator!=( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RECT : public D3D12_RECT +{ + CD3DX12_RECT() + {} + explicit CD3DX12_RECT( const D3D12_RECT& o ) : + D3D12_RECT( o ) + {} + explicit CD3DX12_RECT( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom ) + { + left = Left; + top = Top; + right = Right; + bottom = Bottom; + } + ~CD3DX12_RECT() {} + operator const D3D12_RECT&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BOX : public D3D12_BOX +{ + CD3DX12_BOX() + {} + explicit CD3DX12_BOX( const D3D12_BOX& o ) : + D3D12_BOX( o ) + {} + explicit CD3DX12_BOX( + LONG Left, + LONG Right ) + { + left = Left; + top = 0; + front = 0; + right = Right; + bottom = 1; + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom ) + { + left = Left; + top = Top; + front = 0; + right = Right; + bottom = Bottom; + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Front, + LONG Right, + LONG Bottom, + LONG Back ) + { + left = Left; + top = Top; + front = Front; + right = Right; + bottom = Bottom; + back = Back; + } + ~CD3DX12_BOX() {} + operator const D3D12_BOX&() const { return *this; } +}; +inline bool operator==( const D3D12_BOX& l, const D3D12_BOX& r ) +{ + return l.left == r.left && l.top == r.top && l.front == r.front && + l.right == r.right && l.bottom == r.bottom && l.back == r.back; +} +inline bool operator!=( const D3D12_BOX& l, const D3D12_BOX& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DEPTH_STENCIL_DESC : public D3D12_DEPTH_STENCIL_DESC +{ + CD3DX12_DEPTH_STENCIL_DESC() + {} + explicit CD3DX12_DEPTH_STENCIL_DESC( const D3D12_DEPTH_STENCIL_DESC& o ) : + D3D12_DEPTH_STENCIL_DESC( o ) + {} + explicit CD3DX12_DEPTH_STENCIL_DESC( CD3DX12_DEFAULT ) + { + DepthEnable = TRUE; + DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + DepthFunc = D3D12_COMPARISON_FUNC_LESS; + StencilEnable = FALSE; + StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; + StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; + const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = + { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS }; + FrontFace = defaultStencilOp; + BackFace = defaultStencilOp; + } + explicit CD3DX12_DEPTH_STENCIL_DESC( + BOOL depthEnable, + D3D12_DEPTH_WRITE_MASK depthWriteMask, + D3D12_COMPARISON_FUNC depthFunc, + BOOL stencilEnable, + UINT8 stencilReadMask, + UINT8 stencilWriteMask, + D3D12_STENCIL_OP frontStencilFailOp, + D3D12_STENCIL_OP frontStencilDepthFailOp, + D3D12_STENCIL_OP frontStencilPassOp, + D3D12_COMPARISON_FUNC frontStencilFunc, + D3D12_STENCIL_OP backStencilFailOp, + D3D12_STENCIL_OP backStencilDepthFailOp, + D3D12_STENCIL_OP backStencilPassOp, + D3D12_COMPARISON_FUNC backStencilFunc ) + { + DepthEnable = depthEnable; + DepthWriteMask = depthWriteMask; + DepthFunc = depthFunc; + StencilEnable = stencilEnable; + StencilReadMask = stencilReadMask; + StencilWriteMask = stencilWriteMask; + FrontFace.StencilFailOp = frontStencilFailOp; + FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; + FrontFace.StencilPassOp = frontStencilPassOp; + FrontFace.StencilFunc = frontStencilFunc; + BackFace.StencilFailOp = backStencilFailOp; + BackFace.StencilDepthFailOp = backStencilDepthFailOp; + BackFace.StencilPassOp = backStencilPassOp; + BackFace.StencilFunc = backStencilFunc; + } + ~CD3DX12_DEPTH_STENCIL_DESC() {} + operator const D3D12_DEPTH_STENCIL_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC +{ + CD3DX12_BLEND_DESC() + {} + explicit CD3DX12_BLEND_DESC( const D3D12_BLEND_DESC& o ) : + D3D12_BLEND_DESC( o ) + {} + explicit CD3DX12_BLEND_DESC( CD3DX12_DEFAULT ) + { + AlphaToCoverageEnable = FALSE; + IndependentBlendEnable = FALSE; + const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = + { + FALSE,FALSE, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + D3D12_COLOR_WRITE_ENABLE_ALL, + }; + for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + RenderTarget[ i ] = defaultRenderTargetBlendDesc; + } + ~CD3DX12_BLEND_DESC() {} + operator const D3D12_BLEND_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC +{ + CD3DX12_RASTERIZER_DESC() + {} + explicit CD3DX12_RASTERIZER_DESC( const D3D12_RASTERIZER_DESC& o ) : + D3D12_RASTERIZER_DESC( o ) + {} + explicit CD3DX12_RASTERIZER_DESC( CD3DX12_DEFAULT ) + { + FillMode = D3D12_FILL_MODE_SOLID; + CullMode = D3D12_CULL_MODE_BACK; + FrontCounterClockwise = FALSE; + DepthBias = D3D12_DEFAULT_DEPTH_BIAS; + DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; + SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + DepthClipEnable = TRUE; + MultisampleEnable = FALSE; + AntialiasedLineEnable = FALSE; + ForcedSampleCount = 0; + ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + } + explicit CD3DX12_RASTERIZER_DESC( + D3D12_FILL_MODE fillMode, + D3D12_CULL_MODE cullMode, + BOOL frontCounterClockwise, + INT depthBias, + FLOAT depthBiasClamp, + FLOAT slopeScaledDepthBias, + BOOL depthClipEnable, + BOOL multisampleEnable, + BOOL antialiasedLineEnable, + UINT forcedSampleCount, + D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster) + { + FillMode = fillMode; + CullMode = cullMode; + FrontCounterClockwise = frontCounterClockwise; + DepthBias = depthBias; + DepthBiasClamp = depthBiasClamp; + SlopeScaledDepthBias = slopeScaledDepthBias; + DepthClipEnable = depthClipEnable; + MultisampleEnable = multisampleEnable; + AntialiasedLineEnable = antialiasedLineEnable; + ForcedSampleCount = forcedSampleCount; + ConservativeRaster = conservativeRaster; + } + ~CD3DX12_RASTERIZER_DESC() {} + operator const D3D12_RASTERIZER_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_ALLOCATION_INFO : public D3D12_RESOURCE_ALLOCATION_INFO +{ + CD3DX12_RESOURCE_ALLOCATION_INFO() + {} + explicit CD3DX12_RESOURCE_ALLOCATION_INFO( const D3D12_RESOURCE_ALLOCATION_INFO& o ) : + D3D12_RESOURCE_ALLOCATION_INFO( o ) + {} + CD3DX12_RESOURCE_ALLOCATION_INFO( + UINT64 size, + UINT64 alignment ) + { + SizeInBytes = size; + Alignment = alignment; + } + operator const D3D12_RESOURCE_ALLOCATION_INFO&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES +{ + CD3DX12_HEAP_PROPERTIES() + {} + explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) : + D3D12_HEAP_PROPERTIES(o) + {} + CD3DX12_HEAP_PROPERTIES( + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT creationNodeMask = 1, + UINT nodeMask = 1 ) + { + Type = D3D12_HEAP_TYPE_CUSTOM; + CPUPageProperty = cpuPageProperty; + MemoryPoolPreference = memoryPoolPreference; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + explicit CD3DX12_HEAP_PROPERTIES( + D3D12_HEAP_TYPE type, + UINT creationNodeMask = 1, + UINT nodeMask = 1 ) + { + Type = type; + CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + operator const D3D12_HEAP_PROPERTIES&() const { return *this; } + bool IsCPUAccessible() const + { + return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM && + (CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK)); + } +}; +inline bool operator==( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) +{ + return l.Type == r.Type && l.CPUPageProperty == r.CPUPageProperty && + l.MemoryPoolPreference == r.MemoryPoolPreference && + l.CreationNodeMask == r.CreationNodeMask && + l.VisibleNodeMask == r.VisibleNodeMask; +} +inline bool operator!=( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_DESC : public D3D12_HEAP_DESC +{ + CD3DX12_HEAP_DESC() + {} + explicit CD3DX12_HEAP_DESC(const D3D12_HEAP_DESC &o) : + D3D12_HEAP_DESC(o) + {} + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_PROPERTIES properties, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = properties; + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_TYPE type, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES( type ); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_PROPERTIES properties, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = properties; + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_TYPE type, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES( type ); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + operator const D3D12_HEAP_DESC&() const { return *this; } + bool IsCPUAccessible() const + { return static_cast< const CD3DX12_HEAP_PROPERTIES* >( &Properties )->IsCPUAccessible(); } +}; +inline bool operator==( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) +{ + return l.SizeInBytes == r.SizeInBytes && + l.Properties == r.Properties && + l.Alignment == r.Alignment && + l.Flags == r.Flags; +} +inline bool operator!=( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CLEAR_VALUE : public D3D12_CLEAR_VALUE +{ + CD3DX12_CLEAR_VALUE() + {} + explicit CD3DX12_CLEAR_VALUE(const D3D12_CLEAR_VALUE &o) : + D3D12_CLEAR_VALUE(o) + {} + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + const FLOAT color[4] ) + { + Format = format; + memcpy( Color, color, sizeof( Color ) ); + } + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + FLOAT depth, + UINT8 stencil ) + { + Format = format; + /* Use memcpy to preserve NAN values */ + memcpy( &DepthStencil.Depth, &depth, sizeof( depth ) ); + DepthStencil.Stencil = stencil; + } + operator const D3D12_CLEAR_VALUE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RANGE : public D3D12_RANGE +{ + CD3DX12_RANGE() + {} + explicit CD3DX12_RANGE(const D3D12_RANGE &o) : + D3D12_RANGE(o) + {} + CD3DX12_RANGE( + SIZE_T begin, + SIZE_T end ) + { + Begin = begin; + End = end; + } + operator const D3D12_RANGE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILED_RESOURCE_COORDINATE : public D3D12_TILED_RESOURCE_COORDINATE +{ + CD3DX12_TILED_RESOURCE_COORDINATE() + {} + explicit CD3DX12_TILED_RESOURCE_COORDINATE(const D3D12_TILED_RESOURCE_COORDINATE &o) : + D3D12_TILED_RESOURCE_COORDINATE(o) + {} + CD3DX12_TILED_RESOURCE_COORDINATE( + UINT x, + UINT y, + UINT z, + UINT subresource ) + { + X = x; + Y = y; + Z = z; + Subresource = subresource; + } + operator const D3D12_TILED_RESOURCE_COORDINATE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_REGION_SIZE : public D3D12_TILE_REGION_SIZE +{ + CD3DX12_TILE_REGION_SIZE() + {} + explicit CD3DX12_TILE_REGION_SIZE(const D3D12_TILE_REGION_SIZE &o) : + D3D12_TILE_REGION_SIZE(o) + {} + CD3DX12_TILE_REGION_SIZE( + UINT numTiles, + BOOL useBox, + UINT width, + UINT16 height, + UINT16 depth ) + { + NumTiles = numTiles; + UseBox = useBox; + Width = width; + Height = height; + Depth = depth; + } + operator const D3D12_TILE_REGION_SIZE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_TILING : public D3D12_SUBRESOURCE_TILING +{ + CD3DX12_SUBRESOURCE_TILING() + {} + explicit CD3DX12_SUBRESOURCE_TILING(const D3D12_SUBRESOURCE_TILING &o) : + D3D12_SUBRESOURCE_TILING(o) + {} + CD3DX12_SUBRESOURCE_TILING( + UINT widthInTiles, + UINT16 heightInTiles, + UINT16 depthInTiles, + UINT startTileIndexInOverallResource ) + { + WidthInTiles = widthInTiles; + HeightInTiles = heightInTiles; + DepthInTiles = depthInTiles; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } + operator const D3D12_SUBRESOURCE_TILING&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_SHAPE : public D3D12_TILE_SHAPE +{ + CD3DX12_TILE_SHAPE() + {} + explicit CD3DX12_TILE_SHAPE(const D3D12_TILE_SHAPE &o) : + D3D12_TILE_SHAPE(o) + {} + CD3DX12_TILE_SHAPE( + UINT widthInTexels, + UINT heightInTexels, + UINT depthInTexels ) + { + WidthInTexels = widthInTexels; + HeightInTexels = heightInTexels; + DepthInTexels = depthInTexels; + } + operator const D3D12_TILE_SHAPE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER +{ + CD3DX12_RESOURCE_BARRIER() + {} + explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) : + D3D12_RESOURCE_BARRIER(o) + {} + static inline CD3DX12_RESOURCE_BARRIER Transition( + _In_ ID3D12Resource* pResource, + D3D12_RESOURCE_STATES stateBefore, + D3D12_RESOURCE_STATES stateAfter, + UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, + D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + result.Flags = flags; + barrier.Transition.pResource = pResource; + barrier.Transition.StateBefore = stateBefore; + barrier.Transition.StateAfter = stateAfter; + barrier.Transition.Subresource = subresource; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER Aliasing( + _In_ ID3D12Resource* pResourceBefore, + _In_ ID3D12Resource* pResourceAfter) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING; + barrier.Aliasing.pResourceBefore = pResourceBefore; + barrier.Aliasing.pResourceAfter = pResourceAfter; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER UAV( + _In_ ID3D12Resource* pResource) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; + barrier.UAV.pResource = pResource; + return result; + } + operator const D3D12_RESOURCE_BARRIER&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_PACKED_MIP_INFO : public D3D12_PACKED_MIP_INFO +{ + CD3DX12_PACKED_MIP_INFO() + {} + explicit CD3DX12_PACKED_MIP_INFO(const D3D12_PACKED_MIP_INFO &o) : + D3D12_PACKED_MIP_INFO(o) + {} + CD3DX12_PACKED_MIP_INFO( + UINT8 numStandardMips, + UINT8 numPackedMips, + UINT numTilesForPackedMips, + UINT startTileIndexInOverallResource ) + { + NumStandardMips = numStandardMips; + NumPackedMips = numPackedMips; + NumTilesForPackedMips = numTilesForPackedMips; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } + operator const D3D12_PACKED_MIP_INFO&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_FOOTPRINT : public D3D12_SUBRESOURCE_FOOTPRINT +{ + CD3DX12_SUBRESOURCE_FOOTPRINT() + {} + explicit CD3DX12_SUBRESOURCE_FOOTPRINT(const D3D12_SUBRESOURCE_FOOTPRINT &o) : + D3D12_SUBRESOURCE_FOOTPRINT(o) + {} + CD3DX12_SUBRESOURCE_FOOTPRINT( + DXGI_FORMAT format, + UINT width, + UINT height, + UINT depth, + UINT rowPitch ) + { + Format = format; + Width = width; + Height = height; + Depth = depth; + RowPitch = rowPitch; + } + explicit CD3DX12_SUBRESOURCE_FOOTPRINT( + const D3D12_RESOURCE_DESC& resDesc, + UINT rowPitch ) + { + Format = resDesc.Format; + Width = UINT( resDesc.Width ); + Height = resDesc.Height; + Depth = (resDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? resDesc.DepthOrArraySize : 1); + RowPitch = rowPitch; + } + operator const D3D12_SUBRESOURCE_FOOTPRINT&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TEXTURE_COPY_LOCATION : public D3D12_TEXTURE_COPY_LOCATION +{ + CD3DX12_TEXTURE_COPY_LOCATION() + {} + explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION &o) : + D3D12_TEXTURE_COPY_LOCATION(o) + {} + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes) { pResource = pRes; } + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint) + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + PlacedFootprint = Footprint; + } + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, UINT Sub) + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + SubresourceIndex = Sub; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DESCRIPTOR_RANGE : public D3D12_DESCRIPTOR_RANGE +{ + CD3DX12_DESCRIPTOR_RANGE() { } + explicit CD3DX12_DESCRIPTOR_RANGE(const D3D12_DESCRIPTOR_RANGE &o) : + D3D12_DESCRIPTOR_RANGE(o) + {} + CD3DX12_DESCRIPTOR_RANGE( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + inline void Init( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + static inline void Init( + _Out_ D3D12_DESCRIPTOR_RANGE &range, + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + range.RangeType = rangeType; + range.NumDescriptors = numDescriptors; + range.BaseShaderRegister = baseShaderRegister; + range.RegisterSpace = registerSpace; + range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR_TABLE : public D3D12_ROOT_DESCRIPTOR_TABLE +{ + CD3DX12_ROOT_DESCRIPTOR_TABLE() {} + explicit CD3DX12_ROOT_DESCRIPTOR_TABLE(const D3D12_ROOT_DESCRIPTOR_TABLE &o) : + D3D12_ROOT_DESCRIPTOR_TABLE(o) + {} + CD3DX12_ROOT_DESCRIPTOR_TABLE( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + Init(numDescriptorRanges, _pDescriptorRanges); + } + + inline void Init( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + Init(*this, numDescriptorRanges, _pDescriptorRanges); + } + + static inline void Init( + _Out_ D3D12_ROOT_DESCRIPTOR_TABLE &rootDescriptorTable, + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges; + rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_CONSTANTS : public D3D12_ROOT_CONSTANTS +{ + CD3DX12_ROOT_CONSTANTS() {} + explicit CD3DX12_ROOT_CONSTANTS(const D3D12_ROOT_CONSTANTS &o) : + D3D12_ROOT_CONSTANTS(o) + {} + CD3DX12_ROOT_CONSTANTS( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(num32BitValues, shaderRegister, registerSpace); + } + + inline void Init( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(*this, num32BitValues, shaderRegister, registerSpace); + } + + static inline void Init( + _Out_ D3D12_ROOT_CONSTANTS &rootConstants, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + rootConstants.Num32BitValues = num32BitValues; + rootConstants.ShaderRegister = shaderRegister; + rootConstants.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR : public D3D12_ROOT_DESCRIPTOR +{ + CD3DX12_ROOT_DESCRIPTOR() {} + explicit CD3DX12_ROOT_DESCRIPTOR(const D3D12_ROOT_DESCRIPTOR &o) : + D3D12_ROOT_DESCRIPTOR(o) + {} + CD3DX12_ROOT_DESCRIPTOR( + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(shaderRegister, registerSpace); + } + + inline void Init( + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(*this, shaderRegister, registerSpace); + } + + static inline void Init(_Out_ D3D12_ROOT_DESCRIPTOR &table, UINT shaderRegister, UINT registerSpace = 0) + { + table.ShaderRegister = shaderRegister; + table.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_PARAMETER : public D3D12_ROOT_PARAMETER +{ + CD3DX12_ROOT_PARAMETER() {} + explicit CD3DX12_ROOT_PARAMETER(const D3D12_ROOT_PARAMETER &o) : + D3D12_ROOT_PARAMETER(o) + {} + + static inline void InitAsDescriptorTable( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR_TABLE::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges); + } + + static inline void InitAsConstants( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace); + } + + static inline void InitAsConstantBufferView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsShaderResourceView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsUnorderedAccessView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + inline void InitAsDescriptorTable( + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility); + } + + inline void InitAsConstants( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility); + } + + inline void InitAsConstantBufferView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstantBufferView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsShaderResourceView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsShaderResourceView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsUnorderedAccessView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, visibility); + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_STATIC_SAMPLER_DESC : public D3D12_STATIC_SAMPLER_DESC +{ + CD3DX12_STATIC_SAMPLER_DESC() {} + explicit CD3DX12_STATIC_SAMPLER_DESC(const D3D12_STATIC_SAMPLER_DESC &o) : + D3D12_STATIC_SAMPLER_DESC(o) + {} + CD3DX12_STATIC_SAMPLER_DESC( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + Init( + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + + static inline void Init( + _Out_ D3D12_STATIC_SAMPLER_DESC &samplerDesc, + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + samplerDesc.ShaderRegister = shaderRegister; + samplerDesc.Filter = filter; + samplerDesc.AddressU = addressU; + samplerDesc.AddressV = addressV; + samplerDesc.AddressW = addressW; + samplerDesc.MipLODBias = mipLODBias; + samplerDesc.MaxAnisotropy = maxAnisotropy; + samplerDesc.ComparisonFunc = comparisonFunc; + samplerDesc.BorderColor = borderColor; + samplerDesc.MinLOD = minLOD; + samplerDesc.MaxLOD = maxLOD; + samplerDesc.ShaderVisibility = shaderVisibility; + samplerDesc.RegisterSpace = registerSpace; + } + inline void Init( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + Init( + *this, + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_SIGNATURE_DESC : public D3D12_ROOT_SIGNATURE_DESC +{ + CD3DX12_ROOT_SIGNATURE_DESC() {} + explicit CD3DX12_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) : + D3D12_ROOT_SIGNATURE_DESC(o) + {} + CD3DX12_ROOT_SIGNATURE_DESC( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + CD3DX12_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) + { + Init(0, NULL, 0, NULL, D3D12_ROOT_SIGNATURE_FLAG_NONE); + } + + inline void Init( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + + static inline void Init( + _Out_ D3D12_ROOT_SIGNATURE_DESC &desc, + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + desc.NumParameters = numParameters; + desc.pParameters = _pParameters; + desc.NumStaticSamplers = numStaticSamplers; + desc.pStaticSamplers = _pStaticSamplers; + desc.Flags = flags; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CPU_DESCRIPTOR_HANDLE : public D3D12_CPU_DESCRIPTOR_HANDLE +{ + CD3DX12_CPU_DESCRIPTOR_HANDLE() {} + explicit CD3DX12_CPU_DESCRIPTOR_HANDLE(const D3D12_CPU_DESCRIPTOR_HANDLE &o) : + D3D12_CPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) + { + ptr += offsetInDescriptors * descriptorIncrementSize; + return *this; + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) + { + ptr += offsetScaledByIncrementSize; + return *this; + } + bool operator==(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) + { + return (ptr == other.ptr); + } + bool operator!=(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) + { + return (ptr != other.ptr); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE &operator=(const D3D12_CPU_DESCRIPTOR_HANDLE &other) + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + handle.ptr = base.ptr + offsetScaledByIncrementSize; + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE +{ + CD3DX12_GPU_DESCRIPTOR_HANDLE() {} + explicit CD3DX12_GPU_DESCRIPTOR_HANDLE(const D3D12_GPU_DESCRIPTOR_HANDLE &o) : + D3D12_GPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_GPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) + { + ptr += offsetInDescriptors * descriptorIncrementSize; + return *this; + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) + { + ptr += offsetScaledByIncrementSize; + return *this; + } + inline bool operator==(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) + { + return (ptr == other.ptr); + } + inline bool operator!=(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) + { + return (ptr != other.ptr); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE &operator=(const D3D12_GPU_DESCRIPTOR_HANDLE &other) + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + handle.ptr = base.ptr + offsetScaledByIncrementSize; + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize; + } +}; + +//------------------------------------------------------------------------------------------------ +inline UINT D3D12CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize ) +{ + return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize; +} + +//------------------------------------------------------------------------------------------------ +template <typename T, typename U, typename V> +inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) +{ + MipSlice = static_cast<T>(Subresource % MipLevels); + ArraySlice = static_cast<U>((Subresource / MipLevels) % ArraySize); + PlaneSlice = static_cast<V>(Subresource / (MipLevels * ArraySize)); +} + +//------------------------------------------------------------------------------------------------ +inline UINT8 D3D12GetFormatPlaneCount( + _In_ ID3D12Device* pDevice, + DXGI_FORMAT Format + ) +{ + D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = {Format}; + if (FAILED(pDevice->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo)))) + { + return 0; + } + return formatInfo.PlaneCount; +} + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC +{ + CD3DX12_RESOURCE_DESC() + {} + explicit CD3DX12_RESOURCE_DESC( const D3D12_RESOURCE_DESC& o ) : + D3D12_RESOURCE_DESC( o ) + {} + CD3DX12_RESOURCE_DESC( + D3D12_RESOURCE_DIMENSION dimension, + UINT64 alignment, + UINT64 width, + UINT height, + UINT16 depthOrArraySize, + UINT16 mipLevels, + DXGI_FORMAT format, + UINT sampleCount, + UINT sampleQuality, + D3D12_TEXTURE_LAYOUT layout, + D3D12_RESOURCE_FLAGS flags ) + { + Dimension = dimension; + Alignment = alignment; + Width = width; + Height = height; + DepthOrArraySize = depthOrArraySize; + MipLevels = mipLevels; + Format = format; + SampleDesc.Count = sampleCount; + SampleDesc.Quality = sampleQuality; + Layout = layout; + Flags = flags; + } + static inline CD3DX12_RESOURCE_DESC Buffer( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes, + 1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); + } + static inline CD3DX12_RESOURCE_DESC Buffer( + UINT64 width, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1, + DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex1D( + DXGI_FORMAT format, + UINT64 width, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize, + mipLevels, format, 1, 0, layout, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex2D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + UINT sampleCount = 1, + UINT sampleQuality = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize, + mipLevels, format, sampleCount, sampleQuality, layout, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex3D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 depth, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth, + mipLevels, format, 1, 0, layout, flags ); + } + inline UINT16 Depth() const + { return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT16 ArraySize() const + { return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT8 PlaneCount(_In_ ID3D12Device* pDevice) const + { return D3D12GetFormatPlaneCount(pDevice, Format); } + inline UINT Subresources(_In_ ID3D12Device* pDevice) const + { return MipLevels * ArraySize() * PlaneCount(pDevice); } + inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice) + { return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize()); } + operator const D3D12_RESOURCE_DESC&() const { return *this; } +}; +inline bool operator==( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) +{ + return l.Dimension == r.Dimension && + l.Alignment == r.Alignment && + l.Width == r.Width && + l.Height == r.Height && + l.DepthOrArraySize == r.DepthOrArraySize && + l.MipLevels == r.MipLevels && + l.Format == r.Format && + l.SampleDesc.Count == r.SampleDesc.Count && + l.SampleDesc.Quality == r.SampleDesc.Quality && + l.Layout == r.Layout && + l.Flags == r.Flags; +} +inline bool operator!=( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +// Row-by-row memcpy +inline void MemcpySubresource( + _In_ const D3D12_MEMCPY_DEST* pDest, + _In_ const D3D12_SUBRESOURCE_DATA* pSrc, + SIZE_T RowSizeInBytes, + UINT NumRows, + UINT NumSlices) +{ + for (UINT z = 0; z < NumSlices; ++z) + { + BYTE* pDestSlice = reinterpret_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z; + const BYTE* pSrcSlice = reinterpret_cast<const BYTE*>(pSrc->pData) + pSrc->SlicePitch * z; + for (UINT y = 0; y < NumRows; ++y) + { + memcpy(pDestSlice + pDest->RowPitch * y, + pSrcSlice + pSrc->RowPitch * y, + RowSizeInBytes); + } + } +} + +//------------------------------------------------------------------------------------------------ +// Returns required size of a buffer to be used for data upload +inline UINT64 GetRequiredIntermediateSize( + _In_ ID3D12Resource* pDestinationResource, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources) +{ + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + UINT64 RequiredSize = 0; + + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast<void**>(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize); + pDevice->Release(); + + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// All arrays must be populated (e.g. by calling GetCopyableFootprints) +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 RequiredSize, + _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, + _In_reads_(NumSubresources) const UINT* pNumRows, + _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes, + _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) +{ + // Minor validation + D3D12_RESOURCE_DESC IntermediateDesc = pIntermediate->GetDesc(); + D3D12_RESOURCE_DESC DestinationDesc = pDestinationResource->GetDesc(); + if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER || + IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || + RequiredSize > (SIZE_T)-1 || + (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && + (FirstSubresource != 0 || NumSubresources != 1))) + { + return 0; + } + + BYTE* pData; + HRESULT hr = pIntermediate->Map(0, NULL, reinterpret_cast<void**>(&pData)); + if (FAILED(hr)) + { + return 0; + } + + for (UINT i = 0; i < NumSubresources; ++i) + { + if (pRowSizesInBytes[i] > (SIZE_T)-1) return 0; + D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, pLayouts[i].Footprint.RowPitch * pNumRows[i] }; + MemcpySubresource(&DestData, &pSrcData[i], (SIZE_T)pRowSizesInBytes[i], pNumRows[i], pLayouts[i].Footprint.Depth); + } + pIntermediate->Unmap(0, NULL); + + if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + CD3DX12_BOX SrcBox( UINT( pLayouts[0].Offset ), UINT( pLayouts[0].Offset + pLayouts[0].Footprint.Width ) ); + pCmdList->CopyBufferRegion( + pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width); + } + else + { + for (UINT i = 0; i < NumSubresources; ++i) + { + CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource); + CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]); + pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr); + } + } + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// Heap-allocating UpdateSubresources implementation +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) +{ + UINT64 RequiredSize = 0; + UINT64 MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources; + if (MemToAlloc > SIZE_MAX) + { + return 0; + } + void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc)); + if (pMem == NULL) + { + return 0; + } + D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem); + UINT64* pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources); + UINT* pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources); + + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast<void**>(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize); + pDevice->Release(); + + UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData); + HeapFree(GetProcessHeap(), 0, pMem); + return Result; +} + +//------------------------------------------------------------------------------------------------ +// Stack-allocating UpdateSubresources implementation +template <UINT MaxSubresources> +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0, MaxSubresources) UINT FirstSubresource, + _In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) +{ + UINT64 RequiredSize = 0; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources]; + UINT NumRows[MaxSubresources]; + UINT64 RowSizesInBytes[MaxSubresources]; + + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast<void**>(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize); + pDevice->Release(); + + return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData); +} + +//------------------------------------------------------------------------------------------------ +inline bool D3D12IsLayoutOpaque( D3D12_TEXTURE_LAYOUT Layout ) +{ return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; } + +//------------------------------------------------------------------------------------------------ +inline ID3D12CommandList * const * CommandListCast(ID3D12GraphicsCommandList * const * pp) +{ + // This cast is useful for passing strongly typed command list pointers into + // ExecuteCommandLists. + // This cast is valid as long as the const-ness is respected. D3D12 APIs do + // respect the const-ness of their arguments. + return reinterpret_cast<ID3D12CommandList * const *>(pp); +} + + +#endif // defined( __cplusplus ) + +#endif //__D3DX12_H__ + + + diff --git a/samples/D3D12/src/d3dx12p.h b/samples/D3D12/src/d3dx12p.h new file mode 100644 index 0000000..40535a8 --- /dev/null +++ b/samples/D3D12/src/d3dx12p.h @@ -0,0 +1,1590 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx12.h +// Content: D3DX12 utility library +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DX12_H__ +#define __D3DX12_H__ + +#include "d3d12p.h" + +#if defined( __cplusplus ) + +struct CD3DX12_DEFAULT {}; +extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT; + +//------------------------------------------------------------------------------------------------ +inline bool operator==( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) +{ + return l.TopLeftX == r.TopLeftX && l.TopLeftY == r.TopLeftY && l.Width == r.Width && + l.Height == r.Height && l.MinDepth == r.MinDepth && l.MaxDepth == r.MaxDepth; +} + +//------------------------------------------------------------------------------------------------ +inline bool operator!=( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RECT : public D3D12_RECT +{ + CD3DX12_RECT() + {} + explicit CD3DX12_RECT( const D3D12_RECT& o ) : + D3D12_RECT( o ) + {} + explicit CD3DX12_RECT( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom ) + { + left = Left; + top = Top; + right = Right; + bottom = Bottom; + } + ~CD3DX12_RECT() {} + operator const D3D12_RECT&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BOX : public D3D12_BOX +{ + CD3DX12_BOX() + {} + explicit CD3DX12_BOX( const D3D12_BOX& o ) : + D3D12_BOX( o ) + {} + explicit CD3DX12_BOX( + LONG Left, + LONG Right ) + { + left = Left; + top = 0; + front = 0; + right = Right; + bottom = 1; + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom ) + { + left = Left; + top = Top; + front = 0; + right = Right; + bottom = Bottom; + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Front, + LONG Right, + LONG Bottom, + LONG Back ) + { + left = Left; + top = Top; + front = Front; + right = Right; + bottom = Bottom; + back = Back; + } + ~CD3DX12_BOX() {} + operator const D3D12_BOX&() const { return *this; } +}; +inline bool operator==( const D3D12_BOX& l, const D3D12_BOX& r ) +{ + return l.left == r.left && l.top == r.top && l.front == r.front && + l.right == r.right && l.bottom == r.bottom && l.back == r.back; +} +inline bool operator!=( const D3D12_BOX& l, const D3D12_BOX& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DEPTH_STENCIL_DESC : public D3D12_DEPTH_STENCIL_DESC +{ + CD3DX12_DEPTH_STENCIL_DESC() + {} + explicit CD3DX12_DEPTH_STENCIL_DESC( const D3D12_DEPTH_STENCIL_DESC& o ) : + D3D12_DEPTH_STENCIL_DESC( o ) + {} + explicit CD3DX12_DEPTH_STENCIL_DESC( CD3DX12_DEFAULT ) + { + DepthEnable = TRUE; + DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + DepthFunc = D3D12_COMPARISON_FUNC_LESS; + StencilEnable = FALSE; + StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; + StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; + const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = + { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS }; + FrontFace = defaultStencilOp; + BackFace = defaultStencilOp; + } + explicit CD3DX12_DEPTH_STENCIL_DESC( + BOOL depthEnable, + D3D12_DEPTH_WRITE_MASK depthWriteMask, + D3D12_COMPARISON_FUNC depthFunc, + BOOL stencilEnable, + UINT8 stencilReadMask, + UINT8 stencilWriteMask, + D3D12_STENCIL_OP frontStencilFailOp, + D3D12_STENCIL_OP frontStencilDepthFailOp, + D3D12_STENCIL_OP frontStencilPassOp, + D3D12_COMPARISON_FUNC frontStencilFunc, + D3D12_STENCIL_OP backStencilFailOp, + D3D12_STENCIL_OP backStencilDepthFailOp, + D3D12_STENCIL_OP backStencilPassOp, + D3D12_COMPARISON_FUNC backStencilFunc ) + { + DepthEnable = depthEnable; + DepthWriteMask = depthWriteMask; + DepthFunc = depthFunc; + StencilEnable = stencilEnable; + StencilReadMask = stencilReadMask; + StencilWriteMask = stencilWriteMask; + FrontFace.StencilFailOp = frontStencilFailOp; + FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; + FrontFace.StencilPassOp = frontStencilPassOp; + FrontFace.StencilFunc = frontStencilFunc; + BackFace.StencilFailOp = backStencilFailOp; + BackFace.StencilDepthFailOp = backStencilDepthFailOp; + BackFace.StencilPassOp = backStencilPassOp; + BackFace.StencilFunc = backStencilFunc; + } + ~CD3DX12_DEPTH_STENCIL_DESC() {} + operator const D3D12_DEPTH_STENCIL_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC +{ + CD3DX12_BLEND_DESC() + {} + explicit CD3DX12_BLEND_DESC( const D3D12_BLEND_DESC& o ) : + D3D12_BLEND_DESC( o ) + {} + explicit CD3DX12_BLEND_DESC( CD3DX12_DEFAULT ) + { + AlphaToCoverageEnable = FALSE; + IndependentBlendEnable = FALSE; + const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = + { + FALSE,FALSE, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + D3D12_COLOR_WRITE_ENABLE_ALL, + }; + for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + RenderTarget[ i ] = defaultRenderTargetBlendDesc; + } + ~CD3DX12_BLEND_DESC() {} + operator const D3D12_BLEND_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC +{ + CD3DX12_RASTERIZER_DESC() + {} + explicit CD3DX12_RASTERIZER_DESC( const D3D12_RASTERIZER_DESC& o ) : + D3D12_RASTERIZER_DESC( o ) + {} + explicit CD3DX12_RASTERIZER_DESC( CD3DX12_DEFAULT ) + { + FillMode = D3D12_FILL_MODE_SOLID; + CullMode = D3D12_CULL_MODE_BACK; + FrontCounterClockwise = FALSE; + DepthBias = D3D12_DEFAULT_DEPTH_BIAS; + DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; + SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + DepthClipEnable = TRUE; + MultisampleEnable = FALSE; + AntialiasedLineEnable = FALSE; + ForcedSampleCount = 0; + ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + } + explicit CD3DX12_RASTERIZER_DESC( + D3D12_FILL_MODE fillMode, + D3D12_CULL_MODE cullMode, + BOOL frontCounterClockwise, + INT depthBias, + FLOAT depthBiasClamp, + FLOAT slopeScaledDepthBias, + BOOL depthClipEnable, + BOOL multisampleEnable, + BOOL antialiasedLineEnable, + UINT forcedSampleCount, + D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster) + { + FillMode = fillMode; + CullMode = cullMode; + FrontCounterClockwise = frontCounterClockwise; + DepthBias = depthBias; + DepthBiasClamp = depthBiasClamp; + SlopeScaledDepthBias = slopeScaledDepthBias; + DepthClipEnable = depthClipEnable; + MultisampleEnable = multisampleEnable; + AntialiasedLineEnable = antialiasedLineEnable; + ForcedSampleCount = forcedSampleCount; + ConservativeRaster = conservativeRaster; + } + ~CD3DX12_RASTERIZER_DESC() {} + operator const D3D12_RASTERIZER_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_ALLOCATION_INFO : public D3D12_RESOURCE_ALLOCATION_INFO +{ + CD3DX12_RESOURCE_ALLOCATION_INFO() + {} + explicit CD3DX12_RESOURCE_ALLOCATION_INFO( const D3D12_RESOURCE_ALLOCATION_INFO& o ) : + D3D12_RESOURCE_ALLOCATION_INFO( o ) + {} + CD3DX12_RESOURCE_ALLOCATION_INFO( + UINT64 size, + UINT64 alignment ) + { + SizeInBytes = size; + Alignment = alignment; + } + operator const D3D12_RESOURCE_ALLOCATION_INFO&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES +{ + CD3DX12_HEAP_PROPERTIES() + {} + explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) : + D3D12_HEAP_PROPERTIES(o) + {} + CD3DX12_HEAP_PROPERTIES( + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT creationNodeMask = 1, + UINT nodeMask = 1 ) + { + Type = D3D12_HEAP_TYPE_CUSTOM; + CPUPageProperty = cpuPageProperty; + MemoryPoolPreference = memoryPoolPreference; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + explicit CD3DX12_HEAP_PROPERTIES( + D3D12_HEAP_TYPE type, + UINT creationNodeMask = 1, + UINT nodeMask = 1 ) + { + Type = type; + CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + operator const D3D12_HEAP_PROPERTIES&() const { return *this; } + bool IsCPUAccessible() const + { + return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM && + (CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK)); + } +}; +inline bool operator==( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) +{ + return l.Type == r.Type && l.CPUPageProperty == r.CPUPageProperty && + l.MemoryPoolPreference == r.MemoryPoolPreference && + l.CreationNodeMask == r.CreationNodeMask && + l.VisibleNodeMask == r.VisibleNodeMask; +} +inline bool operator!=( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_DESC : public D3D12_HEAP_DESC +{ + CD3DX12_HEAP_DESC() + {} + explicit CD3DX12_HEAP_DESC(const D3D12_HEAP_DESC &o) : + D3D12_HEAP_DESC(o) + {} + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_PROPERTIES properties, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = properties; + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_TYPE type, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES( type ); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_PROPERTIES properties, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = properties; + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_TYPE type, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES( type ); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + operator const D3D12_HEAP_DESC&() const { return *this; } + bool IsCPUAccessible() const + { return static_cast< const CD3DX12_HEAP_PROPERTIES* >( &Properties )->IsCPUAccessible(); } +}; +inline bool operator==( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) +{ + return l.SizeInBytes == r.SizeInBytes && + l.Properties == r.Properties && + l.Alignment == r.Alignment && + l.Flags == r.Flags; +} +inline bool operator!=( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CLEAR_VALUE : public D3D12_CLEAR_VALUE +{ + CD3DX12_CLEAR_VALUE() + {} + explicit CD3DX12_CLEAR_VALUE(const D3D12_CLEAR_VALUE &o) : + D3D12_CLEAR_VALUE(o) + {} + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + const FLOAT color[4] ) + { + Format = format; + memcpy( Color, color, sizeof( Color ) ); + } + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + FLOAT depth, + UINT8 stencil ) + { + Format = format; + /* Use memcpy to preserve NAN values */ + memcpy( &DepthStencil.Depth, &depth, sizeof( depth ) ); + DepthStencil.Stencil = stencil; + } + operator const D3D12_CLEAR_VALUE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RANGE : public D3D12_RANGE +{ + CD3DX12_RANGE() + {} + explicit CD3DX12_RANGE(const D3D12_RANGE &o) : + D3D12_RANGE(o) + {} + CD3DX12_RANGE( + SIZE_T begin, + SIZE_T end ) + { + Begin = begin; + End = end; + } + operator const D3D12_RANGE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILED_RESOURCE_COORDINATE : public D3D12_TILED_RESOURCE_COORDINATE +{ + CD3DX12_TILED_RESOURCE_COORDINATE() + {} + explicit CD3DX12_TILED_RESOURCE_COORDINATE(const D3D12_TILED_RESOURCE_COORDINATE &o) : + D3D12_TILED_RESOURCE_COORDINATE(o) + {} + CD3DX12_TILED_RESOURCE_COORDINATE( + UINT x, + UINT y, + UINT z, + UINT subresource ) + { + X = x; + Y = y; + Z = z; + Subresource = subresource; + } + operator const D3D12_TILED_RESOURCE_COORDINATE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_REGION_SIZE : public D3D12_TILE_REGION_SIZE +{ + CD3DX12_TILE_REGION_SIZE() + {} + explicit CD3DX12_TILE_REGION_SIZE(const D3D12_TILE_REGION_SIZE &o) : + D3D12_TILE_REGION_SIZE(o) + {} + CD3DX12_TILE_REGION_SIZE( + UINT numTiles, + BOOL useBox, + UINT width, + UINT16 height, + UINT16 depth ) + { + NumTiles = numTiles; + UseBox = useBox; + Width = width; + Height = height; + Depth = depth; + } + operator const D3D12_TILE_REGION_SIZE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_TILING : public D3D12_SUBRESOURCE_TILING +{ + CD3DX12_SUBRESOURCE_TILING() + {} + explicit CD3DX12_SUBRESOURCE_TILING(const D3D12_SUBRESOURCE_TILING &o) : + D3D12_SUBRESOURCE_TILING(o) + {} + CD3DX12_SUBRESOURCE_TILING( + UINT widthInTiles, + UINT16 heightInTiles, + UINT16 depthInTiles, + UINT startTileIndexInOverallResource ) + { + WidthInTiles = widthInTiles; + HeightInTiles = heightInTiles; + DepthInTiles = depthInTiles; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } + operator const D3D12_SUBRESOURCE_TILING&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_SHAPE : public D3D12_TILE_SHAPE +{ + CD3DX12_TILE_SHAPE() + {} + explicit CD3DX12_TILE_SHAPE(const D3D12_TILE_SHAPE &o) : + D3D12_TILE_SHAPE(o) + {} + CD3DX12_TILE_SHAPE( + UINT widthInTexels, + UINT heightInTexels, + UINT depthInTexels ) + { + WidthInTexels = widthInTexels; + HeightInTexels = heightInTexels; + DepthInTexels = depthInTexels; + } + operator const D3D12_TILE_SHAPE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER +{ + CD3DX12_RESOURCE_BARRIER() + {} + explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) : + D3D12_RESOURCE_BARRIER(o) + {} + static inline CD3DX12_RESOURCE_BARRIER Transition( + _In_ ID3D12Resource* pResource, + D3D12_RESOURCE_STATES stateBefore, + D3D12_RESOURCE_STATES stateAfter, + UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, + D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + result.Flags = flags; + barrier.Transition.pResource = pResource; + barrier.Transition.StateBefore = stateBefore; + barrier.Transition.StateAfter = stateAfter; + barrier.Transition.Subresource = subresource; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER Aliasing( + _In_ ID3D12Resource* pResourceBefore, + _In_ ID3D12Resource* pResourceAfter) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING; + barrier.Aliasing.pResourceBefore = pResourceBefore; + barrier.Aliasing.pResourceAfter = pResourceAfter; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER UAV( + _In_ ID3D12Resource* pResource) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; + barrier.UAV.pResource = pResource; + return result; + } + operator const D3D12_RESOURCE_BARRIER&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_PACKED_MIP_INFO : public D3D12_PACKED_MIP_INFO +{ + CD3DX12_PACKED_MIP_INFO() + {} + explicit CD3DX12_PACKED_MIP_INFO(const D3D12_PACKED_MIP_INFO &o) : + D3D12_PACKED_MIP_INFO(o) + {} + CD3DX12_PACKED_MIP_INFO( + UINT8 numStandardMips, + UINT8 numPackedMips, + UINT numTilesForPackedMips, + UINT startTileIndexInOverallResource ) + { + NumStandardMips = numStandardMips; + NumPackedMips = numPackedMips; + NumTilesForPackedMips = numTilesForPackedMips; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } + operator const D3D12_PACKED_MIP_INFO&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_FOOTPRINT : public D3D12_SUBRESOURCE_FOOTPRINT +{ + CD3DX12_SUBRESOURCE_FOOTPRINT() + {} + explicit CD3DX12_SUBRESOURCE_FOOTPRINT(const D3D12_SUBRESOURCE_FOOTPRINT &o) : + D3D12_SUBRESOURCE_FOOTPRINT(o) + {} + CD3DX12_SUBRESOURCE_FOOTPRINT( + DXGI_FORMAT format, + UINT width, + UINT height, + UINT depth, + UINT rowPitch ) + { + Format = format; + Width = width; + Height = height; + Depth = depth; + RowPitch = rowPitch; + } + explicit CD3DX12_SUBRESOURCE_FOOTPRINT( + const D3D12_RESOURCE_DESC& resDesc, + UINT rowPitch ) + { + Format = resDesc.Format; + Width = UINT( resDesc.Width ); + Height = resDesc.Height; + Depth = (resDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? resDesc.DepthOrArraySize : 1); + RowPitch = rowPitch; + } + operator const D3D12_SUBRESOURCE_FOOTPRINT&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TEXTURE_COPY_LOCATION : public D3D12_TEXTURE_COPY_LOCATION +{ + CD3DX12_TEXTURE_COPY_LOCATION() + {} + explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION &o) : + D3D12_TEXTURE_COPY_LOCATION(o) + {} + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes) { pResource = pRes; } + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint) + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + PlacedFootprint = Footprint; + } + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, UINT Sub) + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + SubresourceIndex = Sub; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DESCRIPTOR_RANGE : public D3D12_DESCRIPTOR_RANGE +{ + CD3DX12_DESCRIPTOR_RANGE() { } + explicit CD3DX12_DESCRIPTOR_RANGE(const D3D12_DESCRIPTOR_RANGE &o) : + D3D12_DESCRIPTOR_RANGE(o) + {} + CD3DX12_DESCRIPTOR_RANGE( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + inline void Init( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + static inline void Init( + _Out_ D3D12_DESCRIPTOR_RANGE &range, + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + range.RangeType = rangeType; + range.NumDescriptors = numDescriptors; + range.BaseShaderRegister = baseShaderRegister; + range.RegisterSpace = registerSpace; + range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR_TABLE : public D3D12_ROOT_DESCRIPTOR_TABLE +{ + CD3DX12_ROOT_DESCRIPTOR_TABLE() {} + explicit CD3DX12_ROOT_DESCRIPTOR_TABLE(const D3D12_ROOT_DESCRIPTOR_TABLE &o) : + D3D12_ROOT_DESCRIPTOR_TABLE(o) + {} + CD3DX12_ROOT_DESCRIPTOR_TABLE( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + Init(numDescriptorRanges, _pDescriptorRanges); + } + + inline void Init( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + Init(*this, numDescriptorRanges, _pDescriptorRanges); + } + + static inline void Init( + _Out_ D3D12_ROOT_DESCRIPTOR_TABLE &rootDescriptorTable, + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges; + rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_CONSTANTS : public D3D12_ROOT_CONSTANTS +{ + CD3DX12_ROOT_CONSTANTS() {} + explicit CD3DX12_ROOT_CONSTANTS(const D3D12_ROOT_CONSTANTS &o) : + D3D12_ROOT_CONSTANTS(o) + {} + CD3DX12_ROOT_CONSTANTS( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(num32BitValues, shaderRegister, registerSpace); + } + + inline void Init( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(*this, num32BitValues, shaderRegister, registerSpace); + } + + static inline void Init( + _Out_ D3D12_ROOT_CONSTANTS &rootConstants, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + rootConstants.Num32BitValues = num32BitValues; + rootConstants.ShaderRegister = shaderRegister; + rootConstants.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR : public D3D12_ROOT_DESCRIPTOR +{ + CD3DX12_ROOT_DESCRIPTOR() {} + explicit CD3DX12_ROOT_DESCRIPTOR(const D3D12_ROOT_DESCRIPTOR &o) : + D3D12_ROOT_DESCRIPTOR(o) + {} + CD3DX12_ROOT_DESCRIPTOR( + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(shaderRegister, registerSpace); + } + + inline void Init( + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(*this, shaderRegister, registerSpace); + } + + static inline void Init(_Out_ D3D12_ROOT_DESCRIPTOR &table, UINT shaderRegister, UINT registerSpace = 0) + { + table.ShaderRegister = shaderRegister; + table.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_PARAMETER : public D3D12_ROOT_PARAMETER +{ + CD3DX12_ROOT_PARAMETER() {} + explicit CD3DX12_ROOT_PARAMETER(const D3D12_ROOT_PARAMETER &o) : + D3D12_ROOT_PARAMETER(o) + {} + + static inline void InitAsDescriptorTable( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR_TABLE::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges); + } + + static inline void InitAsConstants( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace); + } + + static inline void InitAsConstantBufferView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsShaderResourceView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsUnorderedAccessView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + inline void InitAsDescriptorTable( + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility); + } + + inline void InitAsConstants( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility); + } + + inline void InitAsConstantBufferView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstantBufferView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsShaderResourceView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsShaderResourceView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsUnorderedAccessView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, visibility); + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_STATIC_SAMPLER_DESC : public D3D12_STATIC_SAMPLER_DESC +{ + CD3DX12_STATIC_SAMPLER_DESC() {} + explicit CD3DX12_STATIC_SAMPLER_DESC(const D3D12_STATIC_SAMPLER_DESC &o) : + D3D12_STATIC_SAMPLER_DESC(o) + {} + CD3DX12_STATIC_SAMPLER_DESC( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + Init( + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + + static inline void Init( + _Out_ D3D12_STATIC_SAMPLER_DESC &samplerDesc, + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + samplerDesc.ShaderRegister = shaderRegister; + samplerDesc.Filter = filter; + samplerDesc.AddressU = addressU; + samplerDesc.AddressV = addressV; + samplerDesc.AddressW = addressW; + samplerDesc.MipLODBias = mipLODBias; + samplerDesc.MaxAnisotropy = maxAnisotropy; + samplerDesc.ComparisonFunc = comparisonFunc; + samplerDesc.BorderColor = borderColor; + samplerDesc.MinLOD = minLOD; + samplerDesc.MaxLOD = maxLOD; + samplerDesc.ShaderVisibility = shaderVisibility; + samplerDesc.RegisterSpace = registerSpace; + } + inline void Init( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + Init( + *this, + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_SIGNATURE_DESC : public D3D12_ROOT_SIGNATURE_DESC +{ + CD3DX12_ROOT_SIGNATURE_DESC() {} + explicit CD3DX12_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) : + D3D12_ROOT_SIGNATURE_DESC(o) + {} + CD3DX12_ROOT_SIGNATURE_DESC( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + CD3DX12_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) + { + Init(0, NULL, 0, NULL, D3D12_ROOT_SIGNATURE_FLAG_NONE); + } + + inline void Init( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + + static inline void Init( + _Out_ D3D12_ROOT_SIGNATURE_DESC &desc, + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + desc.NumParameters = numParameters; + desc.pParameters = _pParameters; + desc.NumStaticSamplers = numStaticSamplers; + desc.pStaticSamplers = _pStaticSamplers; + desc.Flags = flags; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CPU_DESCRIPTOR_HANDLE : public D3D12_CPU_DESCRIPTOR_HANDLE +{ + CD3DX12_CPU_DESCRIPTOR_HANDLE() {} + explicit CD3DX12_CPU_DESCRIPTOR_HANDLE(const D3D12_CPU_DESCRIPTOR_HANDLE &o) : + D3D12_CPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) + { + ptr += offsetInDescriptors * descriptorIncrementSize; + return *this; + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) + { + ptr += offsetScaledByIncrementSize; + return *this; + } + bool operator==(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) + { + return (ptr == other.ptr); + } + bool operator!=(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) + { + return (ptr != other.ptr); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE &operator=(const D3D12_CPU_DESCRIPTOR_HANDLE &other) + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + handle.ptr = base.ptr + offsetScaledByIncrementSize; + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE +{ + CD3DX12_GPU_DESCRIPTOR_HANDLE() {} + explicit CD3DX12_GPU_DESCRIPTOR_HANDLE(const D3D12_GPU_DESCRIPTOR_HANDLE &o) : + D3D12_GPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_GPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) + { + ptr += offsetInDescriptors * descriptorIncrementSize; + return *this; + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) + { + ptr += offsetScaledByIncrementSize; + return *this; + } + inline bool operator==(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) + { + return (ptr == other.ptr); + } + inline bool operator!=(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) + { + return (ptr != other.ptr); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE &operator=(const D3D12_GPU_DESCRIPTOR_HANDLE &other) + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + handle.ptr = base.ptr + offsetScaledByIncrementSize; + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize; + } +}; + +//------------------------------------------------------------------------------------------------ +inline UINT D3D12CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize ) +{ + return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize; +} + +//------------------------------------------------------------------------------------------------ +template <typename T, typename U, typename V> +inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) +{ + MipSlice = static_cast<T>(Subresource % MipLevels); + ArraySlice = static_cast<U>((Subresource / MipLevels) % ArraySize); + PlaneSlice = static_cast<V>(Subresource / (MipLevels * ArraySize)); +} + +//------------------------------------------------------------------------------------------------ +inline UINT8 D3D12GetFormatPlaneCount( + _In_ ID3D12Device* pDevice, + DXGI_FORMAT Format + ) +{ + D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = {Format}; + if (FAILED(pDevice->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo)))) + { + return 0; + } + return formatInfo.PlaneCount; +} + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC +{ + CD3DX12_RESOURCE_DESC() + {} + explicit CD3DX12_RESOURCE_DESC( const D3D12_RESOURCE_DESC& o ) : + D3D12_RESOURCE_DESC( o ) + {} + CD3DX12_RESOURCE_DESC( + D3D12_RESOURCE_DIMENSION dimension, + UINT64 alignment, + UINT64 width, + UINT height, + UINT16 depthOrArraySize, + UINT16 mipLevels, + DXGI_FORMAT format, + UINT sampleCount, + UINT sampleQuality, + D3D12_TEXTURE_LAYOUT layout, + D3D12_RESOURCE_FLAGS flags ) + { + Dimension = dimension; + Alignment = alignment; + Width = width; + Height = height; + DepthOrArraySize = depthOrArraySize; + MipLevels = mipLevels; + Format = format; + SampleDesc.Count = sampleCount; + SampleDesc.Quality = sampleQuality; + Layout = layout; + Flags = flags; + } + static inline CD3DX12_RESOURCE_DESC Buffer( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes, + 1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); + } + static inline CD3DX12_RESOURCE_DESC Buffer( + UINT64 width, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1, + DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex1D( + DXGI_FORMAT format, + UINT64 width, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize, + mipLevels, format, 1, 0, layout, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex2D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + UINT sampleCount = 1, + UINT sampleQuality = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize, + mipLevels, format, sampleCount, sampleQuality, layout, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex3D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 depth, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth, + mipLevels, format, 1, 0, layout, flags ); + } + inline UINT16 Depth() const + { return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT16 ArraySize() const + { return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT8 PlaneCount(_In_ ID3D12Device* pDevice) const + { return D3D12GetFormatPlaneCount(pDevice, Format); } + inline UINT Subresources(_In_ ID3D12Device* pDevice) const + { return MipLevels * ArraySize() * PlaneCount(pDevice); } + inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice) + { return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize()); } + operator const D3D12_RESOURCE_DESC&() const { return *this; } +}; +inline bool operator==( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) +{ + return l.Dimension == r.Dimension && + l.Alignment == r.Alignment && + l.Width == r.Width && + l.Height == r.Height && + l.DepthOrArraySize == r.DepthOrArraySize && + l.MipLevels == r.MipLevels && + l.Format == r.Format && + l.SampleDesc.Count == r.SampleDesc.Count && + l.SampleDesc.Quality == r.SampleDesc.Quality && + l.Layout == r.Layout && + l.Flags == r.Flags; +} +inline bool operator!=( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +// Row-by-row memcpy +inline void MemcpySubresource( + _In_ const D3D12_MEMCPY_DEST* pDest, + _In_ const D3D12_SUBRESOURCE_DATA* pSrc, + SIZE_T RowSizeInBytes, + UINT NumRows, + UINT NumSlices) +{ + for (UINT z = 0; z < NumSlices; ++z) + { + BYTE* pDestSlice = reinterpret_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z; + const BYTE* pSrcSlice = reinterpret_cast<const BYTE*>(pSrc->pData) + pSrc->SlicePitch * z; + for (UINT y = 0; y < NumRows; ++y) + { + memcpy(pDestSlice + pDest->RowPitch * y, + pSrcSlice + pSrc->RowPitch * y, + RowSizeInBytes); + } + } +} + +//------------------------------------------------------------------------------------------------ +// Returns required size of a buffer to be used for data upload +inline UINT64 GetRequiredIntermediateSize( + _In_ ID3D12Resource* pDestinationResource, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources) +{ + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + UINT64 RequiredSize = 0; + + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast<void**>(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize); + pDevice->Release(); + + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// All arrays must be populated (e.g. by calling GetCopyableFootprints) +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 RequiredSize, + _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, + _In_reads_(NumSubresources) const UINT* pNumRows, + _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes, + _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) +{ + // Minor validation + D3D12_RESOURCE_DESC IntermediateDesc = pIntermediate->GetDesc(); + D3D12_RESOURCE_DESC DestinationDesc = pDestinationResource->GetDesc(); + if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER || + IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || + RequiredSize > (SIZE_T)-1 || + (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && + (FirstSubresource != 0 || NumSubresources != 1))) + { + return 0; + } + + BYTE* pData; + HRESULT hr = pIntermediate->Map(0, NULL, reinterpret_cast<void**>(&pData)); + if (FAILED(hr)) + { + return 0; + } + + for (UINT i = 0; i < NumSubresources; ++i) + { + if (pRowSizesInBytes[i] > (SIZE_T)-1) return 0; + D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, pLayouts[i].Footprint.RowPitch * pNumRows[i] }; + MemcpySubresource(&DestData, &pSrcData[i], (SIZE_T)pRowSizesInBytes[i], pNumRows[i], pLayouts[i].Footprint.Depth); + } + pIntermediate->Unmap(0, NULL); + + if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + CD3DX12_BOX SrcBox( UINT( pLayouts[0].Offset ), UINT( pLayouts[0].Offset + pLayouts[0].Footprint.Width ) ); + pCmdList->CopyBufferRegion( + pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width); + } + else + { + for (UINT i = 0; i < NumSubresources; ++i) + { + CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource); + CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]); + pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr); + } + } + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// Heap-allocating UpdateSubresources implementation +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) +{ + UINT64 RequiredSize = 0; + UINT64 MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources; + if (MemToAlloc > SIZE_MAX) + { + return 0; + } + void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc)); + if (pMem == NULL) + { + return 0; + } + D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem); + UINT64* pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources); + UINT* pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources); + + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast<void**>(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize); + pDevice->Release(); + + UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData); + HeapFree(GetProcessHeap(), 0, pMem); + return Result; +} + +//------------------------------------------------------------------------------------------------ +// Stack-allocating UpdateSubresources implementation +template <UINT MaxSubresources> +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0, MaxSubresources) UINT FirstSubresource, + _In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) +{ + UINT64 RequiredSize = 0; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources]; + UINT NumRows[MaxSubresources]; + UINT64 RowSizesInBytes[MaxSubresources]; + + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast<void**>(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize); + pDevice->Release(); + + return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData); +} + +//------------------------------------------------------------------------------------------------ +inline bool D3D12IsLayoutOpaque( D3D12_TEXTURE_LAYOUT Layout ) +{ return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; } + +//------------------------------------------------------------------------------------------------ +inline ID3D12CommandList * const * CommandListCast(ID3D12GraphicsCommandList * const * pp) +{ + // This cast is useful for passing strongly typed command list pointers into + // ExecuteCommandLists. + // This cast is valid as long as the const-ness is respected. D3D12 APIs do + // respect the const-ness of their arguments. + return reinterpret_cast<ID3D12CommandList * const *>(pp); +} + +// +//------------------------------------------------------------------------------------------------ +inline const char* D3D12ToStr( const D3D12_RESOURCE_DIMENSION& val ) +{ + switch( val ) + { + case D3D12_RESOURCE_DIMENSION_UNKNOWN: return "D3D12_RESOURCE_DIMENSION_UNKNOWN"; + case D3D12_RESOURCE_DIMENSION_BUFFER: return "D3D12_RESOURCE_DIMENSION_BUFFER"; + case D3D12_RESOURCE_DIMENSION_TEXTURE1D: return "D3D12_RESOURCE_DIMENSION_TEXTURE1D"; + case D3D12_RESOURCE_DIMENSION_TEXTURE2D: return "D3D12_RESOURCE_DIMENSION_TEXTURE2D"; + case D3D12_RESOURCE_DIMENSION_TEXTURE3D: return "D3D12_RESOURCE_DIMENSION_TEXTURE3D"; + case D3D12_RESOURCE_DIMENSION_MAX_VALID: return "D3D12_RESOURCE_DIMENSION_MAX_VALID"; + default: return "Unrecognized"; + } +} + +//------------------------------------------------------------------------------------------------ +inline const char* D3D12ToStr( const D3D12_TEXTURE_LAYOUT& val ) +{ + switch( val ) + { + case D3D12_TEXTURE_LAYOUT_UNKNOWN: return "D3D12_TEXTURE_LAYOUT_UNKNOWN"; + case D3D12_TEXTURE_LAYOUT_ROW_MAJOR: return "D3D12_TEXTURE_LAYOUT_ROW_MAJOR"; + case D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE: return "D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE"; + case D3D12_TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE: return "D3D12_TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE"; + default: return "Unrecognized"; + } +} + +//------------------------------------------------------------------------------------------------ +inline const char* D3D12ToStr( const D3D12_RESOURCE_HEAP_TIER& val ) +{ + switch( val ) + { + case D3D12_RESOURCE_HEAP_TIER_1: return "D3D12_RESOURCE_HEAP_TIER_1"; + case D3D12_RESOURCE_HEAP_TIER_2: return "D3D12_RESOURCE_HEAP_TIER_2"; + default: return "Unrecognized"; + } +} + +//------------------------------------------------------------------------------------------------ +inline const char* D3D12ToStr( const D3D12_HEAP_TYPE& val ) +{ + switch( val ) + { + case D3D12_HEAP_TYPE_UNKNOWN: return "D3D12_HEAP_TYPE_UNKNOWN"; + case D3D12_HEAP_TYPE_DEFAULT: return "D3D12_HEAP_TYPE_DEFAULT"; + case D3D12_HEAP_TYPE_UPLOAD: return "D3D12_HEAP_TYPE_UPLOAD"; + case D3D12_HEAP_TYPE_READBACK: return "D3D12_HEAP_TYPE_READBACK"; + case D3D12_HEAP_TYPE_CUSTOM: return "D3D12_HEAP_TYPE_CUSTOM"; + case D3D12_HEAP_TYPE_MAX_VALID: return "D3D12_HEAP_TYPE_MAX_VALID"; + default: return "Unrecognized"; + } +} + +//------------------------------------------------------------------------------------------------ +inline const char* D3D12ToStr( const D3D12_CPU_PAGE_PROPERTY& val ) +{ + switch( val ) + { + case D3D12_CPU_PAGE_PROPERTY_UNKNOWN: return "D3D12_CPU_PAGE_PROPERTY_UNKNOWN"; + case D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE: return "D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE"; + case D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE: return "D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE"; + case D3D12_CPU_PAGE_PROPERTY_WRITE_BACK: return "D3D12_CPU_PAGE_PROPERTY_WRITE_BACK"; + case D3D12_CPU_PAGE_PROPERTY_MAX_VALID: return "D3D12_CPU_PAGE_PROPERTY_MAX_VALID"; + default: return "Unrecognized"; + } +} + +//------------------------------------------------------------------------------------------------ +inline const char* D3D12ToStr( const D3D12_MEMORY_POOL& val ) +{ + switch( val ) + { + case D3D12_MEMORY_POOL_UNKNOWN: return "D3D12_MEMORY_POOL_UNKNOWN"; + case D3D12_MEMORY_POOL_L0: return "D3D12_MEMORY_POOL_L0"; + case D3D12_MEMORY_POOL_L1: return "D3D12_MEMORY_POOL_L1"; + case D3D12_MEMORY_POOL_MAX_VALID: return "D3D12_MEMORY_POOL_MAX_VALID"; + default: return "Unrecognized"; + } +} +// + +#endif // defined( __cplusplus ) + +#endif //__D3DX12_H__ + + + |