-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathDxUtility.cpp
More file actions
103 lines (90 loc) · 4.43 KB
/
DxUtility.cpp
File metadata and controls
103 lines (90 loc) · 4.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//*********************************************************
// Copyright (c) Microsoft. All rights reserved.
//
// Apache 2.0 License
//
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.
//
//*********************************************************
#include "pch.h"
#include "DxUtility.h"
#include <D3Dcompiler.h>
#pragma comment(lib, "D3DCompiler.lib")
namespace sample::dx {
winrt::com_ptr<IDXGIAdapter1> GetAdapter(LUID adapterId) {
// Create the DXGI factory.
winrt::com_ptr<IDXGIFactory1> dxgiFactory;
CHECK_HRCMD(CreateDXGIFactory1(winrt::guid_of<IDXGIFactory1>(), dxgiFactory.put_void()));
for (UINT adapterIndex = 0;; adapterIndex++) {
// EnumAdapters1 will fail with DXGI_ERROR_NOT_FOUND when there are no more adapters to enumerate.
winrt::com_ptr<IDXGIAdapter1> dxgiAdapter;
CHECK_HRCMD(dxgiFactory->EnumAdapters1(adapterIndex, dxgiAdapter.put()));
DXGI_ADAPTER_DESC1 adapterDesc;
CHECK_HRCMD(dxgiAdapter->GetDesc1(&adapterDesc));
if (memcmp(&adapterDesc.AdapterLuid, &adapterId, sizeof(adapterId)) == 0) {
DEBUG_PRINT("Using graphics adapter %ws", adapterDesc.Description);
return dxgiAdapter;
}
}
}
void CreateD3D11DeviceAndContext(IDXGIAdapter1* adapter,
const std::vector<D3D_FEATURE_LEVEL>& featureLevels,
ID3D11Device** device,
ID3D11DeviceContext** deviceContext) {
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#ifdef _DEBUG
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
// Create the Direct3D 11 API device object and a corresponding context.
D3D_DRIVER_TYPE driverType = adapter == nullptr ? D3D_DRIVER_TYPE_HARDWARE : D3D_DRIVER_TYPE_UNKNOWN;
TryAgain:
const HRESULT hr = D3D11CreateDevice(adapter,
driverType,
0,
creationFlags,
featureLevels.data(),
(UINT)featureLevels.size(),
D3D11_SDK_VERSION,
device,
nullptr,
deviceContext);
if (FAILED(hr)) {
// If initialization failed, it may be because device debugging isn't supprted, so retry without that.
if ((creationFlags & D3D11_CREATE_DEVICE_DEBUG) && (hr == DXGI_ERROR_SDK_COMPONENT_MISSING)) {
creationFlags &= ~D3D11_CREATE_DEVICE_DEBUG;
goto TryAgain;
}
// If the initialization still fails, fall back to the WARP device.
// For more information on WARP, see: http://go.microsoft.com/fwlink/?LinkId=286690
if (driverType != D3D_DRIVER_TYPE_WARP) {
driverType = D3D_DRIVER_TYPE_WARP;
goto TryAgain;
}
}
}
winrt::com_ptr<ID3DBlob> CompileShader(const char* hlsl, const char* entrypoint, const char* shaderTarget) {
winrt::com_ptr<ID3DBlob> compiled;
winrt::com_ptr<ID3DBlob> errMsgs;
DWORD flags = D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS;
#ifdef _DEBUG
flags |= D3DCOMPILE_SKIP_OPTIMIZATION | D3DCOMPILE_DEBUG;
#else
flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3;
#endif
HRESULT hr =
D3DCompile(hlsl, strlen(hlsl), nullptr, nullptr, nullptr, entrypoint, shaderTarget, flags, 0, compiled.put(), errMsgs.put());
if (FAILED(hr)) {
std::string errMsg((const char*)errMsgs->GetBufferPointer(), errMsgs->GetBufferSize());
DEBUG_PRINT("D3DCompile failed %X: %s", hr, errMsg.c_str());
CHECK_HRESULT(hr, "D3DCompile failed");
}
return compiled;
}
} // namespace sample::dx