aboutsummaryrefslogtreecommitdiff
path: root/dxg/src/dxcommon.c
diff options
context:
space:
mode:
Diffstat (limited to 'dxg/src/dxcommon.c')
-rw-r--r--dxg/src/dxcommon.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/dxg/src/dxcommon.c b/dxg/src/dxcommon.c
new file mode 100644
index 0000000..ecc9a88
--- /dev/null
+++ b/dxg/src/dxcommon.c
@@ -0,0 +1,173 @@
1#include <dxg/dxcommon.h>
2
3// Required so that D3D12.dll can find and load D3D12Core.dll and other DLLs
4// from the Agility SDK. The macro comes from CMakeLists.txt.
5__declspec(dllexport) extern const UINT D3D12SDKVersion = AGILITY_SDK_VERSION;
6__declspec(dllexport) extern const char* D3D12SDKPath = AGILITY_SDK_INSTALL;
7D3D12_RESOURCE_BARRIER CD3DX12_RESOURCE_BARRIER_Transition(
8 ID3D12Resource* pResource,
9 D3D12_RESOURCE_STATES stateBefore,
10 D3D12_RESOURCE_STATES stateAfter) {
11 return (D3D12_RESOURCE_BARRIER){
12 .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
13 .Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE,
14 .Transition.pResource = pResource,
15 .Transition.StateBefore = stateBefore,
16 .Transition.StateAfter = stateAfter,
17 .Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES};
18}
19
20D3D12_RASTERIZER_DESC CD3DX12_RASTERIZER_DESC_DEFAULT() {
21 return (D3D12_RASTERIZER_DESC){
22 .FillMode = D3D12_FILL_MODE_SOLID,
23 .CullMode = D3D12_CULL_MODE_BACK,
24 .FrontCounterClockwise = FALSE,
25 .DepthBias = D3D12_DEFAULT_DEPTH_BIAS,
26 .DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP,
27 .SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,
28 .DepthClipEnable = TRUE,
29 .MultisampleEnable = FALSE,
30 .AntialiasedLineEnable = FALSE,
31 .ForcedSampleCount = 0,
32 .ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF};
33}
34
35D3D12_BLEND_DESC CD3DX12_BLEND_DESC_DEFAULT() {
36 const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = {
37 FALSE, FALSE,
38 D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
39 D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
40 D3D12_LOGIC_OP_NOOP,
41 D3D12_COLOR_WRITE_ENABLE_ALL,
42 };
43 D3D12_BLEND_DESC desc = {
44 .AlphaToCoverageEnable = FALSE,
45 .IndependentBlendEnable = FALSE,
46 };
47 for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) {
48 desc.RenderTarget[i] = defaultRenderTargetBlendDesc;
49 }
50 return desc;
51}
52
53void dxg_wait(ID3D12Fence* pFence, HANDLE fenceEvent, UINT64 fenceValue) {
54 assert(pFence);
55 // Wait for commands to finish execution.
56 // It is possible that execution has already finished by the time we
57 // get here, so first check the fence's completed value.
58 if (pFence->lpVtbl->GetCompletedValue(pFence) < fenceValue) {
59 // GPU Signal still pending. Configure a Windows event and wait for it.
60 // The event fires when the GPU signals.
61 //
62 // Indicate that the fence event is to be fired when the fence reaches
63 // the given fence value.
64 TrapIfFailed(pFence->lpVtbl->SetEventOnCompletion(pFence, fenceValue, fenceEvent));
65 // Will wake up when the fence takes on the given fence value.
66 WaitForSingleObject(fenceEvent, INFINITE);
67 }
68}
69
70// -----------------------------------------------------------------------------
71// Command Recorder
72// -----------------------------------------------------------------------------
73
74HRESULT dxg_cmdrec_init(CommandRecorder* pRec, ID3D12Device* pDevice) {
75 assert(pRec);
76 assert(pDevice);
77
78 HRESULT result = S_OK;
79
80 const D3D12_COMMAND_LIST_TYPE type = D3D12_COMMAND_LIST_TYPE_DIRECT;
81
82 if ((result = pDevice->lpVtbl->CreateCommandAllocator(
83 pDevice, type, &IID_ID3D12CommandAllocator, &pRec->pCmdAllocator)) != S_OK) {
84 return result;
85 }
86
87 if ((result = pDevice->lpVtbl->CreateCommandList(
88 pDevice, 0, type, pRec->pCmdAllocator, NULL, &IID_ID3D12CommandList, &pRec->pCmdList)) != S_OK) {
89 return result;
90 }
91
92 // Command lists start open. Close it for API convenience.
93 if ((result = pRec->pCmdList->lpVtbl->Close(pRec->pCmdList)) != S_OK) {
94 return result;
95 }
96
97 return result;
98}
99
100void dxg_cmdrec_destroy(CommandRecorder* pRec) {
101 assert(pRec);
102 SafeRelease(pRec->pCmdList);
103 SafeRelease(pRec->pCmdAllocator);
104}
105
106HRESULT dxg_cmdrec_reset(CommandRecorder* pRec) {
107 assert(pRec);
108 assert(pRec->pCmdAllocator);
109 assert(pRec->pCmdList);
110 HRESULT result = S_OK;
111 if ((result = pRec->pCmdAllocator->lpVtbl->Reset(pRec->pCmdAllocator)) != S_OK) {
112 return result;
113 }
114 if ((result = pRec->pCmdList->lpVtbl->Reset(pRec->pCmdList, pRec->pCmdAllocator, NULL)) != S_OK) {
115 return result;
116 }
117 return result;
118}
119
120// -----------------------------------------------------------------------------
121// Upload Buffer
122// -----------------------------------------------------------------------------
123
124void dxg_upload_buffer_init(UploadBuffer* pBuf, ID3D12Device* pDevice, size_t size) {
125 assert(pBuf);
126 assert(pDevice);
127
128 pBuf->size = size;
129
130 const D3D12_HEAP_PROPERTIES props = {
131 .Type = D3D12_HEAP_TYPE_UPLOAD,
132 .CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE,
133 .MemoryPoolPreference = D3D12_MEMORY_POOL_L0,
134 .CreationNodeMask = 0,
135 .VisibleNodeMask = 0
136 };
137 // Constant buffers need to be aligned to 256 bytes. Other types of buffers
138 // do not have this requirement. To make the upload buffer general, use the
139 // worst-case alignment.
140 const D3D12_RESOURCE_DESC desc = {
141 .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
142 .Alignment = 256,
143 .Width = size,
144 .Height = 0,
145 .DepthOrArraySize = 0,
146 .MipLevels = 0,
147 .Format = DXGI_FORMAT_UNKNOWN,
148 .SampleDesc = (DXGI_SAMPLE_DESC){0},
149 .Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
150 .Flags = D3D12_RESOURCE_FLAG_NONE
151 };
152 TrapIfFailed(pDevice->lpVtbl->CreateCommittedResource(
153 pDevice,
154 &props,
155 D3D12_HEAP_FLAG_NONE,
156 &desc,
157 D3D12_RESOURCE_STATE_COPY_SOURCE,
158 NULL,
159 &IID_ID3D12Resource,
160 &pBuf->pUploadBuffer));
161}
162
163void dxg_upload_buffer_destroy(UploadBuffer* pBuf, ID3D12Device* pDevice) {
164 assert(pDevice);
165 assert(pBuf);
166 SafeRelease(pBuf->pUploadBuffer);
167}
168
169void dxg_upload_buffer_load(UploadBuffer* pBuf, const void* pData, size_t bytes, ID3D12Resource* pDstBuffer) {
170 assert(pBuf);
171 assert(pData);
172 assert(pDstBuffer);
173}