VirtualBox

source: vbox/trunk/src/libs/dxvk-native-1.9.2a/tests/d3d9/test_d3d9_triangle.cpp@ 103150

Last change on this file since 103150 was 96497, checked in by vboxsync, 2 years ago

libs/dxvk-native-1.9.2a: export to OSE

  • Property svn:eol-style set to native
File size: 16.1 KB
Line 
1#include <cstring>
2
3#include <d3d9.h>
4#include <d3dcompiler.h>
5
6#include "../test_utils.h"
7
8using namespace dxvk;
9
10struct Extent2D {
11 uint32_t w, h;
12};
13
14const std::string g_vertexShaderCode = R"(
15
16struct VS_INPUT {
17 float3 Position : POSITION;
18};
19
20struct VS_OUTPUT {
21 float4 Position : POSITION;
22};
23
24VS_OUTPUT main( VS_INPUT IN ) {
25 VS_OUTPUT OUT;
26 OUT.Position = float4(IN.Position, 0.6f);
27
28 return OUT;
29}
30
31)";
32
33const std::string g_pixelShaderCode = R"(
34
35struct VS_OUTPUT {
36 float4 Position : POSITION;
37};
38
39struct PS_OUTPUT {
40 float4 Colour : COLOR;
41};
42
43sampler g_texDepth : register( s0 );
44
45PS_OUTPUT main( VS_OUTPUT IN ) {
46 PS_OUTPUT OUT;
47
48 OUT.Colour = tex2D(g_texDepth, float2(0, 0));
49 OUT.Colour = 1.0;
50
51 return OUT;
52}
53
54
55)";
56
57Logger Logger::s_instance("triangle.log");
58
59class TriangleApp {
60
61public:
62
63 TriangleApp(HINSTANCE instance, HWND window)
64 : m_window(window) {
65 HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d);
66
67 if (FAILED(status))
68 throw DxvkError("Failed to create D3D9 interface");
69
70 UINT adapter = D3DADAPTER_DEFAULT;
71
72 D3DADAPTER_IDENTIFIER9 adapterId;
73 m_d3d->GetAdapterIdentifier(adapter, 0, &adapterId);
74
75 Logger::info(str::format("Using adapter: ", adapterId.Description));
76
77 auto CheckSRGBFormat = [&](D3DFORMAT fmt, const char* name) {
78 HRESULT status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt);
79 Logger::warn(str::format("(linear) ", name, ": ", SUCCEEDED(status) ? "ok" : "nope"));
80
81 status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, fmt);
82 Logger::warn(str::format("(srgb) ", name, ": ", SUCCEEDED(status) ? "ok" : "nope"));
83 };
84
85 CheckSRGBFormat(D3DFMT_R5G6B5, "R5G6B5");
86 CheckSRGBFormat(D3DFMT_X1R5G5B5, "X1R5G5B5");
87 CheckSRGBFormat(D3DFMT_A1R5G5B5, "A1R5G5B5");
88 CheckSRGBFormat(D3DFMT_A4R4G4B4, "A4R4G4B4");
89 CheckSRGBFormat(D3DFMT_X4R4G4B4, "X4R4G4B4");
90 CheckSRGBFormat(D3DFMT_G16R16, "G16R16");
91 CheckSRGBFormat(D3DFMT_A2R10G10B10, "A2R10G10B10");
92 CheckSRGBFormat(D3DFMT_A16B16G16R16, "A16B16G16R16");
93
94 //
95
96 DWORD quality;
97 status = m_d3d->CheckDepthStencilMatch(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_D24S8);
98 status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8);
99 status = m_d3d->CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8);
100 status = m_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, FALSE, D3DMULTISAMPLE_NONE, &quality);
101 status = m_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_NONE, &quality);
102 status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE);
103 status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE);
104
105 // NULL
106 constexpr D3DFORMAT NullFormat = D3DFORMAT(MAKEFOURCC('N', 'U', 'L', 'L'));
107
108 status = m_d3d->CheckDepthStencilMatch(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, D3DFMT_D24S8);
109 status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, NullFormat);
110 status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, NullFormat);
111 status = m_d3d->CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat);
112 status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, false);
113 status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, true);
114 //
115
116 D3DPRESENT_PARAMETERS params;
117 getPresentParams(params);
118
119 status = m_d3d->CreateDeviceEx(
120 adapter,
121 D3DDEVTYPE_HAL,
122 m_window,
123 D3DCREATE_HARDWARE_VERTEXPROCESSING,
124 &params,
125 nullptr,
126 &m_device);
127
128 if (FAILED(status))
129 throw DxvkError("Failed to create D3D9 device");
130
131 // Funny Swapchain Refcounting
132 // "One of the things COM does really well, is lifecycle management"
133 // Implicit Swapchain
134 {
135 IDirect3DSurface9* pSurface1 = nullptr;
136 IDirect3DSurface9* pSurface2 = nullptr;
137 status = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface1);
138 D3DPRESENT_PARAMETERS newParams = params;
139 newParams.BackBufferWidth = 10;
140 newParams.BackBufferHeight = 10;
141 status = m_device->Reset(&newParams);
142 status = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface2);
143
144 IDirect3DSwapChain9* pSwapChain2 = nullptr;
145 IDirect3DSwapChain9* pSwapChain3 = nullptr;
146 status = pSurface1->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain2));
147 status = pSurface2->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain3));
148
149 printf("E_NOINTERFACE! for pSwapchain2");
150 status = m_device->Reset(&params);
151 }
152 // Additional swapchain
153 {
154 IDirect3DSwapChain9* pSwapChain2 = nullptr;
155 IDirect3DSwapChain9* pSwapChain3 = nullptr;
156 IDirect3DSwapChain9* pSwapChain4 = nullptr;
157 IDirect3DSurface9* pSurface = nullptr;
158 status = m_device->CreateAdditionalSwapChain(&params, &pSwapChain2);
159 status = pSwapChain2->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurface);
160 status = pSurface->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain3));
161 pSwapChain2->Release();
162 UINT count = pSwapChain2->Release();
163 printf("Count: %u - Should be 0 and swapchain dead!", count);
164 status = pSurface->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain4));
165 // E_NOINTERFACE !
166 printf("E_NOINTERFACE!");
167 }
168
169 m_device->AddRef();
170
171 Com<IDirect3DSurface9> backbuffer;
172 m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
173
174 m_device->AddRef();
175
176 Com<IDirect3DSwapChain9> swapchain;
177 m_device->GetSwapChain(0, &swapchain);
178
179 m_device->AddRef();
180
181 DWORD bias = 0xDEADBEEF;
182 status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias);
183 status = m_device->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G', 'E', 'T', '4'));
184 status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias);
185 status = m_device->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G', 'E', 'T', '1'));
186 status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias);
187
188 // Vertex Shader
189 {
190 Com<ID3DBlob> blob;
191
192 status = D3DCompile(
193 g_vertexShaderCode.data(),
194 g_vertexShaderCode.length(),
195 nullptr, nullptr, nullptr,
196 "main",
197 "vs_2_0",
198 0, 0, &blob,
199 nullptr);
200
201 if (FAILED(status))
202 throw DxvkError("Failed to compile vertex shader");
203
204 status = m_device->CreateVertexShader(reinterpret_cast<const DWORD*>(blob->GetBufferPointer()), &m_vs);
205
206 if (FAILED(status))
207 throw DxvkError("Failed to create vertex shader");
208 }
209
210 // Pixel Shader
211 {
212 Com<ID3DBlob> blob;
213
214 status = D3DCompile(
215 g_pixelShaderCode.data(),
216 g_pixelShaderCode.length(),
217 nullptr, nullptr, nullptr,
218 "main",
219 "ps_2_0",
220 0, 0, &blob,
221 nullptr);
222
223 if (FAILED(status))
224 throw DxvkError("Failed to compile pixel shader");
225
226 status = m_device->CreatePixelShader(reinterpret_cast<const DWORD*>(blob->GetBufferPointer()), &m_ps);
227
228 if (FAILED(status))
229 throw DxvkError("Failed to create pixel shader");
230 }
231
232 m_device->SetVertexShader(m_vs.ptr());
233 m_device->SetPixelShader(m_ps.ptr());
234
235 m_device->AddRef();
236
237 Com<IDirect3DSurface9> nullSurface;
238 status = m_device->CreateRenderTarget(64, 64, D3DFORMAT(MAKEFOURCC('N', 'U', 'L', 'L')), D3DMULTISAMPLE_NONE, 0, FALSE, &nullSurface, nullptr);
239
240 status = m_device->ColorFill(nullSurface.ptr(), nullptr, D3DCOLOR_RGBA(255, 0, 0, 255));
241
242 Com<IDirect3DTexture9> defaultTexture;
243 status = m_device->CreateTexture(64, 64, 1, 0, D3DFMT_DXT3, D3DPOOL_DEFAULT, &defaultTexture, nullptr);
244
245 m_device->AddRef();
246
247 Com<IDirect3DSurface9> surface;
248 status = defaultTexture->GetSurfaceLevel(0, &surface);
249
250 m_device->AddRef();
251
252 Com<IDirect3DTexture9> sysmemTexture;
253 status = m_device->CreateTexture(64, 64, 1, 0, D3DFMT_DXT3, D3DPOOL_SYSTEMMEM, &sysmemTexture, nullptr);
254
255 Com<IDirect3DSurface9> offscreenSurface;
256 status = m_device->CreateOffscreenPlainSurfaceEx(64, 64, D3DFMT_DXT3, D3DPOOL_DEFAULT, &offscreenSurface, nullptr, 0);
257
258 D3DLOCKED_RECT offscreenLock;
259 status = offscreenSurface->LockRect(&offscreenLock, nullptr, 0);
260
261 std::memset(offscreenLock.pBits, 0xFF, offscreenLock.Pitch * (64 / 4));
262
263 status = offscreenSurface->UnlockRect();
264
265 //status = m_device->ColorFill(offscreenSurface.ptr(), nullptr, D3DCOLOR_ARGB(255, 255, 0, 0));
266
267 D3DLOCKED_RECT sysmemLock;
268 status = sysmemTexture->LockRect(0, &sysmemLock, nullptr, 0);
269
270 //D3DLOCKED_RECT offscreenLock;
271 status = offscreenSurface->LockRect(&offscreenLock, nullptr, 0);
272
273 std::memcpy(sysmemLock.pBits, offscreenLock.pBits, offscreenLock.Pitch * (64 / 4));
274
275 sysmemTexture->UnlockRect(0);
276 offscreenSurface->UnlockRect();
277
278 status = m_device->UpdateTexture(sysmemTexture.ptr(), defaultTexture.ptr());
279
280 status = m_device->SetTexture(0, defaultTexture.ptr());
281
282 Com<IDirect3DSurface9> rt;
283 status = m_device->CreateRenderTarget(1280, 720, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, nullptr);
284
285 m_device->AddRef();
286
287 Com<IDirect3DSurface9> rt2;
288 status = m_device->CreateRenderTarget(1280, 720, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, nullptr);
289
290 m_device->AddRef();
291
292 rt2 = nullptr;
293
294 m_device->AddRef();
295
296 RECT stretchRect1 = { 0, 0, 640, 720 };
297 RECT stretchRect2 = { 640, 0, 1280, 720 };
298 status = m_device->StretchRect(rt.ptr(), &stretchRect1, rt.ptr(), &stretchRect2, D3DTEXF_LINEAR);
299
300 ///
301
302 Com<IDirect3DSurface9> ds;
303 //status = m_device->CreateDepthStencilSurface(1274, 695, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, FALSE, &ds, nullptr);
304 status = m_device->CreateDepthStencilSurface(1280, 720, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, FALSE, &ds, nullptr);
305
306 status = m_device->SetDepthStencilSurface(ds.ptr());
307 status = m_device->SetRenderState(D3DRS_ZWRITEENABLE, 1);
308 status = m_device->SetRenderState(D3DRS_ZENABLE, 1);
309 status = m_device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
310
311
312
313 std::array<float, 9> vertices = {
314 0.0f, 0.5f, 0.0f,
315 0.5f, -0.5f, 0.0f,
316 -0.5f, -0.5f, 0.0f,
317 };
318
319 const size_t vbSize = vertices.size() * sizeof(float);
320
321 status = m_device->CreateVertexBuffer(vbSize, 0, 0, D3DPOOL_DEFAULT, &m_vb, nullptr);
322 if (FAILED(status))
323 throw DxvkError("Failed to create vertex buffer");
324
325 void* data = nullptr;
326 status = m_vb->Lock(0, 0, &data, 0);
327 if (FAILED(status))
328 throw DxvkError("Failed to lock vertex buffer");
329
330 std::memcpy(data, vertices.data(), vbSize);
331
332 status = m_vb->Unlock();
333 if (FAILED(status))
334 throw DxvkError("Failed to unlock vertex buffer");
335
336 m_device->SetStreamSource(0, m_vb.ptr(), 0, 3 * sizeof(float));
337
338 std::array<D3DVERTEXELEMENT9, 2> elements;
339
340 elements[0].Method = 0;
341 elements[0].Offset = 0;
342 elements[0].Stream = 0;
343 elements[0].Type = D3DDECLTYPE_FLOAT3;
344 elements[0].Usage = D3DDECLUSAGE_POSITION;
345 elements[0].UsageIndex = 0;
346
347 elements[1] = D3DDECL_END();
348
349 HRESULT result = m_device->CreateVertexDeclaration(elements.data(), &m_decl);
350 if (FAILED(result))
351 throw DxvkError("Failed to create vertex decl");
352
353 m_device->SetVertexDeclaration(m_decl.ptr());
354
355 ///
356
357 Com<IDirect3DTexture9> myRT;
358 status = m_device->CreateTexture(512, 256, 1, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &myRT, nullptr);
359
360 Com<IDirect3DSurface9> myRTSurf;
361 myRT->GetSurfaceLevel(0, &myRTSurf);
362
363 Com<IDirect3DTexture9> myCopyThing;
364 status = m_device->CreateTexture(512, 256, 1, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &myCopyThing, nullptr);
365
366 Com<IDirect3DSurface9> myCopyThingSurf;
367 myCopyThing->GetSurfaceLevel(0, &myCopyThingSurf);
368
369 status = m_device->StretchRect(myRTSurf.ptr(), nullptr, myCopyThingSurf.ptr(), nullptr, D3DTEXF_NONE);
370
371 D3DLOCKED_RECT rect;
372 status = myCopyThing->LockRect(0, &rect, nullptr, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK);
373
374 m_device->SetRenderState(D3DRS_ALPHAREF, 256 + 255);
375 m_device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_LESSEQUAL);
376 m_device->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
377 }
378
379 void run() {
380 this->adjustBackBuffer();
381
382 m_device->BeginScene();
383
384 m_device->Clear(
385 0,
386 nullptr,
387 D3DCLEAR_TARGET,
388 D3DCOLOR_RGBA(44, 62, 80, 0),
389 0,
390 0);
391
392 m_device->Clear(
393 0,
394 nullptr,
395 D3DCLEAR_ZBUFFER,
396 0,
397 0.5f,
398 0);
399
400 m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
401
402 m_device->EndScene();
403
404 m_device->PresentEx(
405 nullptr,
406 nullptr,
407 nullptr,
408 nullptr,
409 0);
410 }
411
412 void adjustBackBuffer() {
413 RECT windowRect = { 0, 0, 1024, 600 };
414 GetClientRect(m_window, &windowRect);
415
416 Extent2D newSize = {
417 static_cast<uint32_t>(windowRect.right - windowRect.left),
418 static_cast<uint32_t>(windowRect.bottom - windowRect.top),
419 };
420
421 if (m_windowSize.w != newSize.w
422 || m_windowSize.h != newSize.h) {
423 m_windowSize = newSize;
424
425 D3DPRESENT_PARAMETERS params;
426 getPresentParams(params);
427 HRESULT status = m_device->ResetEx(&params, nullptr);
428
429 if (FAILED(status))
430 throw DxvkError("Device reset failed");
431 }
432 }
433
434 void getPresentParams(D3DPRESENT_PARAMETERS& params) {
435 params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
436 params.BackBufferCount = 1;
437 params.BackBufferFormat = D3DFMT_X8R8G8B8;
438 params.BackBufferWidth = m_windowSize.w;
439 params.BackBufferHeight = m_windowSize.h;
440 params.EnableAutoDepthStencil = 0;
441 params.Flags = 0;
442 params.FullScreen_RefreshRateInHz = 0;
443 params.hDeviceWindow = m_window;
444 params.MultiSampleQuality = 0;
445 params.MultiSampleType = D3DMULTISAMPLE_NONE;
446 params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
447 params.SwapEffect = D3DSWAPEFFECT_DISCARD;
448 params.Windowed = TRUE;
449 }
450
451private:
452
453 HWND m_window;
454 Extent2D m_windowSize = { 1024, 600 };
455
456 Com<IDirect3D9Ex> m_d3d;
457 Com<IDirect3DDevice9Ex> m_device;
458
459 Com<IDirect3DVertexShader9> m_vs;
460 Com<IDirect3DPixelShader9> m_ps;
461 Com<IDirect3DVertexBuffer9> m_vb;
462 Com<IDirect3DVertexDeclaration9> m_decl;
463
464};
465
466LRESULT CALLBACK WindowProc(HWND hWnd,
467 UINT message,
468 WPARAM wParam,
469 LPARAM lParam);
470
471int WINAPI WinMain(HINSTANCE hInstance,
472 HINSTANCE hPrevInstance,
473 LPSTR lpCmdLine,
474 int nCmdShow) {
475 HWND hWnd;
476 WNDCLASSEXW wc;
477 ZeroMemory(&wc, sizeof(WNDCLASSEX));
478 wc.cbSize = sizeof(WNDCLASSEX);
479 wc.style = CS_HREDRAW | CS_VREDRAW;
480 wc.lpfnWndProc = WindowProc;
481 wc.hInstance = hInstance;
482 wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
483 wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
484 wc.lpszClassName = L"WindowClass1";
485 RegisterClassExW(&wc);
486
487 hWnd = CreateWindowExW(0,
488 L"WindowClass1",
489 L"Our First Windowed Program",
490 WS_OVERLAPPEDWINDOW,
491 300, 300,
492 640, 480,
493 nullptr,
494 nullptr,
495 hInstance,
496 nullptr);
497 ShowWindow(hWnd, nCmdShow);
498
499 MSG msg;
500
501 try {
502 TriangleApp app(hInstance, hWnd);
503
504 while (true) {
505 if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
506 TranslateMessage(&msg);
507 DispatchMessage(&msg);
508
509 if (msg.message == WM_QUIT)
510 return msg.wParam;
511 } else {
512 app.run();
513 }
514 }
515 } catch (const dxvk::DxvkError& e) {
516 std::cerr << e.message() << std::endl;
517 return msg.wParam;
518 }
519}
520
521LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
522 switch (message) {
523 case WM_CLOSE:
524 PostQuitMessage(0);
525 return 0;
526 }
527
528 return DefWindowProc(hWnd, message, wParam, lParam);
529}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette