gdi32: Implement nulldrv_StretchDIBits using the PutImage gdi driver function.
[wine] / dlls / d3d10core / tests / device.c
1 /*
2  * Copyright 2008 Henri Verbeet for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #define COBJMACROS
20 #include "initguid.h"
21 #include "d3d10.h"
22 #include "wine/test.h"
23
24 HRESULT WINAPI D3D10CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapter,
25         UINT flags, void *unknown0, ID3D10Device **device);
26
27 static ID3D10Device *create_device(void)
28 {
29     IDXGIFactory *factory = NULL;
30     IDXGIAdapter *adapter = NULL;
31     ID3D10Device *device = NULL;
32     HRESULT hr;
33
34     hr = CreateDXGIFactory(&IID_IDXGIFactory, (void *)&factory);
35     if (FAILED(hr)) goto cleanup;
36
37     hr = IDXGIFactory_EnumAdapters(factory, 0, &adapter);
38     ok(SUCCEEDED(hr) || hr == DXGI_ERROR_NOT_FOUND, /* Some VMware and VirtualBox */
39             "EnumAdapters failed, hr %#x.\n", hr);
40     if (SUCCEEDED(hr))
41     {
42         hr = D3D10CoreCreateDevice(factory, adapter, 0, NULL, &device);
43     }
44
45     if (FAILED(hr))
46     {
47         HMODULE d3d10ref;
48
49         trace("Failed to create a HW device, trying REF\n");
50         if (adapter) IDXGIAdapter_Release(adapter);
51         adapter = NULL;
52
53         d3d10ref = LoadLibraryA("d3d10ref.dll");
54         if (!d3d10ref)
55         {
56             trace("d3d10ref.dll not available, unable to create a REF device\n");
57             goto cleanup;
58         }
59
60         hr = IDXGIFactory_CreateSoftwareAdapter(factory, d3d10ref, &adapter);
61         FreeLibrary(d3d10ref);
62         ok(SUCCEEDED(hr), "CreateSoftwareAdapter failed, hr %#x\n", hr);
63         if (FAILED(hr)) goto cleanup;
64
65         hr = D3D10CoreCreateDevice(factory, adapter, 0, NULL, &device);
66         ok(SUCCEEDED(hr), "Failed to create a REF device, hr %#x\n", hr);
67         if (FAILED(hr)) goto cleanup;
68     }
69
70 cleanup:
71     if (adapter) IDXGIAdapter_Release(adapter);
72     if (factory) IDXGIFactory_Release(factory);
73
74     return device;
75 }
76
77 static void test_device_interfaces(ID3D10Device *device)
78 {
79     IUnknown *obj;
80     HRESULT hr;
81
82     if (SUCCEEDED(hr = ID3D10Device_QueryInterface(device, &IID_IUnknown, (void **)&obj)))
83         IUnknown_Release(obj);
84     ok(SUCCEEDED(hr), "ID3D10Device does not implement IUnknown\n");
85
86     if (SUCCEEDED(hr = ID3D10Device_QueryInterface(device, &IID_IDXGIObject, (void **)&obj)))
87         IUnknown_Release(obj);
88     ok(SUCCEEDED(hr), "ID3D10Device does not implement IDXGIObject\n");
89
90     if (SUCCEEDED(hr = ID3D10Device_QueryInterface(device, &IID_IDXGIDevice, (void **)&obj)))
91         IUnknown_Release(obj);
92     ok(SUCCEEDED(hr), "ID3D10Device does not implement IDXGIDevice\n");
93
94     if (SUCCEEDED(hr = ID3D10Device_QueryInterface(device, &IID_ID3D10Device, (void **)&obj)))
95         IUnknown_Release(obj);
96     ok(SUCCEEDED(hr), "ID3D10Device does not implement ID3D10Device\n");
97 }
98
99 static void test_create_texture2d(ID3D10Device *device)
100 {
101     D3D10_TEXTURE2D_DESC desc;
102     ID3D10Texture2D *texture;
103     IDXGISurface *surface;
104     HRESULT hr;
105
106     desc.Width = 512;
107     desc.Height = 512;
108     desc.MipLevels = 1;
109     desc.ArraySize = 1;
110     desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
111     desc.SampleDesc.Count = 1;
112     desc.SampleDesc.Quality = 0;
113     desc.Usage = D3D10_USAGE_DEFAULT;
114     desc.BindFlags = D3D10_BIND_RENDER_TARGET;
115     desc.CPUAccessFlags = 0;
116     desc.MiscFlags = 0;
117
118     hr = ID3D10Device_CreateTexture2D(device, &desc, NULL, &texture);
119     ok(SUCCEEDED(hr), "Failed to create a 2d texture, hr %#x\n", hr);
120
121     hr = ID3D10Texture2D_QueryInterface(texture, &IID_IDXGISurface, (void **)&surface);
122     ok(SUCCEEDED(hr), "Texture should implement IDXGISurface\n");
123     if (SUCCEEDED(hr)) IDXGISurface_Release(surface);
124     ID3D10Texture2D_Release(texture);
125
126     desc.MipLevels = 0;
127     hr = ID3D10Device_CreateTexture2D(device, &desc, NULL, &texture);
128     ok(SUCCEEDED(hr), "Failed to create a 2d texture, hr %#x\n", hr);
129
130     hr = ID3D10Texture2D_QueryInterface(texture, &IID_IDXGISurface, (void **)&surface);
131     ok(FAILED(hr), "Texture should not implement IDXGISurface\n");
132     if (SUCCEEDED(hr)) IDXGISurface_Release(surface);
133     ID3D10Texture2D_Release(texture);
134
135     desc.MipLevels = 1;
136     desc.ArraySize = 2;
137     hr = ID3D10Device_CreateTexture2D(device, &desc, NULL, &texture);
138     ok(SUCCEEDED(hr), "Failed to create a 2d texture, hr %#x\n", hr);
139
140     hr = ID3D10Texture2D_QueryInterface(texture, &IID_IDXGISurface, (void **)&surface);
141     ok(FAILED(hr), "Texture should not implement IDXGISurface\n");
142     if (SUCCEEDED(hr)) IDXGISurface_Release(surface);
143     ID3D10Texture2D_Release(texture);
144 }
145
146 static void test_create_texture3d(ID3D10Device *device)
147 {
148     D3D10_TEXTURE3D_DESC desc;
149     ID3D10Texture3D *texture;
150     IDXGISurface *surface;
151     HRESULT hr;
152
153     desc.Width = 64;
154     desc.Height = 64;
155     desc.Depth = 64;
156     desc.MipLevels = 1;
157     desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
158     desc.Usage = D3D10_USAGE_DEFAULT;
159     desc.BindFlags = D3D10_BIND_RENDER_TARGET;
160     desc.CPUAccessFlags = 0;
161     desc.MiscFlags = 0;
162
163     hr = ID3D10Device_CreateTexture3D(device, &desc, NULL, &texture);
164     ok(SUCCEEDED(hr), "Failed to create a 3d texture, hr %#x.\n", hr);
165
166     hr = ID3D10Texture3D_QueryInterface(texture, &IID_IDXGISurface, (void **)&surface);
167     ok(FAILED(hr), "Texture should not implement IDXGISurface.\n");
168     if (SUCCEEDED(hr)) IDXGISurface_Release(surface);
169     ID3D10Texture3D_Release(texture);
170
171     desc.MipLevels = 0;
172     hr = ID3D10Device_CreateTexture3D(device, &desc, NULL, &texture);
173     ok(SUCCEEDED(hr), "Failed to create a 3d texture, hr %#x.\n", hr);
174
175     hr = ID3D10Texture3D_QueryInterface(texture, &IID_IDXGISurface, (void **)&surface);
176     ok(FAILED(hr), "Texture should not implement IDXGISurface.\n");
177     if (SUCCEEDED(hr)) IDXGISurface_Release(surface);
178     ID3D10Texture3D_Release(texture);
179 }
180
181 static void test_create_rendertarget_view(ID3D10Device *device)
182 {
183     D3D10_RENDER_TARGET_VIEW_DESC rtv_desc;
184     D3D10_TEXTURE2D_DESC texture_desc;
185     D3D10_BUFFER_DESC buffer_desc;
186     ID3D10RenderTargetView *rtview;
187     ID3D10Texture2D *texture;
188     ID3D10Buffer *buffer;
189     HRESULT hr;
190
191     buffer_desc.ByteWidth = 1024;
192     buffer_desc.Usage = D3D10_USAGE_DEFAULT;
193     buffer_desc.BindFlags = D3D10_BIND_RENDER_TARGET;
194     buffer_desc.CPUAccessFlags = 0;
195     buffer_desc.MiscFlags = 0;
196
197     hr = ID3D10Device_CreateBuffer(device, &buffer_desc, NULL, &buffer);
198     ok(SUCCEEDED(hr), "Failed to create a buffer, hr %#x\n", hr);
199
200     rtv_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
201     rtv_desc.ViewDimension = D3D10_RTV_DIMENSION_BUFFER;
202     U(rtv_desc).Buffer.ElementOffset = 0;
203     U(rtv_desc).Buffer.ElementWidth = 64;
204
205     hr = ID3D10Device_CreateRenderTargetView(device, (ID3D10Resource *)buffer, &rtv_desc, &rtview);
206     ok(SUCCEEDED(hr), "Failed to create a rendertarget view, hr %#x\n", hr);
207
208     ID3D10RenderTargetView_Release(rtview);
209     ID3D10Buffer_Release(buffer);
210
211     texture_desc.Width = 512;
212     texture_desc.Height = 512;
213     texture_desc.MipLevels = 1;
214     texture_desc.ArraySize = 1;
215     texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
216     texture_desc.SampleDesc.Count = 1;
217     texture_desc.SampleDesc.Quality = 0;
218     texture_desc.Usage = D3D10_USAGE_DEFAULT;
219     texture_desc.BindFlags = D3D10_BIND_RENDER_TARGET;
220     texture_desc.CPUAccessFlags = 0;
221     texture_desc.MiscFlags = 0;
222
223     hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, &texture);
224     ok(SUCCEEDED(hr), "Failed to create a 2d texture, hr %#x\n", hr);
225
226     /* For texture resources it's allowed to specify NULL as desc */
227     hr = ID3D10Device_CreateRenderTargetView(device, (ID3D10Resource *)texture, NULL, &rtview);
228     ok(SUCCEEDED(hr), "Failed to create a rendertarget view, hr %#x\n", hr);
229
230     ID3D10RenderTargetView_GetDesc(rtview, &rtv_desc);
231     ok(rtv_desc.Format == texture_desc.Format, "Expected format %#x, got %#x\n", texture_desc.Format, rtv_desc.Format);
232     ok(rtv_desc.ViewDimension == D3D10_RTV_DIMENSION_TEXTURE2D,
233             "Expected view dimension D3D10_RTV_DIMENSION_TEXTURE2D, got %#x\n", rtv_desc.ViewDimension);
234     ok(U(rtv_desc).Texture2D.MipSlice == 0, "Expected mip slice 0, got %#x\n", U(rtv_desc).Texture2D.MipSlice);
235
236     ID3D10RenderTargetView_Release(rtview);
237     ID3D10Texture2D_Release(texture);
238 }
239
240 static void test_create_shader(ID3D10Device *device)
241 {
242 #if 0
243 float4 light;
244 float4x4 mat;
245
246 struct input
247 {
248     float4 position : POSITION;
249     float3 normal : NORMAL;
250 };
251
252 struct output
253 {
254     float4 position : POSITION;
255     float4 diffuse : COLOR;
256 };
257
258 output main(const input v)
259 {
260     output o;
261
262     o.position = mul(v.position, mat);
263     o.diffuse = dot((float3)light, v.normal);
264
265     return o;
266 }
267 #endif
268     static const DWORD vs_4_0[] =
269     {
270         0x43425844, 0x3ae813ca, 0x0f034b91, 0x790f3226, 0x6b4a718a, 0x00000001, 0x000001c0,
271         0x00000003, 0x0000002c, 0x0000007c, 0x000000cc, 0x4e475349, 0x00000048, 0x00000002,
272         0x00000008, 0x00000038, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f,
273         0x00000041, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000707, 0x49534f50,
274         0x4e4f4954, 0x524f4e00, 0x004c414d, 0x4e47534f, 0x00000048, 0x00000002, 0x00000008,
275         0x00000038, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x00000041,
276         0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x49534f50, 0x4e4f4954,
277         0x4c4f4300, 0xab00524f, 0x52444853, 0x000000ec, 0x00010040, 0x0000003b, 0x04000059,
278         0x00208e46, 0x00000000, 0x00000005, 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f,
279         0x00101072, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x03000065, 0x001020f2,
280         0x00000001, 0x08000011, 0x00102012, 0x00000000, 0x00101e46, 0x00000000, 0x00208e46,
281         0x00000000, 0x00000001, 0x08000011, 0x00102022, 0x00000000, 0x00101e46, 0x00000000,
282         0x00208e46, 0x00000000, 0x00000002, 0x08000011, 0x00102042, 0x00000000, 0x00101e46,
283         0x00000000, 0x00208e46, 0x00000000, 0x00000003, 0x08000011, 0x00102082, 0x00000000,
284         0x00101e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x08000010, 0x001020f2,
285         0x00000001, 0x00208246, 0x00000000, 0x00000000, 0x00101246, 0x00000001, 0x0100003e,
286     };
287
288     static const DWORD vs_2_0[] =
289     {
290         0xfffe0200, 0x002bfffe, 0x42415443, 0x0000001c, 0x00000077, 0xfffe0200, 0x00000002,
291         0x0000001c, 0x00000100, 0x00000070, 0x00000044, 0x00040002, 0x00000001, 0x0000004c,
292         0x00000000, 0x0000005c, 0x00000002, 0x00000004, 0x00000060, 0x00000000, 0x6867696c,
293         0xabab0074, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x0074616d, 0x00030003,
294         0x00040004, 0x00000001, 0x00000000, 0x325f7376, 0x4d00305f, 0x6f726369, 0x74666f73,
295         0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072,
296         0x392e3932, 0x332e3235, 0x00313131, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f,
297         0x80000003, 0x900f0001, 0x03000009, 0xc0010000, 0x90e40000, 0xa0e40000, 0x03000009,
298         0xc0020000, 0x90e40000, 0xa0e40001, 0x03000009, 0xc0040000, 0x90e40000, 0xa0e40002,
299         0x03000009, 0xc0080000, 0x90e40000, 0xa0e40003, 0x03000008, 0xd00f0000, 0xa0e40004,
300         0x90e40001, 0x0000ffff,
301     };
302
303     static const DWORD vs_3_0[] =
304     {
305         0xfffe0300, 0x002bfffe, 0x42415443, 0x0000001c, 0x00000077, 0xfffe0300, 0x00000002,
306         0x0000001c, 0x00000100, 0x00000070, 0x00000044, 0x00040002, 0x00000001, 0x0000004c,
307         0x00000000, 0x0000005c, 0x00000002, 0x00000004, 0x00000060, 0x00000000, 0x6867696c,
308         0xabab0074, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x0074616d, 0x00030003,
309         0x00040004, 0x00000001, 0x00000000, 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73,
310         0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072,
311         0x392e3932, 0x332e3235, 0x00313131, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f,
312         0x80000003, 0x900f0001, 0x0200001f, 0x80000000, 0xe00f0000, 0x0200001f, 0x8000000a,
313         0xe00f0001, 0x03000009, 0xe0010000, 0x90e40000, 0xa0e40000, 0x03000009, 0xe0020000,
314         0x90e40000, 0xa0e40001, 0x03000009, 0xe0040000, 0x90e40000, 0xa0e40002, 0x03000009,
315         0xe0080000, 0x90e40000, 0xa0e40003, 0x03000008, 0xe00f0001, 0xa0e40004, 0x90e40001,
316         0x0000ffff,
317     };
318
319 #if 0
320 float4 main(const float4 color : COLOR) : SV_TARGET
321 {
322     float4 o;
323
324     o = color;
325
326     return o;
327 }
328 #endif
329     static const DWORD ps_4_0[] =
330     {
331         0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac,
332         0x00000005, 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452,
333         0x00000050, 0x00000000, 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100,
334         0x0000001c, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168,
335         0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00,
336         0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
337         0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f, 0x0000002c,
338         0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
339         0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040,
340         0x0000000e, 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000,
341         0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453,
342         0x00000074, 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000,
343         0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
344         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
345         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
346         0x00000000, 0x00000000,
347     };
348
349     ID3D10VertexShader *vs = NULL;
350     ID3D10PixelShader *ps = NULL;
351     HRESULT hr;
352
353     hr = ID3D10Device_CreateVertexShader(device, vs_4_0, sizeof(vs_4_0), &vs);
354     ok(SUCCEEDED(hr), "Failed to create SM4 vertex shader, hr %#x\n", hr);
355     if (vs)
356         ID3D10VertexShader_Release(vs);
357
358     hr = ID3D10Device_CreateVertexShader(device, vs_2_0, sizeof(vs_2_0), &vs);
359     ok(hr == E_INVALIDARG, "Created a SM2 vertex shader, hr %#x\n", hr);
360
361     hr = ID3D10Device_CreateVertexShader(device, vs_3_0, sizeof(vs_3_0), &vs);
362     ok(hr == E_INVALIDARG, "Created a SM3 vertex shader, hr %#x\n", hr);
363
364     hr = ID3D10Device_CreateVertexShader(device, ps_4_0, sizeof(ps_4_0), &vs);
365     ok(hr == E_INVALIDARG, "Created a SM4 vertex shader from a pixel shader source, hr %#x\n", hr);
366
367     hr = ID3D10Device_CreatePixelShader(device, ps_4_0, sizeof(ps_4_0), &ps);
368     ok(SUCCEEDED(hr), "Failed to create SM4 vertex shader, hr %#x\n", hr);
369     if (ps)
370         ID3D10VertexShader_Release(ps);
371 }
372
373 START_TEST(device)
374 {
375     ID3D10Device *device;
376     ULONG refcount;
377
378     device = create_device();
379     if (!device)
380     {
381         skip("Failed to create device, skipping tests\n");
382         return;
383     }
384
385     test_device_interfaces(device);
386     test_create_texture2d(device);
387     test_create_texture3d(device);
388     test_create_rendertarget_view(device);
389     test_create_shader(device);
390
391     refcount = ID3D10Device_Release(device);
392     ok(!refcount, "Device has %u references left\n", refcount);
393 }