1 | #include <cstring>
|
---|
2 | #include <d3d9.h>
|
---|
3 |
|
---|
4 | #include "../test_utils.h"
|
---|
5 |
|
---|
6 | using namespace dxvk;
|
---|
7 |
|
---|
8 | struct Extent2D {
|
---|
9 | uint32_t w, h;
|
---|
10 | };
|
---|
11 |
|
---|
12 | DWORD g_UsagePermuatations[] = {
|
---|
13 | 0,
|
---|
14 | D3DUSAGE_DYNAMIC,
|
---|
15 | D3DUSAGE_WRITEONLY,
|
---|
16 | D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC,
|
---|
17 | };
|
---|
18 |
|
---|
19 | DWORD g_MapFlagPermutations[] = {
|
---|
20 | 0,
|
---|
21 | D3DLOCK_DISCARD,
|
---|
22 | D3DLOCK_DONOTWAIT,
|
---|
23 | D3DLOCK_NOOVERWRITE
|
---|
24 | };
|
---|
25 |
|
---|
26 | class BufferApp {
|
---|
27 |
|
---|
28 | public:
|
---|
29 |
|
---|
30 | BufferApp(HINSTANCE instance, HWND window)
|
---|
31 | : m_window(window) {
|
---|
32 | HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d);
|
---|
33 |
|
---|
34 | if (FAILED(status))
|
---|
35 | throw DxvkError("Failed to create D3D9 interface");
|
---|
36 |
|
---|
37 | D3DPRESENT_PARAMETERS params;
|
---|
38 | getPresentParams(params);
|
---|
39 |
|
---|
40 | status = m_d3d->CreateDeviceEx(
|
---|
41 | D3DADAPTER_DEFAULT,
|
---|
42 | D3DDEVTYPE_HAL,
|
---|
43 | m_window,
|
---|
44 | D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
---|
45 | ¶ms,
|
---|
46 | nullptr,
|
---|
47 | &m_device);
|
---|
48 |
|
---|
49 | if (FAILED(status))
|
---|
50 | throw DxvkError("Failed to create D3D9 device");
|
---|
51 |
|
---|
52 | uint8_t* data = new uint8_t[512];
|
---|
53 | std::memset(data, 0xFC, 512);
|
---|
54 |
|
---|
55 | for (uint32_t i = 0; i < ARRAYSIZE(g_UsagePermuatations); i++) {
|
---|
56 | for (uint32_t j = 0; j < ARRAYSIZE(g_MapFlagPermutations); j++) {
|
---|
57 | testBuffer(data, g_UsagePermuatations[i], g_MapFlagPermutations[j]);
|
---|
58 | }
|
---|
59 | }
|
---|
60 |
|
---|
61 | delete[] data;
|
---|
62 | }
|
---|
63 |
|
---|
64 | void testBuffer(uint8_t* data, DWORD usage, DWORD mapFlags) {
|
---|
65 | Com<IDirect3DVertexBuffer9> buffer;
|
---|
66 | HRESULT status = m_device->CreateVertexBuffer(512, usage, 0, D3DPOOL_DEFAULT, &buffer, nullptr);
|
---|
67 |
|
---|
68 | if (FAILED(status))
|
---|
69 | throw DxvkError("Failed to create buffer");
|
---|
70 |
|
---|
71 | void* bufferMem = nullptr;
|
---|
72 | status = buffer->Lock(0, 0, &bufferMem, mapFlags);
|
---|
73 |
|
---|
74 | if (FAILED(status) || bufferMem == nullptr)
|
---|
75 | throw DxvkError("Failed to lock buffer");
|
---|
76 |
|
---|
77 | std::memcpy(bufferMem, data, 512);
|
---|
78 |
|
---|
79 | status = buffer->Unlock();
|
---|
80 |
|
---|
81 | if (FAILED(status))
|
---|
82 | throw DxvkError("Failed to unlock buffer");
|
---|
83 | }
|
---|
84 |
|
---|
85 | void run() {
|
---|
86 | this->adjustBackBuffer();
|
---|
87 |
|
---|
88 | m_device->BeginScene();
|
---|
89 |
|
---|
90 | m_device->Clear(
|
---|
91 | 0,
|
---|
92 | nullptr,
|
---|
93 | D3DCLEAR_TARGET,
|
---|
94 | D3DCOLOR_RGBA(255, 50, 139, 0),
|
---|
95 | 0.0f,
|
---|
96 | 0);
|
---|
97 |
|
---|
98 | m_device->EndScene();
|
---|
99 |
|
---|
100 | m_device->PresentEx(
|
---|
101 | nullptr,
|
---|
102 | nullptr,
|
---|
103 | nullptr,
|
---|
104 | nullptr,
|
---|
105 | 0);
|
---|
106 | }
|
---|
107 |
|
---|
108 | void adjustBackBuffer() {
|
---|
109 | RECT windowRect = { 0, 0, 1024, 600 };
|
---|
110 | GetClientRect(m_window, &windowRect);
|
---|
111 |
|
---|
112 | Extent2D newSize = {
|
---|
113 | static_cast<uint32_t>(windowRect.right - windowRect.left),
|
---|
114 | static_cast<uint32_t>(windowRect.bottom - windowRect.top),
|
---|
115 | };
|
---|
116 |
|
---|
117 | if (m_windowSize.w != newSize.w
|
---|
118 | || m_windowSize.h != newSize.h) {
|
---|
119 | m_windowSize = newSize;
|
---|
120 |
|
---|
121 | D3DPRESENT_PARAMETERS params;
|
---|
122 | getPresentParams(params);
|
---|
123 | HRESULT status = m_device->ResetEx(¶ms, nullptr);
|
---|
124 |
|
---|
125 | if (FAILED(status))
|
---|
126 | throw DxvkError("Device reset failed");
|
---|
127 | }
|
---|
128 | }
|
---|
129 |
|
---|
130 | void getPresentParams(D3DPRESENT_PARAMETERS& params) {
|
---|
131 | params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
---|
132 | params.BackBufferCount = 1;
|
---|
133 | params.BackBufferFormat = D3DFMT_X8R8G8B8;
|
---|
134 | params.BackBufferWidth = m_windowSize.w;
|
---|
135 | params.BackBufferHeight = m_windowSize.h;
|
---|
136 | params.EnableAutoDepthStencil = FALSE;
|
---|
137 | params.Flags = 0;
|
---|
138 | params.FullScreen_RefreshRateInHz = 0;
|
---|
139 | params.hDeviceWindow = m_window;
|
---|
140 | params.MultiSampleQuality = 0;
|
---|
141 | params.MultiSampleType = D3DMULTISAMPLE_NONE;
|
---|
142 | params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
---|
143 | params.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
---|
144 | params.Windowed = TRUE;
|
---|
145 | }
|
---|
146 |
|
---|
147 | private:
|
---|
148 |
|
---|
149 | HWND m_window;
|
---|
150 | Extent2D m_windowSize = { 1024, 600 };
|
---|
151 |
|
---|
152 | Com<IDirect3D9Ex> m_d3d;
|
---|
153 | Com<IDirect3DDevice9Ex> m_device;
|
---|
154 |
|
---|
155 | };
|
---|
156 |
|
---|
157 | LRESULT CALLBACK WindowProc(HWND hWnd,
|
---|
158 | UINT message,
|
---|
159 | WPARAM wParam,
|
---|
160 | LPARAM lParam);
|
---|
161 |
|
---|
162 | int WINAPI WinMain(HINSTANCE hInstance,
|
---|
163 | HINSTANCE hPrevInstance,
|
---|
164 | LPSTR lpCmdLine,
|
---|
165 | int nCmdShow) {
|
---|
166 | HWND hWnd;
|
---|
167 | WNDCLASSEXW wc;
|
---|
168 | ZeroMemory(&wc, sizeof(WNDCLASSEX));
|
---|
169 | wc.cbSize = sizeof(WNDCLASSEX);
|
---|
170 | wc.style = CS_HREDRAW | CS_VREDRAW;
|
---|
171 | wc.lpfnWndProc = WindowProc;
|
---|
172 | wc.hInstance = hInstance;
|
---|
173 | wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
---|
174 | wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
---|
175 | wc.lpszClassName = L"WindowClass1";
|
---|
176 | RegisterClassExW(&wc);
|
---|
177 |
|
---|
178 | hWnd = CreateWindowExW(0,
|
---|
179 | L"WindowClass1",
|
---|
180 | L"Our First Windowed Program",
|
---|
181 | WS_OVERLAPPEDWINDOW,
|
---|
182 | 300, 300,
|
---|
183 | 640, 480,
|
---|
184 | nullptr,
|
---|
185 | nullptr,
|
---|
186 | hInstance,
|
---|
187 | nullptr);
|
---|
188 | ShowWindow(hWnd, nCmdShow);
|
---|
189 |
|
---|
190 | MSG msg;
|
---|
191 |
|
---|
192 | try {
|
---|
193 | BufferApp app(hInstance, hWnd);
|
---|
194 |
|
---|
195 | while (true) {
|
---|
196 | if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
---|
197 | TranslateMessage(&msg);
|
---|
198 | DispatchMessage(&msg);
|
---|
199 |
|
---|
200 | if (msg.message == WM_QUIT)
|
---|
201 | return msg.wParam;
|
---|
202 | } else {
|
---|
203 | app.run();
|
---|
204 | }
|
---|
205 | }
|
---|
206 | } catch (const dxvk::DxvkError& e) {
|
---|
207 | std::cerr << e.message() << std::endl;
|
---|
208 | return msg.wParam;
|
---|
209 | }
|
---|
210 | }
|
---|
211 |
|
---|
212 | LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
---|
213 | switch (message) {
|
---|
214 | case WM_CLOSE:
|
---|
215 | PostQuitMessage(0);
|
---|
216 | return 0;
|
---|
217 | }
|
---|
218 |
|
---|
219 | return DefWindowProc(hWnd, message, wParam, lParam);
|
---|
220 | }
|
---|