1/* 2 * Copyright © Microsoft Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24#include <gtest/gtest.h> 25 26#include <windows.h> 27#include <GL/gl.h> 28 29#undef GetMessage 30 31class window 32{ 33public: 34 window(UINT width = 64, UINT height = 64); 35 ~window(); 36 37 HWND get_hwnd() const { return _window; }; 38 HDC get_hdc() const { return _hdc; }; 39 bool valid() const { return _window && _hdc && _hglrc; } 40 void show() { 41 ShowWindow(_window, SW_SHOW); 42 } 43 44private: 45 HWND _window = nullptr; 46 HDC _hdc = nullptr; 47 HGLRC _hglrc = nullptr; 48}; 49 50window::window(uint32_t width, uint32_t height) 51{ 52 _window = CreateWindowW( 53 L"STATIC", 54 L"OpenGLTestWindow", 55 WS_OVERLAPPEDWINDOW, 56 0, 57 0, 58 width, 59 height, 60 NULL, 61 NULL, 62 NULL, 63 NULL 64 ); 65 66 if (_window == nullptr) 67 return; 68 69 _hdc = ::GetDC(_window); 70 71 PIXELFORMATDESCRIPTOR pfd = { 72 sizeof(PIXELFORMATDESCRIPTOR), /* size */ 73 1, /* version */ 74 PFD_SUPPORT_OPENGL | 75 PFD_DRAW_TO_WINDOW | 76 PFD_DOUBLEBUFFER, /* support double-buffering */ 77 PFD_TYPE_RGBA, /* color type */ 78 8, /* prefered color depth */ 79 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ 80 0, /* no alpha buffer */ 81 0, /* alpha bits (ignored) */ 82 0, /* no accumulation buffer */ 83 0, 0, 0, 0, /* accum bits (ignored) */ 84 32, /* depth buffer */ 85 0, /* no stencil buffer */ 86 0, /* no auxiliary buffers */ 87 PFD_MAIN_PLANE, /* main layer */ 88 0, /* reserved */ 89 0, 0, 0, /* no layer, visible, damage masks */ 90 }; 91 int pixel_format = ChoosePixelFormat(_hdc, &pfd); 92 if (pixel_format == 0) 93 return; 94 if (!SetPixelFormat(_hdc, pixel_format, &pfd)) 95 return; 96 97 _hglrc = wglCreateContext(_hdc); 98 if (!_hglrc) 99 return; 100 101 wglMakeCurrent(_hdc, _hglrc); 102} 103 104window::~window() 105{ 106 if (_hglrc) { 107 wglMakeCurrent(NULL, NULL); 108 wglDeleteContext(_hglrc); 109 } 110 if (_hdc) 111 ReleaseDC(_window, _hdc); 112 if (_window) 113 DestroyWindow(_window); 114} 115 116TEST(wgl, basic_create) 117{ 118 window wnd; 119 ASSERT_TRUE(wnd.valid()); 120 121 const char *version = (const char *)glGetString(GL_VERSION); 122 ASSERT_NE(strstr(version, "Mesa"), nullptr); 123} 124 125#ifdef GALLIUM_D3D12 126/* Fixture for tests for the d3d12 backend. Will be skipped if 127 * the environment isn't set up to run them. 128 */ 129#include <directx/d3d12.h> 130#include <wrl/client.h> 131#include <memory> 132using Microsoft::WRL::ComPtr; 133 134class d3d12 : public ::testing::Test 135{ 136 void SetUp() override; 137}; 138 139void d3d12::SetUp() 140{ 141 window wnd; 142 ASSERT_TRUE(wnd.valid()); 143 144 const char *renderer = (const char *)glGetString(GL_RENDERER); 145 if (!strstr(renderer, "D3D12")) 146 GTEST_SKIP(); 147} 148 149static bool 150info_queue_has_swapchain(ID3D12DebugDevice *debug_device, ID3D12InfoQueue *info_queue) 151{ 152 info_queue->PushEmptyStorageFilter(); 153 154 debug_device->ReportLiveDeviceObjects(D3D12_RLDO_DETAIL); 155 156 uint32_t num_messages = info_queue->GetNumStoredMessages(); 157 for (uint32_t i = 0; i < num_messages; ++i) { 158 SIZE_T message_size = 0; 159 info_queue->GetMessage(i, nullptr, &message_size); 160 EXPECT_GT(message_size, 0); 161 162 std::unique_ptr<byte[]> message_bytes(new byte[message_size]); 163 D3D12_MESSAGE *message = (D3D12_MESSAGE *)message_bytes.get(); 164 info_queue->GetMessage(i, message, &message_size); 165 166 if (strstr(message->pDescription, "SwapChain")) { 167 info_queue->ClearStoredMessages(); 168 info_queue->PopStorageFilter(); 169 return true; 170 } 171 } 172 info_queue->ClearStoredMessages(); 173 info_queue->PopStorageFilter(); 174 return false; 175} 176 177TEST_F(d3d12, swapchain_cleanup) 178{ 179 ComPtr<ID3D12InfoQueue> info_queue; 180 ComPtr<ID3D12DebugDevice> debug_device; 181 if (FAILED(D3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&info_queue))) || 182 FAILED(info_queue.As(&debug_device))) 183 GTEST_SKIP(); 184 185 ASSERT_FALSE(info_queue_has_swapchain(debug_device.Get(), info_queue.Get())); 186 187 { 188 window wnd; 189 wnd.show(); 190 glClearColor(1.0f, 0.0f, 0.0f, 1.0f); 191 glClear(GL_COLOR_BUFFER_BIT); 192 SwapBuffers(wnd.get_hdc()); 193 194 ASSERT_TRUE(info_queue_has_swapchain(debug_device.Get(), info_queue.Get())); 195 } 196 197 ASSERT_FALSE(info_queue_has_swapchain(debug_device.Get(), info_queue.Get())); 198} 199#endif 200