ntdll: Simplify the platform-specific dispatcher interface.
[wine.git] / dlls / d3drm / tests / d3drm.c
blobf1d48639c14a08d1836d72a4ad8543226eb3473a
1 /*
2 * Copyright 2010, 2012 Christian Costa
3 * Copyright 2012 André Hentschel
4 * Copyright 2011-2014 Henri Verbeet for CodeWeavers
5 * Copyright 2014-2015 Aaryaman Vasishta
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <limits.h>
24 #define COBJMACROS
25 #define _USE_MATH_DEFINES
26 #include <d3d.h>
27 #include <initguid.h>
28 #include <d3drm.h>
29 #include <d3drmwin.h>
30 #include <math.h>
32 #include "wine/test.h"
34 #define CHECK_REFCOUNT(obj,rc) \
35 { \
36 int rc_new = rc; \
37 int count = get_refcount( (IUnknown *)obj ); \
38 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
41 static ULONG get_refcount(IUnknown *object)
43 IUnknown_AddRef( object );
44 return IUnknown_Release( object );
47 static BOOL compare_float(float f, float g, unsigned int ulps)
49 int x = *(int *)&f;
50 int y = *(int *)&g;
52 if (x < 0)
53 x = INT_MIN - x;
54 if (y < 0)
55 y = INT_MIN - y;
57 if (abs(x - y) > ulps)
58 return FALSE;
60 return TRUE;
63 #define expect_matrix(m, m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44, u) \
64 expect_matrix_(__LINE__, m, m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44, u)
65 static void expect_matrix_(unsigned int line, D3DRMMATRIX4D m,
66 float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24,
67 float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44,
68 unsigned int ulps)
70 BOOL equal = compare_float(m[0][0], m11, ulps) && compare_float(m[0][1], m12, ulps)
71 && compare_float(m[0][2], m13, ulps) && compare_float(m[0][3], m14, ulps)
72 && compare_float(m[1][0], m21, ulps) && compare_float(m[1][1], m22, ulps)
73 && compare_float(m[1][2], m23, ulps) && compare_float(m[1][3], m24, ulps)
74 && compare_float(m[2][0], m31, ulps) && compare_float(m[2][1], m32, ulps)
75 && compare_float(m[2][2], m33, ulps) && compare_float(m[2][3], m34, ulps)
76 && compare_float(m[3][0], m41, ulps) && compare_float(m[3][1], m42, ulps)
77 && compare_float(m[3][2], m43, ulps) && compare_float(m[3][3], m44, ulps);
79 ok_(__FILE__, line)(equal,
80 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, "
81 "%.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e}, "
82 "expected {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, "
83 "%.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
84 m[0][0], m[0][1], m[0][2], m[0][3], m[1][0], m[1][1], m[1][2], m[1][3],
85 m[2][0], m[2][1], m[2][2], m[2][3], m[3][0], m[3][1], m[3][2], m[3][3],
86 m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
89 #define expect_vector(v, x, y, z, u) expect_vector_(__LINE__, v, x, y, z, u)
90 static void expect_vector_(unsigned int line, const D3DVECTOR *v, float x, float y, float z, unsigned int ulps)
92 BOOL equal = compare_float(U1(*v).x, x, ulps)
93 && compare_float(U2(*v).y, y, ulps)
94 && compare_float(U3(*v).z, z, ulps);
96 ok_(__FILE__, line)(equal, "Got unexpected vector {%.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e}.\n",
97 U1(*v).x, U2(*v).y, U3(*v).z, x, y, z);
100 #define vector_eq(a, b) vector_eq_(__LINE__, a, b)
101 static void vector_eq_(unsigned int line, const D3DVECTOR *left, const D3DVECTOR *right)
103 expect_vector_(line, left, U1(*right).x, U2(*right).y, U3(*right).z, 0);
106 static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
108 unsigned int diff = x > y ? x - y : y - x;
110 return diff <= max_diff;
113 static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
115 return compare_uint(c1 & 0xff, c2 & 0xff, max_diff)
116 && compare_uint((c1 >> 8) & 0xff, (c2 >> 8) & 0xff, max_diff)
117 && compare_uint((c1 >> 16) & 0xff, (c2 >> 16) & 0xff, max_diff)
118 && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff);
121 static D3DRMMATRIX4D identity = {
122 { 1.0f, 0.0f, 0.0f, 0.0f },
123 { 0.0f, 1.0f, 0.0f, 0.0f },
124 { 0.0f, 0.0f, 1.0f, 0.0f },
125 { 0.0f, 0.0f, 0.0f, 1.0f }
128 static void frame_set_transform(IDirect3DRMFrame *frame,
129 float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24,
130 float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)
132 D3DRMMATRIX4D matrix =
134 {m11, m12, m13, m14},
135 {m21, m22, m23, m24},
136 {m31, m32, m33, m34},
137 {m41, m42, m43, m44},
140 IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_REPLACE, matrix);
143 static void set_vector(D3DVECTOR *v, float x, float y, float z)
145 U1(*v).x = x;
146 U2(*v).y = y;
147 U3(*v).z = z;
150 static void matrix_sanitise(D3DRMMATRIX4D m)
152 unsigned int i, j;
154 for (i = 0; i < 4; ++i)
156 for (j = 0; j < 4; ++j)
158 if (m[i][j] > -1e-7f && m[i][j] < 1e-7f)
159 m[i][j] = 0.0f;
164 static HWND create_window(void)
166 RECT r = {0, 0, 640, 480};
168 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
170 return CreateWindowA("static", "d3drm_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
171 CW_USEDEFAULT, CW_USEDEFAULT, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
174 #define test_class_name(a, b) test_class_name_(__LINE__, a, b)
175 static void test_class_name_(unsigned int line, IDirect3DRMObject *object, const char *name)
177 char cname[64] = {0};
178 DWORD size, size2;
179 HRESULT hr;
181 hr = IDirect3DRMObject_GetClassName(object, NULL, cname);
182 ok_(__FILE__, line)(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
183 hr = IDirect3DRMViewport_GetClassName(object, NULL, NULL);
184 ok_(__FILE__, line)(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
186 size = 0;
187 hr = IDirect3DRMObject_GetClassName(object, &size, NULL);
188 ok_(__FILE__, line)(hr == D3DRM_OK, "Failed to get classname size, hr %#x.\n", hr);
189 ok_(__FILE__, line)(size == strlen(name) + 1, "wrong size: %u\n", size);
191 size = size2 = !!*name;
192 hr = IDirect3DRMObject_GetClassName(object, &size, cname);
193 ok_(__FILE__, line)(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
194 ok_(__FILE__, line)(size == size2, "Got size %u.\n", size);
196 size = sizeof(cname);
197 hr = IDirect3DRMObject_GetClassName(object, &size, cname);
198 ok_(__FILE__, line)(hr == D3DRM_OK, "Failed to get classname, hr %#x.\n", hr);
199 ok_(__FILE__, line)(size == strlen(name) + 1, "wrong size: %u\n", size);
200 ok_(__FILE__, line)(!strcmp(cname, name), "Expected cname to be \"%s\", but got \"%s\".\n", name, cname);
202 size = strlen(name) + 1;
203 hr = IDirect3DRMObject_GetClassName(object, &size, cname);
204 ok_(__FILE__, line)(hr == D3DRM_OK, "Failed to get classname, hr %#x.\n", hr);
205 ok_(__FILE__, line)(size == strlen(name) + 1, "wrong size: %u\n", size);
206 ok_(__FILE__, line)(!strcmp(cname, name), "Expected cname to be \"%s\", but got \"%s\".\n", name, cname);
208 size = strlen(name);
209 strcpy(cname, "XXX");
210 hr = IDirect3DRMObject_GetClassName(object, &size, cname);
211 ok_(__FILE__, line)(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
212 ok_(__FILE__, line)(size == strlen(name), "Wrong classname size: %u.\n", size);
213 ok_(__FILE__, line)(!strcmp(cname, "XXX"), "Expected unchanged buffer, but got \"%s\".\n", cname);
216 #define test_object_name(a) test_object_name_(__LINE__, a)
217 static void test_object_name_(unsigned int line, IDirect3DRMObject *object)
219 char name[64] = {0};
220 HRESULT hr;
221 DWORD size;
223 hr = IDirect3DRMObject_GetName(object, NULL, NULL);
224 ok_(__FILE__, line)(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
226 name[0] = 0x1f;
227 hr = IDirect3DRMObject_GetName(object, NULL, name);
228 ok_(__FILE__, line)(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
229 ok_(__FILE__, line)(name[0] == 0x1f, "Unexpected buffer contents, %#x.\n", name[0]);
231 /* Name is not set yet. */
232 size = 100;
233 hr = IDirect3DRMObject_GetName(object, &size, NULL);
234 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#x.\n", hr);
235 ok_(__FILE__, line)(size == 0, "Unexpected size %u.\n", size);
237 size = sizeof(name);
238 name[0] = 0x1f;
239 hr = IDirect3DRMObject_GetName(object, &size, name);
240 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#x.\n", hr);
241 ok_(__FILE__, line)(size == 0, "Unexpected size %u.\n", size);
242 ok_(__FILE__, line)(name[0] == 0, "Unexpected name \"%s\".\n", name);
244 size = 0;
245 name[0] = 0x1f;
246 hr = IDirect3DRMObject_GetName(object, &size, name);
247 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#x.\n", hr);
248 ok_(__FILE__, line)(size == 0, "Unexpected size %u.\n", size);
249 ok_(__FILE__, line)(name[0] == 0x1f, "Unexpected name \"%s\".\n", name);
251 hr = IDirect3DRMObject_SetName(object, NULL);
252 ok_(__FILE__, line)(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
254 hr = IDirect3DRMObject_SetName(object, "name");
255 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to set a name, hr %#x.\n", hr);
257 size = 0;
258 hr = IDirect3DRMObject_GetName(object, &size, NULL);
259 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#x.\n", hr);
260 ok_(__FILE__, line)(size == strlen("name") + 1, "Unexpected size %u.\n", size);
262 size = strlen("name") + 1;
263 hr = IDirect3DRMObject_GetName(object, &size, name);
264 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#x.\n", hr);
265 ok_(__FILE__, line)(size == strlen("name") + 1, "Unexpected size %u.\n", size);
266 ok_(__FILE__, line)(!strcmp(name, "name"), "Unexpected name \"%s\".\n", name);
268 size = 2;
269 name[0] = 0x1f;
270 hr = IDirect3DRMObject_GetName(object, &size, name);
271 ok_(__FILE__, line)(hr == E_INVALIDARG, "Failed to get object name, hr %#x.\n", hr);
272 ok_(__FILE__, line)(size == 2, "Unexpected size %u.\n", size);
273 ok_(__FILE__, line)(name[0] == 0x1f, "Got unexpected name \"%s\".\n", name);
275 hr = IDirect3DRMObject_SetName(object, NULL);
276 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to set object name, hr %#x.\n", hr);
278 size = 1;
279 hr = IDirect3DRMObject_GetName(object, &size, NULL);
280 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#x.\n", hr);
281 ok_(__FILE__, line)(size == 0, "Unexpected size %u.\n", size);
283 size = 1;
284 name[0] = 0x1f;
285 hr = IDirect3DRMObject_GetName(object, &size, name);
286 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#x.\n", hr);
287 ok_(__FILE__, line)(size == 0, "Unexpected size %u.\n", size);
288 ok_(__FILE__, line)(name[0] == 0, "Got unexpected name \"%s\".\n", name);
291 static char data_bad_version[] =
292 "xof 0302txt 0064\n"
293 "Header Object\n"
294 "{\n"
295 "1; 2; 3;\n"
296 "}\n";
298 static char data_no_mesh[] =
299 "xof 0302txt 0064\n"
300 "Header Object\n"
301 "{\n"
302 "1; 0; 1;\n"
303 "}\n";
305 static char data_ok[] =
306 "xof 0302txt 0064\n"
307 "Header Object\n"
308 "{\n"
309 "1; 0; 1;\n"
310 "}\n"
311 "Mesh Object\n"
312 "{\n"
313 "4;\n"
314 "1.0; 0.0; 0.0;,\n"
315 "0.0; 1.0; 0.0;,\n"
316 "0.0; 0.0; 1.0;,\n"
317 "1.0; 1.0; 1.0;;\n"
318 "3;\n"
319 "3; 0, 1, 2;,\n"
320 "3; 1, 2, 3;,\n"
321 "3; 3, 1, 2;;\n"
322 "}\n";
324 static char data_full[] =
325 "xof 0302txt 0064\n"
326 "Header { 1; 0; 1; }\n"
327 "Mesh {\n"
328 " 3;\n"
329 " 0.1; 0.2; 0.3;,\n"
330 " 0.4; 0.5; 0.6;,\n"
331 " 0.7; 0.8; 0.9;;\n"
332 " 1;\n"
333 " 3; 0, 1, 2;;\n"
334 " MeshMaterialList {\n"
335 " 1; 1; 0;\n"
336 " Material {\n"
337 " 0.0; 1.0; 0.0; 1.0;;\n"
338 " 30.0;\n"
339 " 1.0; 0.0; 0.0;;\n"
340 " 0.5; 0.5; 0.5;;\n"
341 " TextureFileName {\n"
342 " \"Texture.bmp\";\n"
343 " }\n"
344 " }\n"
345 " }\n"
346 " MeshNormals {\n"
347 " 3;\n"
348 " 1.1; 1.2; 1.3;,\n"
349 " 1.4; 1.5; 1.6;,\n"
350 " 1.7; 1.8; 1.9;;\n"
351 " 1;"
352 " 3; 0, 1, 2;;\n"
353 " }\n"
354 " MeshTextureCoords {\n"
355 " 3;\n"
356 " 0.13; 0.17;,\n"
357 " 0.23; 0.27;,\n"
358 " 0.33; 0.37;;\n"
359 " }\n"
360 "}\n";
362 static char data_d3drm_load[] =
363 "xof 0302txt 0064\n"
364 "Header Object\n"
365 "{\n"
366 "1; 0; 1;\n"
367 "}\n"
368 "Mesh Object1\n"
369 "{\n"
370 " 1;\n"
371 " 0.1; 0.2; 0.3;,\n"
372 " 1;\n"
373 " 3; 0, 1, 2;;\n"
374 "}\n"
375 "Mesh Object2\n"
376 "{\n"
377 " 1;\n"
378 " 0.1; 0.2; 0.3;,\n"
379 " 1;\n"
380 " 3; 0, 1, 2;;\n"
381 "}\n"
382 "Frame Scene\n"
383 "{\n"
384 " {Object1}\n"
385 " {Object2}\n"
386 "}\n"
387 "Material\n"
388 "{\n"
389 " 0.1, 0.2, 0.3, 0.4;;\n"
390 " 0.5;\n"
391 " 0.6, 0.7, 0.8;;\n"
392 " 0.9, 1.0, 1.1;;\n"
393 "}\n";
395 static char data_frame_mesh_materials[] =
396 "xof 0302txt 0064\n"
397 "Header { 1; 0; 1; }\n"
398 "Frame {\n"
399 " Mesh mesh1 {\n"
400 " 5;\n"
401 " 0.1; 0.2; 0.3;,\n"
402 " 0.4; 0.5; 0.6;,\n"
403 " 0.7; 0.8; 0.9;,\n"
404 " 1.1; 1.2; 1.3;,\n"
405 " 1.4; 1.5; 1.6;;\n"
406 " 6;\n"
407 " 3; 0, 1, 2;,\n"
408 " 3; 0, 2, 1;,\n"
409 " 3; 1, 2, 3;,\n"
410 " 3; 1, 3, 2;,\n"
411 " 3; 2, 3, 4;,\n"
412 " 3; 2, 4, 3;;\n"
413 " MeshMaterialList {\n"
414 " 3; 6; 0, 1, 1, 2, 2, 2;\n"
415 " Material mat1 {\n"
416 " 1.0; 0.0; 0.0; 0.1;;\n"
417 " 10.0;\n"
418 " 0.11; 0.12; 0.13;;\n"
419 " 0.14; 0.15; 0.16;;\n"
420 " }\n"
421 " Material mat2 {\n"
422 " 0.0; 1.0; 0.0; 0.2;;\n"
423 " 20.0;\n"
424 " 0.21; 0.22; 0.23;;\n"
425 " 0.24; 0.25; 0.26;;\n"
426 " }\n"
427 " Material mat3 {\n"
428 " 0.0; 0.0; 1.0; 0.3;;\n"
429 " 30.0;\n"
430 " 0.31; 0.32; 0.33;;\n"
431 " 0.34; 0.35; 0.36;;\n"
432 " }\n"
433 " }\n"
434 " }\n"
435 "}\n";
437 static void test_MeshBuilder(void)
439 HRESULT hr;
440 IDirect3DRM *d3drm;
441 IDirect3DRMMeshBuilder *pMeshBuilder;
442 IDirect3DRMMeshBuilder3 *meshbuilder3;
443 IDirect3DRMMesh *mesh;
444 D3DRMLOADMEMORY info;
445 int val;
446 DWORD val1, val2, val3;
447 D3DVALUE valu, valv;
448 D3DVECTOR v[3];
449 D3DVECTOR n[4];
450 DWORD f[8];
451 char name[10];
452 DWORD size;
453 D3DCOLOR color;
454 IUnknown *unk;
456 hr = Direct3DRMCreate(&d3drm);
457 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
459 hr = IDirect3DRM_CreateMeshBuilder(d3drm, &pMeshBuilder);
460 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder interface (hr = %x)\n", hr);
462 hr = IDirect3DRMMeshBuilder_QueryInterface(pMeshBuilder, &IID_IDirect3DRMObject, (void **)&unk);
463 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, %#x.\n", hr);
464 ok(unk == (IUnknown *)pMeshBuilder, "Unexpected interface pointer.\n");
465 IUnknown_Release(unk);
467 hr = IDirect3DRMMeshBuilder_QueryInterface(pMeshBuilder, &IID_IDirect3DRMVisual, (void **)&unk);
468 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMVisual, %#x.\n", hr);
469 ok(unk == (IUnknown *)pMeshBuilder, "Unexpected interface pointer.\n");
470 IUnknown_Release(unk);
472 hr = IDirect3DRMMeshBuilder_QueryInterface(pMeshBuilder, &IID_IDirect3DRMMeshBuilder3, (void **)&meshbuilder3);
473 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMMeshBuilder3, %#x.\n", hr);
475 hr = IDirect3DRMMeshBuilder3_QueryInterface(meshbuilder3, &IID_IDirect3DRMObject, (void **)&unk);
476 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, %#x.\n", hr);
477 ok(unk == (IUnknown *)pMeshBuilder, "Unexpected interface pointer.\n");
478 IUnknown_Release(unk);
480 hr = IDirect3DRMMeshBuilder3_QueryInterface(meshbuilder3, &IID_IDirect3DRMVisual, (void **)&unk);
481 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMVisual, %#x.\n", hr);
482 ok(unk == (IUnknown *)pMeshBuilder, "Unexpected interface pointer.\n");
483 IUnknown_Release(unk);
485 IDirect3DRMMeshBuilder3_Release(meshbuilder3);
487 test_class_name((IDirect3DRMObject *)pMeshBuilder, "Builder");
488 test_object_name((IDirect3DRMObject *)pMeshBuilder);
490 info.lpMemory = data_bad_version;
491 info.dSize = strlen(data_bad_version);
492 hr = IDirect3DRMMeshBuilder_Load(pMeshBuilder, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
493 ok(hr == D3DRMERR_BADFILE, "Should have returned D3DRMERR_BADFILE (hr = %x)\n", hr);
495 info.lpMemory = data_no_mesh;
496 info.dSize = strlen(data_no_mesh);
497 hr = IDirect3DRMMeshBuilder_Load(pMeshBuilder, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
498 ok(hr == D3DRMERR_NOTFOUND, "Should have returned D3DRMERR_NOTFOUND (hr = %x)\n", hr);
500 info.lpMemory = data_ok;
501 info.dSize = strlen(data_ok);
502 hr = IDirect3DRMMeshBuilder_Load(pMeshBuilder, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
503 ok(hr == D3DRM_OK, "Cannot load mesh data (hr = %x)\n", hr);
505 size = sizeof(name);
506 hr = IDirect3DRMMeshBuilder_GetName(pMeshBuilder, &size, name);
507 ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_GetName returned hr = %x\n", hr);
508 ok(!strcmp(name, "Object"), "Retrieved name '%s' instead of 'Object'\n", name);
509 size = strlen("Object"); /* No space for null character */
510 hr = IDirect3DRMMeshBuilder_GetName(pMeshBuilder, &size, name);
511 ok(hr == E_INVALIDARG, "IDirect3DRMMeshBuilder_GetName returned hr = %x\n", hr);
512 hr = IDirect3DRMMeshBuilder_SetName(pMeshBuilder, NULL);
513 ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_SetName returned hr = %x\n", hr);
514 size = sizeof(name);
515 hr = IDirect3DRMMeshBuilder_GetName(pMeshBuilder, &size, name);
516 ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_GetName returned hr = %x\n", hr);
517 ok(size == 0, "Size should be 0 instead of %u\n", size);
518 hr = IDirect3DRMMeshBuilder_SetName(pMeshBuilder, "");
519 ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_SetName returned hr = %x\n", hr);
520 size = sizeof(name);
521 hr = IDirect3DRMMeshBuilder_GetName(pMeshBuilder, &size, name);
522 ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_GetName returned hr = %x\n", hr);
523 ok(!strcmp(name, ""), "Retrieved name '%s' instead of ''\n", name);
525 val = IDirect3DRMMeshBuilder_GetVertexCount(pMeshBuilder);
526 ok(val == 4, "Wrong number of vertices %d (must be 4)\n", val);
528 val = IDirect3DRMMeshBuilder_GetFaceCount(pMeshBuilder);
529 ok(val == 3, "Wrong number of faces %d (must be 3)\n", val);
531 hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, NULL, &val2, NULL, &val3, NULL);
532 ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
533 ok(val1 == 4, "Wrong number of vertices %d (must be 4)\n", val1);
534 ok(val2 == 4, "Wrong number of normals %d (must be 4)\n", val2);
535 ok(val3 == 22, "Wrong number of face data bytes %d (must be 22)\n", val3);
537 /* Check that Load method generated default normals */
538 hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, NULL, NULL, &val2, n, NULL, NULL);
539 ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
540 expect_vector(&n[0], 0.577350f, 0.577350f, 0.577350f, 32);
541 expect_vector(&n[1], -0.229416f, 0.688247f, 0.688247f, 32);
542 expect_vector(&n[2], -0.229416f, 0.688247f, 0.688247f, 32);
543 expect_vector(&n[3], -0.577350f, 0.577350f, 0.577350f, 32);
545 /* Check that Load method generated default texture coordinates (0.0f, 0.0f) for each vertex */
546 valu = 1.23f;
547 valv = 3.21f;
548 hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 0, &valu, &valv);
549 ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
550 ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
551 ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
552 valu = 1.23f;
553 valv = 3.21f;
554 hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 1, &valu, &valv);
555 ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
556 ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
557 ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
558 valu = 1.23f;
559 valv = 3.21f;
560 hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 2, &valu, &valv);
561 ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
562 ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
563 ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
564 valu = 1.23f;
565 valv = 3.21f;
566 hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 3, &valu, &valv);
567 ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
568 ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
569 ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
570 hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 4, &valu, &valv);
571 ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
573 valu = 1.23f;
574 valv = 3.21f;
575 hr = IDirect3DRMMeshBuilder_SetTextureCoordinates(pMeshBuilder, 0, valu, valv);
576 ok(hr == D3DRM_OK, "Cannot set texture coordinates (hr = %x)\n", hr);
577 hr = IDirect3DRMMeshBuilder_SetTextureCoordinates(pMeshBuilder, 4, valu, valv);
578 ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
580 valu = 0.0f;
581 valv = 0.0f;
582 hr = IDirect3DRMMeshBuilder_GetTextureCoordinates(pMeshBuilder, 0, &valu, &valv);
583 ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
584 ok(valu == 1.23f, "Wrong coordinate %f (must be 1.23)\n", valu);
585 ok(valv == 3.21f, "Wrong coordinate %f (must be 3.21)\n", valv);
587 IDirect3DRMMeshBuilder_Release(pMeshBuilder);
589 hr = IDirect3DRM_CreateMeshBuilder(d3drm, &pMeshBuilder);
590 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder interface (hr = %x)\n", hr);
592 /* No group in mesh when mesh builder is not loaded */
593 hr = IDirect3DRMMeshBuilder_CreateMesh(pMeshBuilder, &mesh);
594 ok(hr == D3DRM_OK, "CreateMesh failed returning hr = %x\n", hr);
595 if (hr == D3DRM_OK)
597 DWORD nb_groups;
599 nb_groups = IDirect3DRMMesh_GetGroupCount(mesh);
600 ok(nb_groups == 0, "GetCroupCount returned %u\n", nb_groups);
602 IDirect3DRMMesh_Release(mesh);
605 info.lpMemory = data_full;
606 info.dSize = strlen(data_full);
607 hr = IDirect3DRMMeshBuilder_Load(pMeshBuilder, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
608 ok(hr == D3DRM_OK, "Cannot load mesh data (hr = %x)\n", hr);
610 val = IDirect3DRMMeshBuilder_GetVertexCount(pMeshBuilder);
611 ok(val == 3, "Wrong number of vertices %d (must be 3)\n", val);
613 val = IDirect3DRMMeshBuilder_GetFaceCount(pMeshBuilder);
614 ok(val == 1, "Wrong number of faces %d (must be 1)\n", val);
616 /* Check no buffer size and too small buffer size errors */
617 val1 = 1; val2 = 3; val3 = 8;
618 hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
619 ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
620 hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, NULL, v, &val2, n, &val3, f);
621 ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
622 val1 = 3; val2 = 1; val3 = 8;
623 hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
624 ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
625 hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, NULL, n, &val3, f);
626 ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
627 val1 = 3; val2 = 3; val3 = 1;
628 hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
629 ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
630 hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, NULL, f);
631 ok(hr == D3DRMERR_BADVALUE, "IDirect3DRMMeshBuilder_GetVertices returned %#x\n", hr);
633 val1 = 3; val2 = 3; val3 = 8;
634 hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
635 ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
636 ok(val1 == 3, "Wrong number of vertices %d (must be 3)\n", val1);
637 ok(val2 == 3, "Wrong number of normals %d (must be 3)\n", val2);
638 ok(val3 == 8, "Wrong number of face data bytes %d (must be 8)\n", val3);
639 expect_vector(&v[0], 0.1f, 0.2f, 0.3f, 32);
640 expect_vector(&v[1], 0.4f, 0.5f, 0.6f, 32);
641 expect_vector(&v[2], 0.7f, 0.8f, 0.9f, 32);
642 expect_vector(&n[0], 1.1f, 1.2f, 1.3f, 32);
643 expect_vector(&n[1], 1.4f, 1.5f, 1.6f, 32);
644 expect_vector(&n[2], 1.7f, 1.8f, 1.9f, 32);
645 ok(f[0] == 3 , "Wrong component f[0] = %d (expected 3)\n", f[0]);
646 ok(f[1] == 0 , "Wrong component f[1] = %d (expected 0)\n", f[1]);
647 ok(f[2] == 0 , "Wrong component f[2] = %d (expected 0)\n", f[2]);
648 ok(f[3] == 1 , "Wrong component f[3] = %d (expected 1)\n", f[3]);
649 ok(f[4] == 1 , "Wrong component f[4] = %d (expected 1)\n", f[4]);
650 ok(f[5] == 2 , "Wrong component f[5] = %d (expected 2)\n", f[5]);
651 ok(f[6] == 2 , "Wrong component f[6] = %d (expected 2)\n", f[6]);
652 ok(f[7] == 0 , "Wrong component f[7] = %d (expected 0)\n", f[7]);
654 hr = IDirect3DRMMeshBuilder_CreateMesh(pMeshBuilder, &mesh);
655 ok(hr == D3DRM_OK, "CreateMesh failed returning hr = %x\n", hr);
656 if (hr == D3DRM_OK)
658 DWORD nb_groups;
659 unsigned nb_vertices, nb_faces, nb_face_vertices;
660 DWORD data_size;
661 IDirect3DRMMaterial *material = (IDirect3DRMMaterial *)0xdeadbeef;
662 IDirect3DRMTexture *texture = (IDirect3DRMTexture *)0xdeadbeef;
663 D3DVALUE values[3];
665 nb_groups = IDirect3DRMMesh_GetGroupCount(mesh);
666 ok(nb_groups == 1, "GetCroupCount returned %u\n", nb_groups);
667 hr = IDirect3DRMMesh_GetGroup(mesh, 1, &nb_vertices, &nb_faces, &nb_face_vertices, &data_size, NULL);
668 ok(hr == D3DRMERR_BADVALUE, "GetCroup returned hr = %x\n", hr);
669 hr = IDirect3DRMMesh_GetGroup(mesh, 0, &nb_vertices, &nb_faces, &nb_face_vertices, &data_size, NULL);
670 ok(hr == D3DRM_OK, "GetCroup failed returning hr = %x\n", hr);
671 ok(nb_vertices == 3, "Wrong number of vertices %u (must be 3)\n", nb_vertices);
672 ok(nb_faces == 1, "Wrong number of faces %u (must be 1)\n", nb_faces);
673 ok(nb_face_vertices == 3, "Wrong number of vertices per face %u (must be 3)\n", nb_face_vertices);
674 ok(data_size == 3, "Wrong number of face data bytes %u (must be 3)\n", data_size);
675 color = IDirect3DRMMesh_GetGroupColor(mesh, 0);
676 ok(color == 0xff00ff00, "Wrong color returned %#x instead of %#x\n", color, 0xff00ff00);
677 hr = IDirect3DRMMesh_GetGroupTexture(mesh, 0, &texture);
678 ok(hr == D3DRM_OK, "GetCroupTexture failed returning hr = %x\n", hr);
679 ok(texture == NULL, "No texture should be present\n");
680 hr = IDirect3DRMMesh_GetGroupMaterial(mesh, 0, &material);
681 ok(hr == D3DRM_OK, "GetCroupMaterial failed returning hr = %x\n", hr);
682 ok(material != NULL, "No material present\n");
683 hr = IDirect3DRMMaterial_GetEmissive(material, &values[0], &values[1], &values[2]);
684 ok(hr == D3DRM_OK, "Failed to get emissive color, hr %#x.\n", hr);
685 ok(values[0] == 0.5f, "Got unexpected red component %.8e.\n", values[0]);
686 ok(values[1] == 0.5f, "Got unexpected green component %.8e.\n", values[1]);
687 ok(values[2] == 0.5f, "Got unexpected blue component %.8e.\n", values[2]);
688 hr = IDirect3DRMMaterial_GetSpecular(material, &values[0], &values[1], &values[2]);
689 ok(hr == D3DRM_OK, "Failed to get specular color, hr %#x.\n", hr);
690 ok(values[0] == 1.0f, "Got unexpected red component %.8e.\n", values[0]);
691 ok(values[1] == 0.0f, "Got unexpected green component %.8e.\n", values[1]);
692 ok(values[2] == 0.0f, "Got unexpected blue component %.8e.\n", values[2]);
693 values[0] = IDirect3DRMMaterial_GetPower(material);
694 ok(values[0] == 30.0f, "Got unexpected power value %.8e.\n", values[0]);
695 IDirect3DRMMaterial_Release(material);
697 IDirect3DRMMesh_Release(mesh);
700 hr = IDirect3DRMMeshBuilder_Scale(pMeshBuilder, 2, 3 ,4);
701 ok(hr == D3DRM_OK, "Scale failed returning hr = %x\n", hr);
703 hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
704 ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
705 ok(val2 == 3, "Wrong number of normals %d (must be 3)\n", val2);
706 ok(val1 == 3, "Wrong number of vertices %d (must be 3)\n", val1);
708 expect_vector(&v[0], 0.1f * 2, 0.2f * 3, 0.3f * 4, 32);
709 expect_vector(&v[1], 0.4f * 2, 0.5f * 3, 0.6f * 4, 32);
710 expect_vector(&v[2], 0.7f * 2, 0.8f * 3, 0.9f * 4, 32);
711 /* Normals are not affected by Scale */
712 expect_vector(&n[0], 1.1f, 1.2f, 1.3f, 32);
713 expect_vector(&n[1], 1.4f, 1.5f, 1.6f, 32);
714 expect_vector(&n[2], 1.7f, 1.8f, 1.9f, 32);
716 IDirect3DRMMeshBuilder_Release(pMeshBuilder);
718 IDirect3DRM_Release(d3drm);
721 static void test_MeshBuilder3(void)
723 HRESULT hr;
724 IDirect3DRM *d3drm;
725 IDirect3DRM3 *d3drm3;
726 IDirect3DRMMeshBuilder3 *pMeshBuilder3;
727 D3DRMLOADMEMORY info;
728 int val;
729 DWORD val1;
730 D3DVALUE valu, valv;
732 hr = Direct3DRMCreate(&d3drm);
733 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
735 if (FAILED(hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM3, (void **)&d3drm3)))
737 win_skip("Cannot get IDirect3DRM3 interface (hr = %x), skipping tests\n", hr);
738 IDirect3DRM_Release(d3drm);
739 return;
742 hr = IDirect3DRM3_CreateMeshBuilder(d3drm3, &pMeshBuilder3);
743 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder3 interface (hr = %x)\n", hr);
745 test_class_name((IDirect3DRMObject *)pMeshBuilder3, "Builder");
746 test_object_name((IDirect3DRMObject *)pMeshBuilder3);
748 info.lpMemory = data_bad_version;
749 info.dSize = strlen(data_bad_version);
750 hr = IDirect3DRMMeshBuilder3_Load(pMeshBuilder3, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
751 ok(hr == D3DRMERR_BADFILE, "Should have returned D3DRMERR_BADFILE (hr = %x)\n", hr);
753 info.lpMemory = data_no_mesh;
754 info.dSize = strlen(data_no_mesh);
755 hr = IDirect3DRMMeshBuilder3_Load(pMeshBuilder3, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
756 ok(hr == D3DRMERR_NOTFOUND, "Should have returned D3DRMERR_NOTFOUND (hr = %x)\n", hr);
758 info.lpMemory = data_ok;
759 info.dSize = strlen(data_ok);
760 hr = IDirect3DRMMeshBuilder3_Load(pMeshBuilder3, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
761 ok(hr == D3DRM_OK, "Cannot load mesh data (hr = %x)\n", hr);
763 val = IDirect3DRMMeshBuilder3_GetVertexCount(pMeshBuilder3);
764 ok(val == 4, "Wrong number of vertices %d (must be 4)\n", val);
766 val = IDirect3DRMMeshBuilder3_GetFaceCount(pMeshBuilder3);
767 ok(val == 3, "Wrong number of faces %d (must be 3)\n", val);
769 hr = IDirect3DRMMeshBuilder3_GetVertices(pMeshBuilder3, 0, &val1, NULL);
770 ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
771 ok(val1 == 4, "Wrong number of vertices %d (must be 4)\n", val1);
773 /* Check that Load method generated default texture coordinates (0.0f, 0.0f) for each vertex */
774 valu = 1.23f;
775 valv = 3.21f;
776 hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 0, &valu, &valv);
777 ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
778 ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
779 ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
780 valu = 1.23f;
781 valv = 3.21f;
782 hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 1, &valu, &valv);
783 ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
784 ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
785 ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
786 valu = 1.23f;
787 valv = 3.21f;
788 hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 2, &valu, &valv);
789 ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
790 ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
791 ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
792 valu = 1.23f;
793 valv = 3.21f;
794 hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 3, &valu, &valv);
795 ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
796 ok(valu == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valu);
797 ok(valv == 0.0f, "Wrong coordinate %f (must be 0.0)\n", valv);
798 hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 4, &valu, &valv);
799 ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
801 valu = 1.23f;
802 valv = 3.21f;
803 hr = IDirect3DRMMeshBuilder3_SetTextureCoordinates(pMeshBuilder3, 0, valu, valv);
804 ok(hr == D3DRM_OK, "Cannot set texture coordinates (hr = %x)\n", hr);
805 hr = IDirect3DRMMeshBuilder3_SetTextureCoordinates(pMeshBuilder3, 4, valu, valv);
806 ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
808 valu = 0.0f;
809 valv = 0.0f;
810 hr = IDirect3DRMMeshBuilder3_GetTextureCoordinates(pMeshBuilder3, 0, &valu, &valv);
811 ok(hr == D3DRM_OK, "Cannot get texture coordinates (hr = %x)\n", hr);
812 ok(valu == 1.23f, "Wrong coordinate %f (must be 1.23)\n", valu);
813 ok(valv == 3.21f, "Wrong coordinate %f (must be 3.21)\n", valv);
815 IDirect3DRMMeshBuilder3_Release(pMeshBuilder3);
816 IDirect3DRM3_Release(d3drm3);
817 IDirect3DRM_Release(d3drm);
820 static void test_Mesh(void)
822 HRESULT hr;
823 IDirect3DRM *d3drm;
824 IDirect3DRMMesh *mesh;
825 IUnknown *unk;
827 hr = Direct3DRMCreate(&d3drm);
828 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
830 hr = IDirect3DRM_CreateMesh(d3drm, &mesh);
831 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMesh interface (hr = %x)\n", hr);
833 test_class_name((IDirect3DRMObject *)mesh, "Mesh");
834 test_object_name((IDirect3DRMObject *)mesh);
836 hr = IDirect3DRMMesh_QueryInterface(mesh, &IID_IDirect3DRMObject, (void **)&unk);
837 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, %#x.\n", hr);
838 IUnknown_Release(unk);
840 hr = IDirect3DRMMesh_QueryInterface(mesh, &IID_IDirect3DRMVisual, (void **)&unk);
841 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMVisual, %#x.\n", hr);
842 IUnknown_Release(unk);
844 IDirect3DRMMesh_Release(mesh);
846 IDirect3DRM_Release(d3drm);
849 static void test_Face(void)
851 HRESULT hr;
852 IDirect3DRM *d3drm;
853 IDirect3DRM2 *d3drm2;
854 IDirect3DRM3 *d3drm3;
855 IDirect3DRMMeshBuilder2 *MeshBuilder2;
856 IDirect3DRMMeshBuilder3 *MeshBuilder3;
857 IDirect3DRMFace *face1;
858 IDirect3DRMObject *obj;
859 IDirect3DRMFace2 *face2;
860 IDirect3DRMFaceArray *array1;
861 D3DRMLOADMEMORY info;
862 D3DVECTOR v1[4], n1[4], v2[4], n2[4];
863 D3DCOLOR color;
864 DWORD count;
865 int icount;
867 hr = Direct3DRMCreate(&d3drm);
868 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
870 hr = IDirect3DRM_CreateFace(d3drm, &face1);
871 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFace interface (hr = %x)\n", hr);
872 if (FAILED(hr))
874 skip("Cannot get IDirect3DRMFace interface (hr = %x), skipping tests\n", hr);
875 IDirect3DRM_Release(d3drm);
876 return;
879 hr = IDirect3DRMFace_QueryInterface(face1, &IID_IDirect3DRMObject, (void **)&obj);
880 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, %#x.\n", hr);
881 ok(obj == (IDirect3DRMObject *)face1, "Unexpected interface pointer.\n");
882 IDirect3DRMObject_Release(obj);
884 test_class_name((IDirect3DRMObject *)face1, "Face");
885 test_object_name((IDirect3DRMObject *)face1);
887 icount = IDirect3DRMFace_GetVertexCount(face1);
888 ok(!icount, "wrong VertexCount: %i\n", icount);
890 IDirect3DRMFace_Release(face1);
892 if (FAILED(hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM2, (void **)&d3drm2)))
894 win_skip("Cannot get IDirect3DRM2 interface (hr = %x), skipping tests\n", hr);
895 IDirect3DRM_Release(d3drm);
896 return;
899 hr = IDirect3DRM2_CreateMeshBuilder(d3drm2, &MeshBuilder2);
900 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder2 interface (hr = %x)\n", hr);
902 icount = IDirect3DRMMeshBuilder2_GetFaceCount(MeshBuilder2);
903 ok(!icount, "wrong FaceCount: %i\n", icount);
905 array1 = NULL;
906 hr = IDirect3DRMMeshBuilder2_GetFaces(MeshBuilder2, &array1);
907 todo_wine
908 ok(hr == D3DRM_OK, "Cannot get FaceArray (hr = %x)\n", hr);
910 hr = IDirect3DRMMeshBuilder2_CreateFace(MeshBuilder2, &face1);
911 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFace interface (hr = %x)\n", hr);
913 icount = IDirect3DRMMeshBuilder2_GetFaceCount(MeshBuilder2);
914 todo_wine
915 ok(icount == 1, "wrong FaceCount: %i\n", icount);
917 array1 = NULL;
918 hr = IDirect3DRMMeshBuilder2_GetFaces(MeshBuilder2, &array1);
919 todo_wine
920 ok(hr == D3DRM_OK, "Cannot get FaceArray (hr = %x)\n", hr);
921 todo_wine
922 ok(array1 != NULL, "pArray = %p\n", array1);
923 if (array1)
925 IDirect3DRMFace *face;
926 count = IDirect3DRMFaceArray_GetSize(array1);
927 ok(count == 1, "count = %u\n", count);
928 hr = IDirect3DRMFaceArray_GetElement(array1, 0, &face);
929 ok(hr == D3DRM_OK, "Cannot get face (hr = %x)\n", hr);
930 IDirect3DRMFace_Release(face);
931 IDirect3DRMFaceArray_Release(array1);
934 icount = IDirect3DRMFace_GetVertexCount(face1);
935 ok(!icount, "wrong VertexCount: %i\n", icount);
937 IDirect3DRMFace_Release(face1);
938 IDirect3DRMMeshBuilder2_Release(MeshBuilder2);
940 if (FAILED(hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM3, (void **)&d3drm3)))
942 win_skip("Cannot get IDirect3DRM3 interface (hr = %x), skipping tests\n", hr);
943 IDirect3DRM_Release(d3drm);
944 return;
947 hr = IDirect3DRM3_CreateMeshBuilder(d3drm3, &MeshBuilder3);
948 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder3 interface (hr = %x)\n", hr);
950 icount = IDirect3DRMMeshBuilder3_GetFaceCount(MeshBuilder3);
951 ok(!icount, "wrong FaceCount: %i\n", icount);
953 hr = IDirect3DRMMeshBuilder3_CreateFace(MeshBuilder3, &face2);
954 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFace2 interface (hr = %x)\n", hr);
956 hr = IDirect3DRMFace2_QueryInterface(face2, &IID_IDirect3DRMObject, (void **)&obj);
957 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, %#x.\n", hr);
959 hr = IDirect3DRMFace2_QueryInterface(face2, &IID_IDirect3DRMFace, (void **)&face1);
960 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, %#x.\n", hr);
961 ok(obj == (IDirect3DRMObject *)face1, "Unexpected interface pointer.\n");
963 IDirect3DRMFace_Release(face1);
964 IDirect3DRMObject_Release(obj);
966 test_class_name((IDirect3DRMObject *)face2, "Face");
967 test_object_name((IDirect3DRMObject *)face2);
969 icount = IDirect3DRMMeshBuilder3_GetFaceCount(MeshBuilder3);
970 todo_wine
971 ok(icount == 1, "wrong FaceCount: %i\n", icount);
973 array1 = NULL;
974 hr = IDirect3DRMMeshBuilder3_GetFaces(MeshBuilder3, &array1);
975 todo_wine
976 ok(hr == D3DRM_OK, "Cannot get FaceArray (hr = %x)\n", hr);
977 todo_wine
978 ok(array1 != NULL, "pArray = %p\n", array1);
979 if (array1)
981 IDirect3DRMFace *face;
982 count = IDirect3DRMFaceArray_GetSize(array1);
983 ok(count == 1, "count = %u\n", count);
984 hr = IDirect3DRMFaceArray_GetElement(array1, 0, &face);
985 ok(hr == D3DRM_OK, "Cannot get face (hr = %x)\n", hr);
986 IDirect3DRMFace_Release(face);
987 IDirect3DRMFaceArray_Release(array1);
990 icount = IDirect3DRMFace2_GetVertexCount(face2);
991 ok(!icount, "wrong VertexCount: %i\n", icount);
993 info.lpMemory = data_ok;
994 info.dSize = strlen(data_ok);
995 hr = IDirect3DRMMeshBuilder3_Load(MeshBuilder3, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
996 ok(hr == D3DRM_OK, "Cannot load mesh data (hr = %x)\n", hr);
998 icount = IDirect3DRMMeshBuilder3_GetVertexCount(MeshBuilder3);
999 ok(icount == 4, "Wrong number of vertices %d (must be 4)\n", icount);
1001 icount = IDirect3DRMMeshBuilder3_GetNormalCount(MeshBuilder3);
1002 ok(icount == 4, "Wrong number of normals %d (must be 4)\n", icount);
1004 icount = IDirect3DRMMeshBuilder3_GetFaceCount(MeshBuilder3);
1005 todo_wine
1006 ok(icount == 4, "Wrong number of faces %d (must be 4)\n", icount);
1008 count = 4;
1009 hr = IDirect3DRMMeshBuilder3_GetVertices(MeshBuilder3, 0, &count, v1);
1010 ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
1011 ok(count == 4, "Wrong number of vertices %d (must be 4)\n", count);
1013 hr = IDirect3DRMMeshBuilder3_GetNormals(MeshBuilder3, 0, &count, n1);
1014 ok(hr == D3DRM_OK, "Cannot get normals information (hr = %x)\n", hr);
1015 ok(count == 4, "Wrong number of normals %d (must be 4)\n", count);
1017 array1 = NULL;
1018 hr = IDirect3DRMMeshBuilder3_GetFaces(MeshBuilder3, &array1);
1019 todo_wine
1020 ok(hr == D3DRM_OK, "Cannot get FaceArray (hr = %x)\n", hr);
1021 todo_wine
1022 ok(array1 != NULL, "pArray = %p\n", array1);
1023 if (array1)
1025 IDirect3DRMFace *face;
1026 count = IDirect3DRMFaceArray_GetSize(array1);
1027 ok(count == 4, "count = %u\n", count);
1028 hr = IDirect3DRMFaceArray_GetElement(array1, 1, &face);
1029 ok(hr == D3DRM_OK, "Cannot get face (hr = %x)\n", hr);
1030 hr = IDirect3DRMFace_GetVertices(face, &count, v2, n2);
1031 ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr);
1032 ok(count == 3, "Wrong number of vertices %d (must be 3)\n", count);
1034 vector_eq(&v1[0], &v2[0]);
1035 vector_eq(&v1[1], &v2[1]);
1036 vector_eq(&v1[2], &v2[2]);
1038 vector_eq(&n1[0], &n2[0]);
1039 vector_eq(&n1[1], &n2[1]);
1040 vector_eq(&n1[2], &n2[2]);
1042 IDirect3DRMFace_Release(face);
1043 IDirect3DRMFaceArray_Release(array1);
1046 /* Setting face color. */
1047 hr = IDirect3DRMFace2_SetColor(face2, 0x1f180587);
1048 ok(SUCCEEDED(hr), "Failed to set face color, hr %#x.\n", hr);
1049 color = IDirect3DRMFace2_GetColor(face2);
1050 ok(color == 0x1f180587, "Unexpected color %8x.\n", color);
1052 hr = IDirect3DRMFace2_SetColorRGB(face2, 0.5f, 0.5f, 0.5f);
1053 ok(SUCCEEDED(hr), "Failed to set color, hr %#x.\n", hr);
1054 color = IDirect3DRMFace2_GetColor(face2);
1055 ok(color == 0xff7f7f7f, "Unexpected color %8x.\n", color);
1057 IDirect3DRMFace2_Release(face2);
1058 IDirect3DRMMeshBuilder3_Release(MeshBuilder3);
1059 IDirect3DRM3_Release(d3drm3);
1060 IDirect3DRM2_Release(d3drm2);
1061 IDirect3DRM_Release(d3drm);
1064 static void test_Frame(void)
1066 HRESULT hr;
1067 IDirect3DRM *d3drm;
1068 IDirect3DRMFrame *pFrameC;
1069 IDirect3DRMFrame *pFrameP1;
1070 IDirect3DRMFrame *pFrameP2;
1071 IDirect3DRMFrame *pFrameTmp;
1072 IDirect3DRMFrame *scene_frame;
1073 IDirect3DRMFrameArray *frame_array;
1074 IDirect3DRMMeshBuilder *mesh_builder;
1075 IDirect3DRMVisual *visual1;
1076 IDirect3DRMVisual *visual_tmp;
1077 IDirect3DRMVisualArray *visual_array;
1078 IDirect3DRMLight *light1;
1079 IDirect3DRMLight *light_tmp;
1080 IDirect3DRMLightArray *light_array;
1081 IDirect3DRMFrame3 *frame3;
1082 DWORD count, options;
1083 ULONG ref, ref2;
1084 D3DCOLOR color;
1086 hr = Direct3DRMCreate(&d3drm);
1087 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
1089 ref = get_refcount((IUnknown *)d3drm);
1090 hr = IDirect3DRM_CreateFrame(d3drm, NULL, &pFrameC);
1091 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr);
1092 CHECK_REFCOUNT(pFrameC, 1);
1093 ref2 = get_refcount((IUnknown *)d3drm);
1094 ok(ref2 > ref, "Expected d3drm object to be referenced.\n");
1096 test_class_name((IDirect3DRMObject *)pFrameC, "Frame");
1097 test_object_name((IDirect3DRMObject *)pFrameC);
1099 hr = IDirect3DRMFrame_GetParent(pFrameC, NULL);
1100 ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
1101 pFrameTmp = (void*)0xdeadbeef;
1102 hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
1103 ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
1104 ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1105 CHECK_REFCOUNT(pFrameC, 1);
1107 frame_array = NULL;
1108 hr = IDirect3DRMFrame_GetChildren(pFrameC, &frame_array);
1109 ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
1110 ok(!!frame_array, "frame_array = %p\n", frame_array);
1111 if (frame_array)
1113 count = IDirect3DRMFrameArray_GetSize(frame_array);
1114 ok(count == 0, "count = %u\n", count);
1115 hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1116 ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE (hr = %x)\n", hr);
1117 ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1118 IDirect3DRMFrameArray_Release(frame_array);
1121 hr = IDirect3DRM_CreateFrame(d3drm, NULL, &pFrameP1);
1122 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr);
1124 /* GetParent with NULL pointer */
1125 hr = IDirect3DRMFrame_GetParent(pFrameP1, NULL);
1126 ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE (hr = %x)\n", hr);
1127 CHECK_REFCOUNT(pFrameP1, 1);
1129 /* [Add/Delete]Child with NULL pointer */
1130 hr = IDirect3DRMFrame_AddChild(pFrameP1, NULL);
1131 ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
1132 CHECK_REFCOUNT(pFrameP1, 1);
1134 hr = IDirect3DRMFrame_DeleteChild(pFrameP1, NULL);
1135 ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
1136 CHECK_REFCOUNT(pFrameP1, 1);
1138 /* Add child to first parent */
1139 pFrameTmp = (void*)0xdeadbeef;
1140 hr = IDirect3DRMFrame_GetParent(pFrameP1, &pFrameTmp);
1141 ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
1142 ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1144 hr = IDirect3DRMFrame_AddChild(pFrameP1, pFrameC);
1145 ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
1146 CHECK_REFCOUNT(pFrameP1, 1);
1147 CHECK_REFCOUNT(pFrameC, 2);
1149 hr = IDirect3DRMFrame_GetScene(pFrameC, NULL);
1150 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1151 hr = IDirect3DRMFrame_GetScene(pFrameC, &scene_frame);
1152 ok(SUCCEEDED(hr), "Cannot get scene (hr == %#x).\n", hr);
1153 ok(scene_frame == pFrameP1, "Expected scene frame == %p, got %p.\n", pFrameP1, scene_frame);
1154 CHECK_REFCOUNT(pFrameP1, 2);
1155 IDirect3DRMFrame_Release(scene_frame);
1156 hr = IDirect3DRMFrame_GetScene(pFrameP1, &scene_frame);
1157 ok(SUCCEEDED(hr), "Cannot get scene (hr == %#x).\n", hr);
1158 ok(scene_frame == pFrameP1, "Expected scene frame == %p, got %p.\n", pFrameP1, scene_frame);
1159 CHECK_REFCOUNT(pFrameP1, 2);
1160 IDirect3DRMFrame_Release(scene_frame);
1162 frame_array = NULL;
1163 hr = IDirect3DRMFrame_GetChildren(pFrameP1, &frame_array);
1164 ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
1165 /* In some older version of d3drm, creating IDirect3DRMFrameArray object with GetChildren does not increment refcount of children frames */
1166 ok((get_refcount((IUnknown*)pFrameC) == 3) || broken(get_refcount((IUnknown*)pFrameC) == 2),
1167 "Invalid refcount. Expected 3 (or 2) got %d\n", get_refcount((IUnknown*)pFrameC));
1168 if (frame_array)
1170 count = IDirect3DRMFrameArray_GetSize(frame_array);
1171 ok(count == 1, "count = %u\n", count);
1172 hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1173 ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
1174 ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
1175 ok((get_refcount((IUnknown*)pFrameC) == 4) || broken(get_refcount((IUnknown*)pFrameC) == 3),
1176 "Invalid refcount. Expected 4 (or 3) got %d\n", get_refcount((IUnknown*)pFrameC));
1177 IDirect3DRMFrame_Release(pFrameTmp);
1178 ok((get_refcount((IUnknown*)pFrameC) == 3) || broken(get_refcount((IUnknown*)pFrameC) == 2),
1179 "Invalid refcount. Expected 3 (or 2) got %d\n", get_refcount((IUnknown*)pFrameC));
1180 IDirect3DRMFrameArray_Release(frame_array);
1181 CHECK_REFCOUNT(pFrameC, 2);
1184 pFrameTmp = (void*)0xdeadbeef;
1185 hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
1186 ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
1187 ok(pFrameTmp == pFrameP1, "pFrameTmp = %p\n", pFrameTmp);
1188 CHECK_REFCOUNT(pFrameP1, 2);
1189 IDirect3DRMFrame_Release(pFrameTmp);
1190 CHECK_REFCOUNT(pFrameP1, 1);
1192 /* Add child to second parent */
1193 hr = IDirect3DRM_CreateFrame(d3drm, NULL, &pFrameP2);
1194 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr);
1196 hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameC);
1197 ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
1198 CHECK_REFCOUNT(pFrameC, 2);
1200 frame_array = NULL;
1201 hr = IDirect3DRMFrame_GetChildren(pFrameP2, &frame_array);
1202 ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
1203 if (frame_array)
1205 count = IDirect3DRMFrameArray_GetSize(frame_array);
1206 ok(count == 1, "count = %u\n", count);
1207 hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1208 ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
1209 ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
1210 IDirect3DRMFrame_Release(pFrameTmp);
1211 IDirect3DRMFrameArray_Release(frame_array);
1214 frame_array = NULL;
1215 hr = IDirect3DRMFrame_GetChildren(pFrameP1, &frame_array);
1216 ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
1217 if (frame_array)
1219 count = IDirect3DRMFrameArray_GetSize(frame_array);
1220 ok(count == 0, "count = %u\n", count);
1221 pFrameTmp = (void*)0xdeadbeef;
1222 hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1223 ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE (hr = %x)\n", hr);
1224 ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1225 IDirect3DRMFrameArray_Release(frame_array);
1227 hr = IDirect3DRMFrame_GetScene(pFrameC, &scene_frame);
1228 ok(SUCCEEDED(hr), "Cannot get scene (hr == %#x).\n", hr);
1229 ok(scene_frame == pFrameP2, "Expected scene frame == %p, got %p.\n", pFrameP2, scene_frame);
1230 CHECK_REFCOUNT(pFrameP2, 2);
1231 IDirect3DRMFrame_Release(scene_frame);
1232 hr = IDirect3DRMFrame_GetScene(pFrameP2, &scene_frame);
1233 ok(SUCCEEDED(hr), "Cannot get scene (hr == %#x).\n", hr);
1234 ok(scene_frame == pFrameP2, "Expected scene frame == %p, got %p.\n", pFrameP2, scene_frame);
1235 CHECK_REFCOUNT(pFrameP2, 2);
1236 IDirect3DRMFrame_Release(scene_frame);
1238 pFrameTmp = (void*)0xdeadbeef;
1239 hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
1240 ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
1241 ok(pFrameTmp == pFrameP2, "pFrameTmp = %p\n", pFrameTmp);
1242 CHECK_REFCOUNT(pFrameP2, 2);
1243 CHECK_REFCOUNT(pFrameC, 2);
1244 IDirect3DRMFrame_Release(pFrameTmp);
1245 CHECK_REFCOUNT(pFrameP2, 1);
1247 /* Add child again */
1248 hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameC);
1249 ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
1250 CHECK_REFCOUNT(pFrameC, 2);
1252 frame_array = NULL;
1253 hr = IDirect3DRMFrame_GetChildren(pFrameP2, &frame_array);
1254 ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
1255 if (frame_array)
1257 count = IDirect3DRMFrameArray_GetSize(frame_array);
1258 ok(count == 1, "count = %u\n", count);
1259 hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1260 ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
1261 ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
1262 IDirect3DRMFrame_Release(pFrameTmp);
1263 IDirect3DRMFrameArray_Release(frame_array);
1266 /* Delete child */
1267 hr = IDirect3DRMFrame_DeleteChild(pFrameP2, pFrameC);
1268 ok(hr == D3DRM_OK, "Cannot delete child frame (hr = %x)\n", hr);
1269 CHECK_REFCOUNT(pFrameC, 1);
1271 frame_array = NULL;
1272 hr = IDirect3DRMFrame_GetChildren(pFrameP2, &frame_array);
1273 ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
1274 if (frame_array)
1276 count = IDirect3DRMFrameArray_GetSize(frame_array);
1277 ok(count == 0, "count = %u\n", count);
1278 pFrameTmp = (void*)0xdeadbeef;
1279 hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1280 ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE (hr = %x)\n", hr);
1281 ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1282 IDirect3DRMFrameArray_Release(frame_array);
1285 pFrameTmp = (void*)0xdeadbeef;
1286 hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
1287 ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
1288 ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1290 /* Add two children */
1291 hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameC);
1292 ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
1293 CHECK_REFCOUNT(pFrameC, 2);
1295 hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameP1);
1296 ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
1297 CHECK_REFCOUNT(pFrameP1, 2);
1299 frame_array = NULL;
1300 hr = IDirect3DRMFrame_GetChildren(pFrameP2, &frame_array);
1301 ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr);
1302 if (frame_array)
1304 count = IDirect3DRMFrameArray_GetSize(frame_array);
1305 ok(count == 2, "count = %u\n", count);
1306 hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1307 ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
1308 ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
1309 IDirect3DRMFrame_Release(pFrameTmp);
1310 hr = IDirect3DRMFrameArray_GetElement(frame_array, 1, &pFrameTmp);
1311 ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
1312 ok(pFrameTmp == pFrameP1, "pFrameTmp = %p\n", pFrameTmp);
1313 IDirect3DRMFrame_Release(pFrameTmp);
1314 IDirect3DRMFrameArray_Release(frame_array);
1317 /* [Add/Delete]Visual with NULL pointer */
1318 hr = IDirect3DRMFrame_AddVisual(pFrameP1, NULL);
1319 ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
1320 CHECK_REFCOUNT(pFrameP1, 2);
1322 hr = IDirect3DRMFrame_DeleteVisual(pFrameP1, NULL);
1323 ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
1324 CHECK_REFCOUNT(pFrameP1, 2);
1326 /* Create Visual */
1327 hr = IDirect3DRM_CreateMeshBuilder(d3drm, &mesh_builder);
1328 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder interface (hr = %x)\n", hr);
1329 visual1 = (IDirect3DRMVisual *)mesh_builder;
1331 /* Add Visual to first parent */
1332 hr = IDirect3DRMFrame_AddVisual(pFrameP1, visual1);
1333 ok(hr == D3DRM_OK, "Cannot add visual (hr = %x)\n", hr);
1334 CHECK_REFCOUNT(pFrameP1, 2);
1335 CHECK_REFCOUNT(visual1, 2);
1337 visual_array = NULL;
1338 hr = IDirect3DRMFrame_GetVisuals(pFrameP1, &visual_array);
1339 ok(hr == D3DRM_OK, "Cannot get visuals (hr = %x)\n", hr);
1340 if (visual_array)
1342 count = IDirect3DRMVisualArray_GetSize(visual_array);
1343 ok(count == 1, "count = %u\n", count);
1344 hr = IDirect3DRMVisualArray_GetElement(visual_array, 0, &visual_tmp);
1345 ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
1346 ok(visual_tmp == visual1, "visual_tmp = %p\n", visual_tmp);
1347 IDirect3DRMVisual_Release(visual_tmp);
1348 IDirect3DRMVisualArray_Release(visual_array);
1351 /* Delete Visual */
1352 hr = IDirect3DRMFrame_DeleteVisual(pFrameP1, visual1);
1353 ok(hr == D3DRM_OK, "Cannot delete visual (hr = %x)\n", hr);
1354 CHECK_REFCOUNT(pFrameP1, 2);
1355 IDirect3DRMMeshBuilder_Release(mesh_builder);
1357 /* [Add/Delete]Light with NULL pointer */
1358 hr = IDirect3DRMFrame_AddLight(pFrameP1, NULL);
1359 ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
1360 CHECK_REFCOUNT(pFrameP1, 2);
1362 hr = IDirect3DRMFrame_DeleteLight(pFrameP1, NULL);
1363 ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
1364 CHECK_REFCOUNT(pFrameP1, 2);
1366 /* Create Light */
1367 hr = IDirect3DRM_CreateLightRGB(d3drm, D3DRMLIGHT_SPOT, 0.1, 0.2, 0.3, &light1);
1368 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMLight interface (hr = %x)\n", hr);
1370 /* Add Light to first parent */
1371 hr = IDirect3DRMFrame_AddLight(pFrameP1, light1);
1372 ok(hr == D3DRM_OK, "Cannot add light (hr = %x)\n", hr);
1373 CHECK_REFCOUNT(pFrameP1, 2);
1374 CHECK_REFCOUNT(light1, 2);
1376 light_array = NULL;
1377 hr = IDirect3DRMFrame_GetLights(pFrameP1, &light_array);
1378 ok(hr == D3DRM_OK, "Cannot get lights (hr = %x)\n", hr);
1379 if (light_array)
1381 count = IDirect3DRMLightArray_GetSize(light_array);
1382 ok(count == 1, "count = %u\n", count);
1383 hr = IDirect3DRMLightArray_GetElement(light_array, 0, &light_tmp);
1384 ok(hr == D3DRM_OK, "Cannot get element (hr = %x)\n", hr);
1385 ok(light_tmp == light1, "light_tmp = %p\n", light_tmp);
1386 IDirect3DRMLight_Release(light_tmp);
1387 IDirect3DRMLightArray_Release(light_array);
1390 /* Delete Light */
1391 hr = IDirect3DRMFrame_DeleteLight(pFrameP1, light1);
1392 ok(hr == D3DRM_OK, "Cannot delete light (hr = %x)\n", hr);
1393 CHECK_REFCOUNT(pFrameP1, 2);
1394 IDirect3DRMLight_Release(light1);
1396 /* Test SceneBackground on first parent */
1397 color = IDirect3DRMFrame_GetSceneBackground(pFrameP1);
1398 ok(color == 0xff000000, "wrong color (%x)\n", color);
1400 hr = IDirect3DRMFrame_SetSceneBackground(pFrameP1, 0xff180587);
1401 ok(hr == D3DRM_OK, "Cannot set color (hr = %x)\n", hr);
1402 color = IDirect3DRMFrame_GetSceneBackground(pFrameP1);
1403 ok(color == 0xff180587, "wrong color (%x)\n", color);
1405 hr = IDirect3DRMFrame_SetSceneBackgroundRGB(pFrameP1, 0.5, 0.5, 0.5);
1406 ok(hr == D3DRM_OK, "Cannot set color (hr = %x)\n", hr);
1407 color = IDirect3DRMFrame_GetSceneBackground(pFrameP1);
1408 ok(color == 0xff7f7f7f, "wrong color (%x)\n", color);
1410 /* Traversal options. */
1411 hr = IDirect3DRMFrame_QueryInterface(pFrameP2, &IID_IDirect3DRMFrame3, (void **)&frame3);
1412 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMFrame3 interface, hr %#x.\n", hr);
1414 hr = IDirect3DRMFrame3_GetTraversalOptions(frame3, NULL);
1415 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#x.\n", hr);
1417 options = 0;
1418 hr = IDirect3DRMFrame3_GetTraversalOptions(frame3, &options);
1419 ok(SUCCEEDED(hr), "Failed to get traversal options, hr %#x.\n", hr);
1420 ok(options == (D3DRMFRAME_RENDERENABLE | D3DRMFRAME_PICKENABLE), "Unexpected default options %#x.\n", options);
1422 hr = IDirect3DRMFrame3_SetTraversalOptions(frame3, 0);
1423 ok(SUCCEEDED(hr), "Unexpected hr %#x.\n", hr);
1425 hr = IDirect3DRMFrame3_SetTraversalOptions(frame3, 0xf0000000);
1426 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#x.\n", hr);
1428 hr = IDirect3DRMFrame3_SetTraversalOptions(frame3, 0xf0000000 | D3DRMFRAME_PICKENABLE);
1429 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#x.\n", hr);
1431 options = 0xf;
1432 hr = IDirect3DRMFrame3_GetTraversalOptions(frame3, &options);
1433 ok(SUCCEEDED(hr), "Failed to get traversal options, hr %#x.\n", hr);
1434 ok(options == 0, "Unexpected traversal options %#x.\n", options);
1436 hr = IDirect3DRMFrame3_SetTraversalOptions(frame3, D3DRMFRAME_PICKENABLE);
1437 ok(SUCCEEDED(hr), "Failed to set traversal options, hr %#x.\n", hr);
1439 options = 0;
1440 hr = IDirect3DRMFrame3_GetTraversalOptions(frame3, &options);
1441 ok(SUCCEEDED(hr), "Failed to get traversal options, hr %#x.\n", hr);
1442 ok(options == D3DRMFRAME_PICKENABLE, "Unexpected traversal options %#x.\n", options);
1444 IDirect3DRMFrame3_Release(frame3);
1446 /* Cleanup */
1447 IDirect3DRMFrame_Release(pFrameP2);
1448 CHECK_REFCOUNT(pFrameC, 1);
1449 CHECK_REFCOUNT(pFrameP1, 1);
1451 IDirect3DRMFrame_Release(pFrameC);
1452 IDirect3DRMFrame_Release(pFrameP1);
1454 IDirect3DRM_Release(d3drm);
1457 struct destroy_context
1459 IDirect3DRMObject *obj;
1460 unsigned int test_idx;
1461 int called;
1464 struct callback_order
1466 void *callback;
1467 void *context;
1468 } corder[3], d3drm_corder[3];
1470 static void CDECL destroy_callback(IDirect3DRMObject *obj, void *arg)
1472 struct destroy_context *ctxt = arg;
1473 ok(ctxt->called == 1 || ctxt->called == 2, "got called counter %d\n", ctxt->called);
1474 ok(obj == ctxt->obj, "called with %p, expected %p\n", obj, ctxt->obj);
1475 d3drm_corder[ctxt->called].callback = &destroy_callback;
1476 d3drm_corder[ctxt->called++].context = ctxt;
1479 static void CDECL destroy_callback1(IDirect3DRMObject *obj, void *arg)
1481 struct destroy_context *ctxt = (struct destroy_context*)arg;
1482 ok(ctxt->called == 0, "got called counter %d\n", ctxt->called);
1483 ok(obj == ctxt->obj, "called with %p, expected %p\n", obj, ctxt->obj);
1484 d3drm_corder[ctxt->called].callback = &destroy_callback1;
1485 d3drm_corder[ctxt->called++].context = ctxt;
1488 static void test_destroy_callback(unsigned int test_idx, REFCLSID clsid, REFIID iid)
1490 struct destroy_context context;
1491 IDirect3DRMObject *obj;
1492 IUnknown *unknown;
1493 IDirect3DRM *d3drm;
1494 HRESULT hr;
1495 int i;
1497 hr = Direct3DRMCreate(&d3drm);
1498 ok(SUCCEEDED(hr), "Test %u: Cannot get IDirect3DRM interface (hr = %x).\n", test_idx, hr);
1500 hr = IDirect3DRM_CreateObject(d3drm, clsid, NULL, iid, (void **)&unknown);
1501 ok(hr == D3DRM_OK, "Test %u: Cannot get IDirect3DRMObject interface (hr = %x).\n", test_idx, hr);
1502 hr = IUnknown_QueryInterface(unknown, &IID_IDirect3DRMObject, (void**)&obj);
1503 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1504 IUnknown_Release(unknown);
1506 context.called = 0;
1507 context.test_idx = test_idx;
1508 context.obj = obj;
1510 hr = IDirect3DRMObject_AddDestroyCallback(obj, NULL, &context);
1511 ok(hr == D3DRMERR_BADVALUE, "Test %u: expected D3DRMERR_BADVALUE (hr = %x).\n", test_idx, hr);
1513 hr = IDirect3DRMObject_AddDestroyCallback(obj, destroy_callback, &context);
1514 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1515 corder[2].callback = &destroy_callback;
1516 corder[2].context = &context;
1518 /* same callback added twice */
1519 hr = IDirect3DRMObject_AddDestroyCallback(obj, destroy_callback, &context);
1520 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1521 corder[1].callback = &destroy_callback;
1522 corder[1].context = &context;
1524 hr = IDirect3DRMObject_DeleteDestroyCallback(obj, destroy_callback1, NULL);
1525 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1527 hr = IDirect3DRMObject_DeleteDestroyCallback(obj, destroy_callback1, &context);
1528 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1530 /* add one more */
1531 hr = IDirect3DRMObject_AddDestroyCallback(obj, destroy_callback1, &context);
1532 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1533 corder[0].callback = &destroy_callback1;
1534 corder[0].context = &context;
1536 hr = IDirect3DRMObject_DeleteDestroyCallback(obj, NULL, NULL);
1537 ok(hr == D3DRMERR_BADVALUE, "Test %u: expected D3DRM_BADVALUE (hr = %x).\n", test_idx, hr);
1539 context.called = 0;
1540 IDirect3DRMObject_Release(obj);
1541 ok(context.called == 3, "Test %u: got %d, expected 3.\n", test_idx, context.called);
1542 for (i = 0; i < context.called; i++)
1544 ok(corder[i].callback == d3drm_corder[i].callback
1545 && corder[i].context == d3drm_corder[i].context,
1546 "Expected callback = %p, context = %p. Got callback = %p, context = %p.\n", d3drm_corder[i].callback,
1547 d3drm_corder[i].context, corder[i].callback, corder[i].context);
1550 /* test this pattern - add cb1, add cb2, add cb1, delete cb1 */
1551 hr = IDirect3DRM_CreateObject(d3drm, clsid, NULL, iid, (void **)&unknown);
1552 ok(hr == D3DRM_OK, "Test %u: Cannot get IDirect3DRMObject interface (hr = %x).\n", test_idx, hr);
1553 hr = IUnknown_QueryInterface(unknown, &IID_IDirect3DRMObject, (void**)&obj);
1554 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1555 IUnknown_Release(unknown);
1557 hr = IDirect3DRMObject_AddDestroyCallback(obj, destroy_callback, &context);
1558 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1559 corder[1].callback = &destroy_callback;
1560 corder[1].context = &context;
1562 hr = IDirect3DRMObject_AddDestroyCallback(obj, destroy_callback1, &context);
1563 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1564 corder[0].callback = &destroy_callback1;
1565 corder[0].context = &context;
1567 hr = IDirect3DRMObject_AddDestroyCallback(obj, destroy_callback, &context);
1568 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1570 hr = IDirect3DRMObject_DeleteDestroyCallback(obj, destroy_callback, &context);
1571 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1573 context.called = 0;
1574 hr = IDirect3DRMObject_QueryInterface(obj, &IID_IDirect3DRMObject, (void**)&context.obj);
1575 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK (hr = %x).\n", test_idx, hr);
1576 IDirect3DRMObject_Release(context.obj);
1577 IUnknown_Release(unknown);
1578 ok(context.called == 2, "Test %u: got %d, expected 2.\n", test_idx, context.called);
1579 for (i = 0; i < context.called; i++)
1581 ok(corder[i].callback == d3drm_corder[i].callback
1582 && corder[i].context == d3drm_corder[i].context,
1583 "Expected callback = %p, context = %p. Got callback = %p, context = %p.\n", d3drm_corder[i].callback,
1584 d3drm_corder[i].context, corder[i].callback, corder[i].context);
1587 IDirect3DRM_Release(d3drm);
1590 static void test_object(void)
1592 static const struct
1594 REFCLSID clsid;
1595 REFIID iid;
1596 BOOL takes_d3drm_ref;
1598 tests[] =
1600 { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMDevice },
1601 { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMDevice2 },
1602 { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMDevice3 },
1603 { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMWinDevice },
1604 { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture },
1605 { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture2 },
1606 { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture3 },
1607 { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport },
1608 { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport2 },
1609 { &CLSID_CDirect3DRMFace, &IID_IDirect3DRMFace },
1610 { &CLSID_CDirect3DRMFace, &IID_IDirect3DRMFace2 },
1611 { &CLSID_CDirect3DRMMeshBuilder, &IID_IDirect3DRMMeshBuilder, TRUE },
1612 { &CLSID_CDirect3DRMMeshBuilder, &IID_IDirect3DRMMeshBuilder2, TRUE },
1613 { &CLSID_CDirect3DRMMeshBuilder, &IID_IDirect3DRMMeshBuilder3, TRUE },
1614 { &CLSID_CDirect3DRMFrame, &IID_IDirect3DRMFrame, TRUE },
1615 { &CLSID_CDirect3DRMFrame, &IID_IDirect3DRMFrame2, TRUE },
1616 { &CLSID_CDirect3DRMFrame, &IID_IDirect3DRMFrame3, TRUE },
1617 { &CLSID_CDirect3DRMLight, &IID_IDirect3DRMLight, TRUE },
1618 { &CLSID_CDirect3DRMMaterial, &IID_IDirect3DRMMaterial, TRUE },
1619 { &CLSID_CDirect3DRMMaterial, &IID_IDirect3DRMMaterial2, TRUE },
1620 { &CLSID_CDirect3DRMMesh, &IID_IDirect3DRMMesh, TRUE },
1621 { &CLSID_CDirect3DRMAnimation, &IID_IDirect3DRMAnimation, TRUE },
1622 { &CLSID_CDirect3DRMAnimation, &IID_IDirect3DRMAnimation2, TRUE },
1623 { &CLSID_CDirect3DRMWrap, &IID_IDirect3DRMWrap },
1625 IDirect3DRM *d3drm1;
1626 IDirect3DRM2 *d3drm2;
1627 IDirect3DRM3 *d3drm3;
1628 IUnknown *unknown = (IUnknown *)0xdeadbeef;
1629 HRESULT hr;
1630 ULONG ref1, ref2, ref3, ref4;
1631 int i;
1633 hr = Direct3DRMCreate(&d3drm1);
1634 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface (hr = %#x).\n", hr);
1635 ref1 = get_refcount((IUnknown *)d3drm1);
1636 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
1637 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface (hr = %#x).\n", hr);
1638 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
1639 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface (hr = %#x).\n", hr);
1641 hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_DirectDraw, NULL, &IID_IDirectDraw, (void **)&unknown);
1642 ok(hr == CLASSFACTORY_E_FIRST, "Expected hr == CLASSFACTORY_E_FIRST, got %#x.\n", hr);
1643 ok(!unknown, "Expected object returned == NULL, got %p.\n", unknown);
1645 for (i = 0; i < ARRAY_SIZE(tests); ++i)
1647 unknown = (IUnknown *)0xdeadbeef;
1648 hr = IDirect3DRM_CreateObject(d3drm1, NULL, NULL, tests[i].iid, (void **)&unknown);
1649 ok(hr == D3DRMERR_BADVALUE, "Test %u: expected hr == D3DRMERR_BADVALUE, got %#x.\n", i, hr);
1650 ok(!unknown, "Expected object returned == NULL, got %p.\n", unknown);
1651 unknown = (IUnknown *)0xdeadbeef;
1652 hr = IDirect3DRM_CreateObject(d3drm1, tests[i].clsid, NULL, NULL, (void **)&unknown);
1653 ok(hr == D3DRMERR_BADVALUE, "Test %u: expected hr == D3DRMERR_BADVALUE, got %#x.\n", i, hr);
1654 ok(!unknown, "Expected object returned == NULL, got %p.\n", unknown);
1655 hr = IDirect3DRM_CreateObject(d3drm1, tests[i].clsid, NULL, NULL, NULL);
1656 ok(hr == D3DRMERR_BADVALUE, "Test %u: expected hr == D3DRMERR_BADVALUE, got %#x.\n", i, hr);
1658 hr = IDirect3DRM_CreateObject(d3drm1, tests[i].clsid, NULL, tests[i].iid, (void **)&unknown);
1659 ok(SUCCEEDED(hr), "Test %u: expected hr == D3DRM_OK, got %#x.\n", i, hr);
1660 if (SUCCEEDED(hr))
1662 ref2 = get_refcount((IUnknown *)d3drm1);
1663 if (tests[i].takes_d3drm_ref)
1664 ok(ref2 > ref1, "Test %u: expected ref2 > ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1665 else
1666 ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1668 ref3 = get_refcount((IUnknown *)d3drm2);
1669 ok(ref3 == ref1, "Test %u: expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", i, ref1, ref3);
1670 ref4 = get_refcount((IUnknown *)d3drm3);
1671 ok(ref4 == ref1, "Test %u: expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", i, ref1, ref4);
1672 IUnknown_Release(unknown);
1673 ref2 = get_refcount((IUnknown *)d3drm1);
1674 ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1675 ref3 = get_refcount((IUnknown *)d3drm2);
1676 ok(ref3 == ref1, "Test %u: expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", i, ref1, ref3);
1677 ref4 = get_refcount((IUnknown *)d3drm3);
1678 ok(ref4 == ref1, "Test %u: expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", i, ref1, ref4);
1680 /* test Add/Destroy callbacks */
1681 test_destroy_callback(i, tests[i].clsid, tests[i].iid);
1683 hr = IDirect3DRM2_CreateObject(d3drm2, tests[i].clsid, NULL, tests[i].iid, (void **)&unknown);
1684 ok(SUCCEEDED(hr), "Test %u: expected hr == D3DRM_OK, got %#x.\n", i, hr);
1685 ref2 = get_refcount((IUnknown *)d3drm1);
1686 if (tests[i].takes_d3drm_ref)
1687 ok(ref2 > ref1, "Test %u: expected ref2 > ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1688 else
1689 ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1690 ref3 = get_refcount((IUnknown *)d3drm2);
1691 ok(ref3 == ref1, "Test %u: expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", i, ref1, ref3);
1692 ref4 = get_refcount((IUnknown *)d3drm3);
1693 ok(ref4 == ref1, "Test %u: expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", i, ref1, ref4);
1694 IUnknown_Release(unknown);
1695 ref2 = get_refcount((IUnknown *)d3drm1);
1696 ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1697 ref3 = get_refcount((IUnknown *)d3drm2);
1698 ok(ref3 == ref1, "Test %u: expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", i, ref1, ref3);
1699 ref4 = get_refcount((IUnknown *)d3drm3);
1700 ok(ref4 == ref1, "Test %u: expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", i, ref1, ref4);
1702 hr = IDirect3DRM3_CreateObject(d3drm3, tests[i].clsid, NULL, tests[i].iid, (void **)&unknown);
1703 ok(SUCCEEDED(hr), "Test %u: expected hr == D3DRM_OK, got %#x.\n", i, hr);
1704 ref2 = get_refcount((IUnknown *)d3drm1);
1705 if (tests[i].takes_d3drm_ref)
1706 ok(ref2 > ref1, "Test %u: expected ref2 > ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1707 else
1708 ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1709 ref3 = get_refcount((IUnknown *)d3drm2);
1710 ok(ref3 == ref1, "Test %u: expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", i, ref1, ref3);
1711 ref4 = get_refcount((IUnknown *)d3drm3);
1712 ok(ref4 == ref1, "Test %u: expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", i, ref1, ref4);
1713 IUnknown_Release(unknown);
1714 ref2 = get_refcount((IUnknown *)d3drm1);
1715 ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
1716 ref3 = get_refcount((IUnknown *)d3drm2);
1717 ok(ref3 == ref1, "Test %u: expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", i, ref1, ref3);
1718 ref4 = get_refcount((IUnknown *)d3drm3);
1719 ok(ref4 == ref1, "Test %u: expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", i, ref1, ref4);
1723 IDirect3DRM_Release(d3drm1);
1724 IDirect3DRM2_Release(d3drm2);
1725 IDirect3DRM3_Release(d3drm3);
1728 static void test_Viewport(void)
1730 IDirect3DRMFrame3 *frame3, *d3drm_frame3, *tmp_frame3;
1731 IDirect3DRMFrame *frame, *d3drm_frame, *tmp_frame1;
1732 float field, left, top, right, bottom, front, back;
1733 D3DRMPROJECTIONTYPE projection;
1734 IDirectDrawClipper *clipper;
1735 HRESULT hr;
1736 IDirect3DRM *d3drm1;
1737 IDirect3DRM2 *d3drm2;
1738 IDirect3DRM3 *d3drm3;
1739 IDirect3DRMDevice *device1, *d3drm_device1;
1740 IDirect3DRMDevice3 *device3, *d3drm_device3;
1741 IDirect3DRMViewport *viewport;
1742 IDirect3DRMViewport2 *viewport2;
1743 IDirect3DViewport *d3d_viewport;
1744 D3DVIEWPORT vp;
1745 D3DVALUE expected_val;
1746 IDirect3DRMObject *obj, *obj2;
1747 GUID driver;
1748 HWND window;
1749 RECT rc;
1750 DWORD data, ref1, ref2, ref3, ref4;
1751 DWORD initial_ref1, initial_ref2, initial_ref3, device_ref, frame_ref, frame_ref2, viewport_ref;
1753 window = create_window();
1754 GetClientRect(window, &rc);
1756 hr = Direct3DRMCreate(&d3drm1);
1757 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
1758 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
1759 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface (hr = %#x).\n", hr);
1760 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
1761 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface (hr = %#x).\n", hr);
1762 initial_ref1 = get_refcount((IUnknown *)d3drm1);
1763 initial_ref2 = get_refcount((IUnknown *)d3drm2);
1764 initial_ref3 = get_refcount((IUnknown *)d3drm3);
1766 hr = DirectDrawCreateClipper(0, &clipper, NULL);
1767 ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface (hr = %x)\n", hr);
1769 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
1770 ok(hr == DD_OK, "Cannot set HWnd to Clipper (hr = %x)\n", hr);
1772 memcpy(&driver, &IID_IDirect3DRGBDevice, sizeof(GUID));
1773 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, rc.right, rc.bottom, &device3);
1774 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMDevice interface (hr = %x)\n", hr);
1775 hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice, (void **)&device1);
1776 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface (hr = %#x).\n", hr);
1778 hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &frame);
1779 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr);
1780 hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &tmp_frame1);
1781 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
1782 hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &frame3);
1783 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame3 interface (hr = %x).\n", hr);
1784 hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &tmp_frame3);
1785 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
1787 ref1 = get_refcount((IUnknown *)d3drm1);
1788 ref2 = get_refcount((IUnknown *)d3drm2);
1789 ref3 = get_refcount((IUnknown *)d3drm3);
1790 device_ref = get_refcount((IUnknown *)device1);
1791 frame_ref = get_refcount((IUnknown *)frame);
1793 hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, 0, 0, 0, 0, &viewport);
1794 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport interface (hr = %#x)\n", hr);
1795 ref4 = get_refcount((IUnknown *)d3drm1);
1796 ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
1797 ref4 = get_refcount((IUnknown *)d3drm2);
1798 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
1799 ref4 = get_refcount((IUnknown *)d3drm3);
1800 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
1801 ref4 = get_refcount((IUnknown *)device1);
1802 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
1803 ref4 = get_refcount((IUnknown *)frame);
1804 ok(ref4 > frame_ref, "Expected ref4 > frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4);
1806 hr = IDirect3DRMViewport_GetDevice(viewport, &d3drm_device1);
1807 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface (hr = %x)\n", hr);
1808 ok(device1 == d3drm_device1, "Expected device returned = %p, got %p.\n", device1, d3drm_device1);
1809 IDirect3DRMDevice_Release(d3drm_device1);
1811 hr = IDirect3DRMViewport_SetCamera(viewport, NULL);
1812 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
1813 hr = IDirect3DRMViewport_GetCamera(viewport, &d3drm_frame);
1814 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
1815 ok(frame == d3drm_frame, "Expected frame returned = %p, got %p.\n", frame, d3drm_frame);
1816 IDirect3DRMFrame_Release(d3drm_frame);
1818 hr = IDirect3DRMViewport_SetCamera(viewport, tmp_frame1);
1819 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
1820 hr = IDirect3DRMViewport_GetCamera(viewport, &d3drm_frame);
1821 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
1822 ok(d3drm_frame == tmp_frame1, "Got unexpected frame %p, expected %p.\n", d3drm_frame, tmp_frame1);
1823 IDirect3DRMFrame_Release(d3drm_frame);
1825 IDirect3DRMViewport_Release(viewport);
1826 ref4 = get_refcount((IUnknown *)d3drm1);
1827 ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
1828 ref4 = get_refcount((IUnknown *)d3drm2);
1829 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
1830 ref4 = get_refcount((IUnknown *)d3drm3);
1831 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
1832 ref4 = get_refcount((IUnknown *)device1);
1833 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
1834 ref4 = get_refcount((IUnknown *)frame);
1835 ok(ref4 == frame_ref, "Expected ref4 == frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4);
1837 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, 0, 0, 0, 0, &viewport);
1838 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport interface (hr = %#x)\n", hr);
1839 ref4 = get_refcount((IUnknown *)d3drm1);
1840 ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
1841 ref4 = get_refcount((IUnknown *)d3drm2);
1842 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
1843 ref4 = get_refcount((IUnknown *)d3drm3);
1844 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
1845 ref4 = get_refcount((IUnknown *)device1);
1846 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
1847 ref4 = get_refcount((IUnknown *)frame);
1848 ok(ref4 > frame_ref, "Expected ref4 > frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4);
1850 hr = IDirect3DRMViewport_GetDevice(viewport, &d3drm_device1);
1851 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface (hr = %x)\n", hr);
1852 ok(device1 == d3drm_device1, "Expected device returned = %p, got %p.\n", device1, d3drm_device1);
1853 IDirect3DRMDevice_Release(d3drm_device1);
1855 hr = IDirect3DRMViewport_SetCamera(viewport, NULL);
1856 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
1857 hr = IDirect3DRMViewport_GetCamera(viewport, &d3drm_frame);
1858 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
1859 ok(frame == d3drm_frame, "Expected frame returned = %p, got %p.\n", frame, d3drm_frame);
1860 IDirect3DRMFrame_Release(d3drm_frame);
1862 hr = IDirect3DRMViewport_SetCamera(viewport, tmp_frame1);
1863 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
1864 hr = IDirect3DRMViewport_GetCamera(viewport, &d3drm_frame);
1865 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
1866 ok(d3drm_frame == tmp_frame1, "Got unexpected frame %p, expected %p.\n", d3drm_frame, tmp_frame1);
1867 IDirect3DRMFrame_Release(d3drm_frame);
1869 IDirect3DRMViewport_Release(viewport);
1870 ref4 = get_refcount((IUnknown *)d3drm1);
1871 ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
1872 ref4 = get_refcount((IUnknown *)d3drm2);
1873 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
1874 ref4 = get_refcount((IUnknown *)d3drm3);
1875 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
1876 ref4 = get_refcount((IUnknown *)device1);
1877 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
1878 ref4 = get_refcount((IUnknown *)frame);
1879 ok(ref4 == frame_ref, "Expected ref4 == frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4);
1881 device_ref = get_refcount((IUnknown *)device3);
1882 frame_ref2 = get_refcount((IUnknown *)frame3);
1884 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, 0, 0, 0, 0, &viewport2);
1885 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport2 interface (hr = %#x)\n", hr);
1886 ref4 = get_refcount((IUnknown *)d3drm1);
1887 ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
1888 ref4 = get_refcount((IUnknown *)d3drm2);
1889 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
1890 ref4 = get_refcount((IUnknown *)d3drm3);
1891 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
1892 ref4 = get_refcount((IUnknown *)device3);
1893 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
1894 ref4 = get_refcount((IUnknown *)frame3);
1895 ok(ref4 > frame_ref2, "Expected ref4 > frame_ref2, got frame_ref2 = %u, ref4 = %u.\n", frame_ref2, ref4);
1897 hr = IDirect3DRMViewport2_GetDevice(viewport2, &d3drm_device3);
1898 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface (hr = %x)\n", hr);
1899 ok(device3 == d3drm_device3, "Expected device returned = %p, got %p.\n", device3, d3drm_device3);
1900 IDirect3DRMDevice3_Release(d3drm_device3);
1902 hr = IDirect3DRMViewport2_SetCamera(viewport2, NULL);
1903 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
1904 hr = IDirect3DRMViewport2_GetCamera(viewport2, &d3drm_frame3);
1905 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
1906 ok(frame3 == d3drm_frame3, "Expected frame returned = %p, got %p.\n", frame3, d3drm_frame3);
1907 IDirect3DRMFrame3_Release(d3drm_frame3);
1909 hr = IDirect3DRMViewport2_SetCamera(viewport2, tmp_frame3);
1910 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
1911 hr = IDirect3DRMViewport2_GetCamera(viewport2, &d3drm_frame3);
1912 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
1913 ok(d3drm_frame3 == tmp_frame3, "Got unexpected frame %p, expected %p.\n", d3drm_frame3, tmp_frame3);
1914 IDirect3DRMFrame3_Release(d3drm_frame3);
1916 IDirect3DRMViewport2_Release(viewport2);
1917 ref4 = get_refcount((IUnknown *)d3drm1);
1918 ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
1919 ref4 = get_refcount((IUnknown *)d3drm2);
1920 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
1921 ref4 = get_refcount((IUnknown *)d3drm3);
1922 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
1923 ref4 = get_refcount((IUnknown *)device3);
1924 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
1925 ref4 = get_refcount((IUnknown *)frame3);
1926 ok(ref4 == frame_ref2, "Expected ref4 == frame_ref2, got frame_ref2 = %u, ref4 = %u.\n", frame_ref2, ref4);
1928 /* Test all failures together */
1929 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1930 hr = IDirect3DRM_CreateViewport(d3drm1, NULL, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1931 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
1932 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1933 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1934 hr = IDirect3DRM_CreateViewport(d3drm1, device1, NULL, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1935 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
1936 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1937 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1938 hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom + 1, &viewport);
1939 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1940 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1941 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1942 hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom, &viewport);
1943 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1944 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1945 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1946 hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right, rc.bottom + 1, &viewport);
1947 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1948 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1949 hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right, rc.bottom, NULL);
1950 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1952 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1953 hr = IDirect3DRM2_CreateViewport(d3drm2, NULL, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1954 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
1955 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1956 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1957 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, NULL, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1958 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
1959 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1960 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1961 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom + 1, &viewport);
1962 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1963 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1964 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1965 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom, &viewport);
1966 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1967 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1968 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1969 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right, rc.bottom + 1, &viewport);
1970 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1971 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1972 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right, rc.bottom, NULL);
1973 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1975 viewport2 = (IDirect3DRMViewport2 *)0xdeadbeef;
1976 hr = IDirect3DRM3_CreateViewport(d3drm3, NULL, frame3, rc.left, rc.top, rc.right, rc.bottom, &viewport2);
1977 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
1978 ok(!viewport2, "Expected viewport returned == NULL, got %p.\n", viewport2);
1979 viewport2 = (IDirect3DRMViewport2 *)0xdeadbeef;
1980 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, NULL, rc.left, rc.top, rc.right, rc.bottom, &viewport2);
1981 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
1982 ok(!viewport2, "Expected viewport returned == NULL, got %p.\n", viewport2);
1983 viewport2 = (IDirect3DRMViewport2 *)0xdeadbeef;
1984 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom + 1, &viewport2);
1985 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1986 ok(!viewport2, "Expected viewport returned == NULL, got %p.\n", viewport2);
1987 viewport2 = (IDirect3DRMViewport2 *)0xdeadbeef;
1988 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom, &viewport2);
1989 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1990 ok(!viewport2, "Expected viewport returned == NULL, got %p.\n", viewport2);
1991 viewport2 = (IDirect3DRMViewport2 *)0xdeadbeef;
1992 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right, rc.bottom + 1, &viewport2);
1993 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1994 ok(!viewport2, "Expected viewport returned == NULL, got %p.\n", viewport2);
1995 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right, rc.bottom, NULL);
1996 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
1998 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1999 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMViewport interface (hr = %#x)\n", hr);
2000 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2001 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2002 viewport_ref = get_refcount((IUnknown *)d3d_viewport);
2003 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2004 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2005 ref4 = get_refcount((IUnknown *)d3d_viewport);
2006 ok(ref4 > viewport_ref, "Expected ref4 > viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
2007 IDirect3DViewport_Release(d3d_viewport);
2008 ref4 = get_refcount((IUnknown *)d3d_viewport);
2009 ok(ref4 == viewport_ref, "Expected ref4 == viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
2010 IDirect3DViewport_Release(d3d_viewport);
2012 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2013 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2014 vp.dwSize = sizeof(vp);
2015 hr = IDirect3DViewport_GetViewport(d3d_viewport, &vp);
2016 ok(SUCCEEDED(hr), "Cannot get D3DVIEWPORT struct (hr = %#x).\n", hr);
2017 ok(vp.dwWidth == rc.right, "Expected viewport width = %u, got %u.\n", rc.right, vp.dwWidth);
2018 ok(vp.dwHeight == rc.bottom, "Expected viewport height = %u, got %u.\n", rc.bottom, vp.dwHeight);
2019 ok(vp.dwX == rc.left, "Expected viewport X position = %u, got %u.\n", rc.left, vp.dwX);
2020 ok(vp.dwY == rc.top, "Expected viewport Y position = %u, got %u.\n", rc.top, vp.dwY);
2021 expected_val = (rc.right > rc.bottom) ? (rc.right / 2.0f) : (rc.bottom / 2.0f);
2022 ok(vp.dvScaleX == expected_val, "Expected dvScaleX = %f, got %f.\n", expected_val, vp.dvScaleX);
2023 ok(vp.dvScaleY == expected_val, "Expected dvScaleY = %f, got %f.\n", expected_val, vp.dvScaleY);
2024 expected_val = vp.dwWidth / (2.0f * vp.dvScaleX);
2025 ok(vp.dvMaxX == expected_val, "Expected dvMaxX = %f, got %f.\n", expected_val, vp.dvMaxX);
2026 expected_val = vp.dwHeight / (2.0f * vp.dvScaleY);
2027 ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY);
2028 IDirect3DViewport_Release(d3d_viewport);
2029 IDirect3DRMViewport_Release(viewport);
2031 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right, rc.bottom, &viewport2);
2032 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMViewport2 interface (hr = %#x)\n", hr);
2033 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
2034 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2035 viewport_ref = get_refcount((IUnknown *)d3d_viewport);
2036 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
2037 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2038 ref4 = get_refcount((IUnknown *)d3d_viewport);
2039 ok(ref4 > viewport_ref, "Expected ref4 > viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
2040 IDirect3DViewport_Release(d3d_viewport);
2041 ref4 = get_refcount((IUnknown *)d3d_viewport);
2042 ok(ref4 == viewport_ref, "Expected ref4 == viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
2043 IDirect3DViewport_Release(d3d_viewport);
2045 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
2046 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2047 vp.dwSize = sizeof(vp);
2048 hr = IDirect3DViewport_GetViewport(d3d_viewport, &vp);
2049 ok(SUCCEEDED(hr), "Cannot get D3DVIEWPORT struct (hr = %#x).\n", hr);
2050 ok(vp.dwWidth == rc.right, "Expected viewport width = %u, got %u.\n", rc.right, vp.dwWidth);
2051 ok(vp.dwHeight == rc.bottom, "Expected viewport height = %u, got %u.\n", rc.bottom, vp.dwHeight);
2052 ok(vp.dwX == rc.left, "Expected viewport X position = %u, got %u.\n", rc.left, vp.dwX);
2053 ok(vp.dwY == rc.top, "Expected viewport Y position = %u, got %u.\n", rc.top, vp.dwY);
2054 expected_val = (rc.right > rc.bottom) ? (rc.right / 2.0f) : (rc.bottom / 2.0f);
2055 ok(vp.dvScaleX == expected_val, "Expected dvScaleX = %f, got %f.\n", expected_val, vp.dvScaleX);
2056 ok(vp.dvScaleY == expected_val, "Expected dvScaleY = %f, got %f.\n", expected_val, vp.dvScaleY);
2057 expected_val = vp.dwWidth / (2.0f * vp.dvScaleX);
2058 ok(vp.dvMaxX == expected_val, "Expected dvMaxX = %f, got %f.\n", expected_val, vp.dvMaxX);
2059 expected_val = vp.dwHeight / (2.0f * vp.dvScaleY);
2060 ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY);
2061 IDirect3DViewport_Release(d3d_viewport);
2062 IDirect3DRMViewport2_Release(viewport2);
2064 hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport);
2065 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMViewport interface (hr = %x)\n", hr);
2066 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2067 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2068 viewport_ref = get_refcount((IUnknown *)d3d_viewport);
2069 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2070 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2071 ref4 = get_refcount((IUnknown *)d3d_viewport);
2072 ok(ref4 > viewport_ref, "Expected ref4 > viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
2073 IDirect3DViewport_Release(d3d_viewport);
2074 ref4 = get_refcount((IUnknown *)d3d_viewport);
2075 ok(ref4 == viewport_ref, "Expected ref4 == viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
2076 IDirect3DViewport_Release(d3d_viewport);
2078 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2079 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2080 vp.dwSize = sizeof(vp);
2081 hr = IDirect3DViewport_GetViewport(d3d_viewport, &vp);
2082 ok(SUCCEEDED(hr), "Cannot get D3DVIEWPORT struct (hr = %#x).\n", hr);
2083 ok(vp.dwWidth == rc.right, "Expected viewport width = %u, got %u.\n", rc.right, vp.dwWidth);
2084 ok(vp.dwHeight == rc.bottom, "Expected viewport height = %u, got %u.\n", rc.bottom, vp.dwHeight);
2085 ok(vp.dwX == rc.left, "Expected viewport X position = %u, got %u.\n", rc.left, vp.dwX);
2086 ok(vp.dwY == rc.top, "Expected viewport Y position = %u, got %u.\n", rc.top, vp.dwY);
2087 expected_val = (rc.right > rc.bottom) ? (rc.right / 2.0f) : (rc.bottom / 2.0f);
2088 ok(vp.dvScaleX == expected_val, "Expected dvScaleX = %f, got %f.\n", expected_val, vp.dvScaleX);
2089 ok(vp.dvScaleY == expected_val, "Expected dvScaleY = %f, got %f.\n", expected_val, vp.dvScaleY);
2090 expected_val = vp.dwWidth / (2.0f * vp.dvScaleX);
2091 ok(vp.dvMaxX == expected_val, "Expected dvMaxX = %f, got %f.\n", expected_val, vp.dvMaxX);
2092 expected_val = vp.dwHeight / (2.0f * vp.dvScaleY);
2093 ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY);
2094 IDirect3DViewport_Release(d3d_viewport);
2096 hr = IDirect3DRMViewport_QueryInterface(viewport, &IID_IDirect3DRMObject, (void**)&obj);
2097 ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
2098 ok((IDirect3DRMObject*)viewport == obj, "got object pointer %p, expected %p\n", obj, viewport);
2100 hr = IDirect3DRMViewport_QueryInterface(viewport, &IID_IDirect3DRMViewport2, (void**)&viewport2);
2101 ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
2103 hr = IDirect3DRMViewport2_QueryInterface(viewport2, &IID_IDirect3DRMObject, (void**)&obj2);
2104 ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
2105 ok(obj == obj2, "got object pointer %p, expected %p\n", obj2, obj);
2106 ok((IUnknown*)viewport != (IUnknown*)viewport2, "got viewport1 %p, viewport2 %p\n", viewport, viewport2);
2108 IDirect3DRMViewport2_Release(viewport2);
2109 IDirect3DRMObject_Release(obj);
2110 IDirect3DRMObject_Release(obj2);
2112 test_class_name((IDirect3DRMObject *)viewport, "Viewport");
2113 test_object_name((IDirect3DRMObject *)viewport);
2115 /* AppData */
2116 hr = IDirect3DRMViewport_SetAppData(viewport, 0);
2117 ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
2119 hr = IDirect3DRMViewport_SetAppData(viewport, 0);
2120 ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
2122 hr = IDirect3DRMViewport_SetAppData(viewport, 1);
2123 ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
2125 hr = IDirect3DRMViewport_SetAppData(viewport, 1);
2126 ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
2128 hr = IDirect3DRMViewport_QueryInterface(viewport, &IID_IDirect3DRMViewport2, (void**)&viewport2);
2129 ok(hr == D3DRM_OK, "expected D3DRM_OK (hr = %x)\n", hr);
2131 data = IDirect3DRMViewport2_GetAppData(viewport2);
2132 ok(data == 1, "got %x\n", data);
2133 IDirect3DRMViewport2_Release(viewport2);
2134 IDirect3DRMViewport_Release(viewport);
2136 /* IDirect3DRMViewport*::Init tests */
2137 ref1 = get_refcount((IUnknown *)d3drm1);
2138 ref2 = get_refcount((IUnknown *)d3drm2);
2139 ref3 = get_refcount((IUnknown *)d3drm3);
2140 hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_CDirect3DRMViewport, NULL, &IID_IDirect3DRMViewport,
2141 (void **)&viewport);
2142 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport interface (hr = %#x).\n", hr);
2143 ref4 = get_refcount((IUnknown *)d3drm1);
2144 ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2145 ref4 = get_refcount((IUnknown *)d3drm2);
2146 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
2147 ref4 = get_refcount((IUnknown *)d3drm3);
2148 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
2150 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2151 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2152 hr = IDirect3DRMViewport_GetDevice(viewport, &d3drm_device1);
2153 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2154 hr = IDirect3DRMViewport_GetCamera(viewport, &d3drm_frame);
2155 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2156 field = IDirect3DRMViewport_GetField(viewport);
2157 ok(field == -1.0f, "Got unexpected field %.8e.\n", field);
2158 left = right = bottom = top = 10.0f;
2159 hr = IDirect3DRMViewport_GetPlane(viewport, &left, &right, &bottom, &top);
2160 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2161 ok(left == 10.0f, "Got unexpected left %.8e.\n", left);
2162 ok(right == 10.0f, "Got unexpected right %.8e.\n", right);
2163 ok(bottom == 10.0f, "Got unexpected bottom %.8e.\n", bottom);
2164 ok(top == 10.0f, "Got unexpected top %.8e.\n", top);
2165 front = IDirect3DRMViewport_GetFront(viewport);
2166 ok(front == -1.0f, "Got unexpected front %.8e\n", front);
2167 back = IDirect3DRMViewport_GetBack(viewport);
2168 ok(back == -1.0f, "Got unexpected back %.8e\n", back);
2169 projection = IDirect3DRMViewport_GetProjection(viewport);
2170 ok(projection == ~0u, "Got unexpected projection type %#x.\n", projection);
2172 hr = IDirect3DRMViewport_SetCamera(viewport, frame);
2173 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2174 hr = IDirect3DRMViewport_SetField(viewport, 0.5f);
2175 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2176 hr = IDirect3DRMViewport_SetPlane(viewport, -0.5f, 0.5f, -0.5f, 0.5f);
2177 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2178 hr = IDirect3DRMViewport_SetFront(viewport, 1.0f);
2179 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2180 hr = IDirect3DRMViewport_SetBack(viewport, 100.0f);
2181 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2182 hr = IDirect3DRMViewport_SetProjection(viewport, D3DRMPROJECT_PERSPECTIVE);
2183 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2185 /* Test all failures together */
2186 hr = IDirect3DRMViewport_Init(viewport, NULL, frame, rc.left, rc.top, rc.right, rc.bottom);
2187 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2188 hr = IDirect3DRMViewport_Init(viewport, device1, NULL, rc.left, rc.top, rc.right, rc.bottom);
2189 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2190 hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom + 1);
2191 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2192 hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom);
2193 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2194 hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right, rc.bottom + 1);
2195 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2197 device_ref = get_refcount((IUnknown *)device1);
2198 frame_ref = get_refcount((IUnknown *)frame);
2199 hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right, rc.bottom);
2200 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMViewport interface (hr = %#x).\n", hr);
2201 ref4 = get_refcount((IUnknown *)d3drm1);
2202 ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2203 ref4 = get_refcount((IUnknown *)d3drm2);
2204 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
2205 ref4 = get_refcount((IUnknown *)d3drm3);
2206 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
2207 ref4 = get_refcount((IUnknown *)device1);
2208 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
2209 ref4 = get_refcount((IUnknown *)frame);
2210 ok(ref4 > frame_ref, "Expected ref4 > frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4);
2212 hr = IDirect3DRMViewport_GetDevice(viewport, &d3drm_device1);
2213 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface (hr = %x)\n", hr);
2214 ok(device1 == d3drm_device1, "Expected device returned = %p, got %p.\n", device3, d3drm_device3);
2215 IDirect3DRMDevice_Release(d3drm_device1);
2217 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2218 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2219 viewport_ref = get_refcount((IUnknown *)d3d_viewport);
2220 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2221 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2222 ref4 = get_refcount((IUnknown *)d3d_viewport);
2223 ok(ref4 > viewport_ref, "Expected ref4 > viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
2224 IDirect3DViewport_Release(d3d_viewport);
2225 ref4 = get_refcount((IUnknown *)d3d_viewport);
2226 ok(ref4 == viewport_ref, "Expected ref4 == viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
2227 IDirect3DViewport_Release(d3d_viewport);
2229 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2230 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2231 vp.dwSize = sizeof(vp);
2232 hr = IDirect3DViewport_GetViewport(d3d_viewport, &vp);
2233 ok(SUCCEEDED(hr), "Cannot get D3DVIEWPORT struct (hr = %#x).\n", hr);
2234 ok(vp.dwWidth == rc.right, "Expected viewport width = %u, got %u.\n", rc.right, vp.dwWidth);
2235 ok(vp.dwHeight == rc.bottom, "Expected viewport height = %u, got %u.\n", rc.bottom, vp.dwHeight);
2236 ok(vp.dwX == rc.left, "Expected viewport X position = %u, got %u.\n", rc.left, vp.dwX);
2237 ok(vp.dwY == rc.top, "Expected viewport Y position = %u, got %u.\n", rc.top, vp.dwY);
2238 expected_val = (rc.right > rc.bottom) ? (rc.right / 2.0f) : (rc.bottom / 2.0f);
2239 ok(vp.dvScaleX == expected_val, "Expected dvScaleX = %f, got %f.\n", expected_val, vp.dvScaleX);
2240 ok(vp.dvScaleY == expected_val, "Expected dvScaleY = %f, got %f.\n", expected_val, vp.dvScaleY);
2241 expected_val = vp.dwWidth / (2.0f * vp.dvScaleX);
2242 ok(vp.dvMaxX == expected_val, "Expected dvMaxX = %f, got %f.\n", expected_val, vp.dvMaxX);
2243 expected_val = vp.dwHeight / (2.0f * vp.dvScaleY);
2244 ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY);
2245 IDirect3DViewport_Release(d3d_viewport);
2247 field = IDirect3DRMViewport_GetField(viewport);
2248 ok(field == 0.5f, "Got unexpected field %.8e.\n", field);
2249 hr = IDirect3DRMViewport_GetPlane(viewport, &left, &right, &bottom, &top);
2250 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2251 ok(left == -0.5f, "Got unexpected left %.8e.\n", left);
2252 ok(right == 0.5f, "Got unexpected right %.8e.\n", right);
2253 ok(bottom == -0.5f, "Got unexpected bottom %.8e.\n", bottom);
2254 ok(top == 0.5f, "Got unexpected top %.8e.\n", top);
2255 front = IDirect3DRMViewport_GetFront(viewport);
2256 ok(front == 1.0f, "Got unexpected front %.8e.\n", front);
2257 back = IDirect3DRMViewport_GetBack(viewport);
2258 ok(back == 100.0f, "Got unexpected back %.8e.\n", back);
2259 projection = IDirect3DRMViewport_GetProjection(viewport);
2260 ok(projection == D3DRMPROJECT_PERSPECTIVE, "Got unexpected projection type %#x.\n", projection);
2262 hr = IDirect3DRMViewport_SetField(viewport, 1.0f);
2263 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2264 field = IDirect3DRMViewport_GetField(viewport);
2265 ok(field == 1.0f, "Got unexpected field %.8e.\n", field);
2266 hr = IDirect3DRMViewport_GetPlane(viewport, &left, &right, &bottom, &top);
2267 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2268 ok(left == -1.0f, "Got unexpected left %.8e.\n", left);
2269 ok(right == 1.0f, "Got unexpected right %.8e.\n", right);
2270 ok(bottom == -1.0f, "Got unexpected bottom %.8e.\n", bottom);
2271 ok(top == 1.0f, "Got unexpected top %.8e.\n", top);
2273 hr = IDirect3DRMViewport_SetPlane(viewport, 5.0f, 3.0f, 2.0f, 0.0f);
2274 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2275 field = IDirect3DRMViewport_GetField(viewport);
2276 ok(field == -1.0f, "Got unexpected field %.8e.\n", field);
2277 hr = IDirect3DRMViewport_GetPlane(viewport, &left, &right, &bottom, &top);
2278 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2279 ok(left == 5.0f, "Got unexpected left %.8e.\n", left);
2280 ok(right == 3.0f, "Got unexpected right %.8e.\n", right);
2281 ok(bottom == 2.0f, "Got unexpected bottom %.8e.\n", bottom);
2282 ok(top == 0.0f, "Got unexpected top %.8e.\n", top);
2283 hr = IDirect3DRMViewport_SetFront(viewport, 2.0f);
2284 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2285 front = IDirect3DRMViewport_GetFront(viewport);
2286 ok(front == 2.0f, "Got unexpected front %.8e.\n", front);
2287 hr = IDirect3DRMViewport_SetBack(viewport, 200.0f);
2288 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2289 back = IDirect3DRMViewport_GetBack(viewport);
2290 ok(back == 200.0f, "Got unexpected back %.8e.\n", back);
2291 hr = IDirect3DRMViewport_SetProjection(viewport, D3DRMPROJECT_ORTHOGRAPHIC);
2292 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2293 projection = IDirect3DRMViewport_GetProjection(viewport);
2294 ok(projection == D3DRMPROJECT_ORTHOGRAPHIC, "Got unexpected projection type %#x.\n", projection);
2296 hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right, rc.bottom);
2297 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2298 hr = IDirect3DRMViewport_GetDevice(viewport, NULL);
2299 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2300 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, NULL);
2301 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2302 hr = IDirect3DRMViewport_GetCamera(viewport, NULL);
2303 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr);
2304 hr = IDirect3DRMViewport_SetField(viewport, 0.0f);
2305 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2306 hr = IDirect3DRMViewport_SetField(viewport, -1.0f);
2307 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2308 hr = IDirect3DRMViewport_SetFront(viewport, 0.0f);
2309 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr);
2310 hr = IDirect3DRMViewport_SetFront(viewport, -1.0f);
2311 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr);
2312 front = IDirect3DRMViewport_GetFront(viewport);
2313 hr = IDirect3DRMViewport_SetBack(viewport, front);
2314 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr);
2315 hr = IDirect3DRMViewport_SetBack(viewport, front / 2.0f);
2316 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr);
2318 IDirect3DRMViewport_Release(viewport);
2319 ref4 = get_refcount((IUnknown *)d3drm1);
2320 todo_wine ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2321 ref4 = get_refcount((IUnknown *)d3drm2);
2322 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
2323 ref4 = get_refcount((IUnknown *)d3drm3);
2324 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
2325 ref4 = get_refcount((IUnknown *)device1);
2326 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
2327 ref4 = get_refcount((IUnknown *)frame);
2328 todo_wine ok(ref4 > frame_ref, "Expected ref4 > frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4);
2330 ref1 = get_refcount((IUnknown *)d3drm1);
2331 ref2 = get_refcount((IUnknown *)d3drm2);
2332 ref3 = get_refcount((IUnknown *)d3drm3);
2333 hr = IDirect3DRM3_CreateObject(d3drm2, &CLSID_CDirect3DRMViewport, NULL, &IID_IDirect3DRMViewport2,
2334 (void **)&viewport2);
2335 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport2 interface (hr = %#x).\n", hr);
2336 ref4 = get_refcount((IUnknown *)d3drm1);
2337 ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2338 ref4 = get_refcount((IUnknown *)d3drm2);
2339 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
2340 ref4 = get_refcount((IUnknown *)d3drm3);
2341 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
2343 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
2344 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2345 hr = IDirect3DRMViewport2_GetDevice(viewport2, &d3drm_device3);
2346 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2347 hr = IDirect3DRMViewport2_GetCamera(viewport2, &d3drm_frame3);
2348 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2349 field = IDirect3DRMViewport2_GetField(viewport2);
2350 ok(field == -1.0f, "Got unexpected field %.8e.\n", field);
2351 left = right = bottom = top = 10.0f;
2352 hr = IDirect3DRMViewport2_GetPlane(viewport2, &left, &right, &bottom, &top);
2353 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2354 ok(left == 10.0f, "Got unexpected left %.8e.\n", left);
2355 ok(right == 10.0f, "Got unexpected right %.8e.\n", right);
2356 ok(bottom == 10.0f, "Got unexpected bottom %.8e.\n", bottom);
2357 ok(top == 10.0f, "Got unexpected top %.8e.\n", top);
2358 front = IDirect3DRMViewport2_GetFront(viewport2);
2359 ok(front == -1.0f, "Got unexpected front %.8e\n", front);
2360 back = IDirect3DRMViewport2_GetBack(viewport2);
2361 ok(back == -1.0f, "Got unexpected back %.8e\n", back);
2362 projection = IDirect3DRMViewport2_GetProjection(viewport2);
2363 ok(projection == ~0u, "Got unexpected projection type %#x.\n", projection);
2365 hr = IDirect3DRMViewport2_SetCamera(viewport2, frame3);
2366 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2367 hr = IDirect3DRMViewport2_SetField(viewport2, 0.5f);
2368 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2369 hr = IDirect3DRMViewport2_SetPlane(viewport2, -0.5f, 0.5f, -0.5f, 0.5f);
2370 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2371 hr = IDirect3DRMViewport2_SetFront(viewport2, 1.0f);
2372 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2373 hr = IDirect3DRMViewport2_SetBack(viewport2, 100.0f);
2374 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2375 hr = IDirect3DRMViewport2_SetProjection(viewport2, D3DRMPROJECT_PERSPECTIVE);
2376 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr);
2378 hr = IDirect3DRMViewport2_Init(viewport2, NULL, frame3, rc.left, rc.top, rc.right, rc.bottom);
2379 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2380 hr = IDirect3DRMViewport2_Init(viewport2, device3, NULL, rc.left, rc.top, rc.right, rc.bottom);
2381 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2382 hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom + 1);
2383 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2384 hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom);
2385 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2386 hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right, rc.bottom + 1);
2387 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2389 device_ref = get_refcount((IUnknown *)device3);
2390 frame_ref2 = get_refcount((IUnknown *)frame3);
2391 hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right, rc.bottom);
2392 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMViewport2 interface (hr = %#x).\n", hr);
2393 ref4 = get_refcount((IUnknown *)device3);
2394 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
2395 ref4 = get_refcount((IUnknown *)frame3);
2396 ok(ref4 > frame_ref2, "Expected ref4 > frame_ref2, got frame_ref2 = %u, ref4 = %u.\n", frame_ref2, ref4);
2398 hr = IDirect3DRMViewport2_GetDevice(viewport2, &d3drm_device3);
2399 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface (hr = %x)\n", hr);
2400 ok(device3 == d3drm_device3, "Expected device returned = %p, got %p.\n", device3, d3drm_device3);
2401 IDirect3DRMDevice3_Release(d3drm_device3);
2403 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
2404 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2405 viewport_ref = get_refcount((IUnknown *)d3d_viewport);
2406 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
2407 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2408 ref4 = get_refcount((IUnknown *)d3d_viewport);
2409 ok(ref4 > viewport_ref, "Expected ref4 > viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
2410 IDirect3DViewport_Release(d3d_viewport);
2411 ref4 = get_refcount((IUnknown *)d3d_viewport);
2412 ok(ref4 == viewport_ref, "Expected ref4 == viewport_ref, got ref4 = %u, viewport_ref = %u.\n", ref4, viewport_ref);
2413 IDirect3DViewport_Release(d3d_viewport);
2415 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
2416 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
2417 vp.dwSize = sizeof(vp);
2418 hr = IDirect3DViewport_GetViewport(d3d_viewport, &vp);
2419 ok(SUCCEEDED(hr), "Cannot get D3DVIEWPORT struct (hr = %#x).\n", hr);
2420 ok(vp.dwWidth == rc.right, "Expected viewport width = %u, got %u.\n", rc.right, vp.dwWidth);
2421 ok(vp.dwHeight == rc.bottom, "Expected viewport height = %u, got %u.\n", rc.bottom, vp.dwHeight);
2422 ok(vp.dwX == rc.left, "Expected viewport X position = %u, got %u.\n", rc.left, vp.dwX);
2423 ok(vp.dwY == rc.top, "Expected viewport Y position = %u, got %u.\n", rc.top, vp.dwY);
2424 expected_val = (rc.right > rc.bottom) ? (rc.right / 2.0f) : (rc.bottom / 2.0f);
2425 ok(vp.dvScaleX == expected_val, "Expected dvScaleX = %f, got %f.\n", expected_val, vp.dvScaleX);
2426 ok(vp.dvScaleY == expected_val, "Expected dvScaleY = %f, got %f.\n", expected_val, vp.dvScaleY);
2427 expected_val = vp.dwWidth / (2.0f * vp.dvScaleX);
2428 ok(vp.dvMaxX == expected_val, "Expected dvMaxX = %f, got %f.\n", expected_val, vp.dvMaxX);
2429 expected_val = vp.dwHeight / (2.0f * vp.dvScaleY);
2430 ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY);
2431 IDirect3DViewport_Release(d3d_viewport);
2433 field = IDirect3DRMViewport2_GetField(viewport2);
2434 ok(field == 0.5f, "Got unexpected field %.8e.\n", field);
2435 hr = IDirect3DRMViewport2_GetPlane(viewport2, &left, &right, &bottom, &top);
2436 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2437 ok(left == -0.5f, "Got unexpected left %.8e.\n", left);
2438 ok(right == 0.5f, "Got unexpected right %.8e.\n", right);
2439 ok(bottom == -0.5f, "Got unexpected bottom %.8e.\n", bottom);
2440 ok(top == 0.5f, "Got unexpected top %.8e.\n", top);
2441 front = IDirect3DRMViewport2_GetFront(viewport2);
2442 ok(front == 1.0f, "Got unexpected front %.8e.\n", front);
2443 back = IDirect3DRMViewport2_GetBack(viewport2);
2444 ok(back == 100.0f, "Got unexpected back %.8e.\n", back);
2445 projection = IDirect3DRMViewport2_GetProjection(viewport2);
2446 ok(projection == D3DRMPROJECT_PERSPECTIVE, "Got unexpected projection type %#x.\n", projection);
2448 hr = IDirect3DRMViewport2_SetField(viewport2, 1.0f);
2449 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2450 field = IDirect3DRMViewport2_GetField(viewport2);
2451 ok(field == 1.0f, "Got unexpected field %.8e.\n", field);
2452 hr = IDirect3DRMViewport2_GetPlane(viewport2, &left, &right, &bottom, &top);
2453 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2454 ok(left == -1.0f, "Got unexpected left %.8e.\n", left);
2455 ok(right == 1.0f, "Got unexpected right %.8e.\n", right);
2456 ok(bottom == -1.0f, "Got unexpected bottom %.8e.\n", bottom);
2457 ok(top == 1.0f, "Got unexpected top %.8e.\n", top);
2459 hr = IDirect3DRMViewport2_SetPlane(viewport2, 5.0f, 3.0f, 2.0f, 0.0f);
2460 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2461 field = IDirect3DRMViewport2_GetField(viewport2);
2462 ok(field == -1.0f, "Got unexpected field %.8e.\n", field);
2463 hr = IDirect3DRMViewport2_GetPlane(viewport2, &left, &right, &bottom, &top);
2464 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2465 ok(left == 5.0f, "Got unexpected left %.8e.\n", left);
2466 ok(right == 3.0f, "Got unexpected right %.8e.\n", right);
2467 ok(bottom == 2.0f, "Got unexpected bottom %.8e.\n", bottom);
2468 ok(top == 0.0f, "Got unexpected top %.8e.\n", top);
2469 hr = IDirect3DRMViewport2_SetFront(viewport2, 2.0f);
2470 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2471 front = IDirect3DRMViewport2_GetFront(viewport2);
2472 ok(front == 2.0f, "Got unexpected front %.8e.\n", front);
2473 hr = IDirect3DRMViewport2_SetBack(viewport2, 200.0f);
2474 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2475 back = IDirect3DRMViewport2_GetBack(viewport2);
2476 ok(back == 200.0f, "Got unexpected back %.8e.\n", back);
2477 hr = IDirect3DRMViewport2_SetProjection(viewport2, D3DRMPROJECT_ORTHOGRAPHIC);
2478 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2479 projection = IDirect3DRMViewport2_GetProjection(viewport2);
2480 ok(projection == D3DRMPROJECT_ORTHOGRAPHIC, "Got unexpected projection type %#x.\n", projection);
2482 hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right, rc.bottom);
2483 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2484 hr = IDirect3DRMViewport2_GetDevice(viewport2, NULL);
2485 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2486 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, NULL);
2487 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2488 hr = IDirect3DRMViewport2_GetCamera(viewport2, NULL);
2489 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr);
2490 hr = IDirect3DRMViewport2_SetField(viewport2, 0.0f);
2491 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2492 hr = IDirect3DRMViewport2_SetField(viewport2, -1.0f);
2493 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2494 hr = IDirect3DRMViewport2_SetFront(viewport2, 0.0f);
2495 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr);
2496 hr = IDirect3DRMViewport2_SetFront(viewport2, -1.0f);
2497 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr);
2498 front = IDirect3DRMViewport2_GetFront(viewport2);
2499 hr = IDirect3DRMViewport2_SetBack(viewport2, front);
2500 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr);
2501 hr = IDirect3DRMViewport2_SetBack(viewport2, front / 2.0f);
2502 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr);
2504 IDirect3DRMViewport2_Release(viewport2);
2505 ref4 = get_refcount((IUnknown *)d3drm1);
2506 todo_wine ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2507 ref4 = get_refcount((IUnknown *)d3drm2);
2508 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4);
2509 ref4 = get_refcount((IUnknown *)d3drm3);
2510 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4);
2511 ref4 = get_refcount((IUnknown *)device3);
2512 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4);
2513 ref4 = get_refcount((IUnknown *)frame3);
2514 todo_wine ok(ref4 > frame_ref2, "Expected ref4 > frame_ref2, got frame_ref2 = %u, ref4 = %u.\n", frame_ref2, ref4);
2516 IDirect3DRMDevice3_Release(device3);
2517 IDirect3DRMDevice_Release(device1);
2518 ref4 = get_refcount((IUnknown *)d3drm1);
2519 ok(ref4 > initial_ref1, "Expected ref4 > initial_ref1, got initial_ref1 = %u, ref4 = %u.\n", initial_ref1, ref4);
2520 ref4 = get_refcount((IUnknown *)d3drm2);
2521 ok(ref4 == initial_ref2, "Expected ref4 == initial_ref2, got initial_ref2 = %u, ref4 = %u.\n", initial_ref2, ref4);
2522 ref4 = get_refcount((IUnknown *)d3drm3);
2523 ok(ref4 == initial_ref3, "Expected ref4 == initial_ref3, got initial_ref3 = %u, ref4 = %u.\n", initial_ref3, ref4);
2524 ref4 = get_refcount((IUnknown *)frame);
2525 ok(ref4 == frame_ref, "Expected ref4 == frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4);
2526 ref4 = get_refcount((IUnknown *)frame3);
2527 ok(ref4 == frame_ref2, "Expected ref4 == frame_ref2, got frame_ref2 = %u, ref4 = %u.\n", frame_ref2, ref4);
2529 IDirect3DRMFrame3_Release(tmp_frame3);
2530 IDirect3DRMFrame3_Release(frame3);
2531 ref4 = get_refcount((IUnknown *)d3drm1);
2532 ok(ref4 > initial_ref1, "Expected ref4 > initial_ref1, got initial_ref1 = %u, ref4 = %u.\n", initial_ref1, ref4);
2533 ref4 = get_refcount((IUnknown *)d3drm2);
2534 ok(ref4 == initial_ref2, "Expected ref4 == initial_ref2, got initial_ref2 = %u, ref4 = %u.\n", initial_ref2, ref4);
2535 ref4 = get_refcount((IUnknown *)d3drm3);
2536 ok(ref4 == initial_ref3, "Expected ref4 == initial_ref3, got initial_ref3 = %u, ref4 = %u.\n", initial_ref3, ref4);
2538 IDirect3DRMFrame3_Release(tmp_frame1);
2539 IDirect3DRMFrame_Release(frame);
2540 ref4 = get_refcount((IUnknown *)d3drm1);
2541 ok(ref4 == initial_ref1, "Expected ref4 == initial_ref1, got initial_ref1 = %u, ref4 = %u.\n", initial_ref1, ref4);
2542 ref4 = get_refcount((IUnknown *)d3drm2);
2543 ok(ref4 == initial_ref2, "Expected ref4 == initial_ref2, got initial_ref2 = %u, ref4 = %u.\n", initial_ref2, ref4);
2544 ref4 = get_refcount((IUnknown *)d3drm3);
2545 ok(ref4 == initial_ref3, "Expected ref4 == initial_ref3, got initial_ref3 = %u, ref4 = %u.\n", initial_ref3, ref4);
2546 IDirectDrawClipper_Release(clipper);
2548 IDirect3DRM3_Release(d3drm3);
2549 IDirect3DRM2_Release(d3drm2);
2550 IDirect3DRM_Release(d3drm1);
2551 DestroyWindow(window);
2554 static void test_Light(void)
2556 IDirect3DRMObject *object;
2557 HRESULT hr;
2558 IDirect3DRM *d3drm;
2559 IDirect3DRMLight *light;
2560 D3DRMLIGHTTYPE type;
2561 D3DCOLOR color;
2563 hr = Direct3DRMCreate(&d3drm);
2564 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
2566 hr = IDirect3DRM_CreateLightRGB(d3drm, D3DRMLIGHT_SPOT, 0.5, 0.5, 0.5, &light);
2567 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMLight interface (hr = %x)\n", hr);
2569 hr = IDirect3DRMLight_QueryInterface(light, &IID_IDirect3DRMObject, (void **)&object);
2570 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, hr %#x.\n", hr);
2571 IDirect3DRMObject_Release(object);
2573 test_class_name((IDirect3DRMObject *)light, "Light");
2574 test_object_name((IDirect3DRMObject *)light);
2576 type = IDirect3DRMLight_GetType(light);
2577 ok(type == D3DRMLIGHT_SPOT, "wrong type (%u)\n", type);
2579 color = IDirect3DRMLight_GetColor(light);
2580 ok(color == 0xff7f7f7f, "wrong color (%x)\n", color);
2582 hr = IDirect3DRMLight_SetType(light, D3DRMLIGHT_POINT);
2583 ok(hr == D3DRM_OK, "Cannot set type (hr = %x)\n", hr);
2584 type = IDirect3DRMLight_GetType(light);
2585 ok(type == D3DRMLIGHT_POINT, "wrong type (%u)\n", type);
2587 hr = IDirect3DRMLight_SetColor(light, 0xff180587);
2588 ok(hr == D3DRM_OK, "Cannot set color (hr = %x)\n", hr);
2589 color = IDirect3DRMLight_GetColor(light);
2590 ok(color == 0xff180587, "wrong color (%x)\n", color);
2592 hr = IDirect3DRMLight_SetColor(light, 0x00c0c0c0);
2593 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2594 color = IDirect3DRMLight_GetColor(light);
2595 ok(color == 0xffc0c0c0, "Got unexpected color 0x%08x.\n", color);
2597 hr = IDirect3DRMLight_SetColorRGB(light, 0.5, 0.5, 0.5);
2598 ok(hr == D3DRM_OK, "Cannot set color (hr = %x)\n", hr);
2599 color = IDirect3DRMLight_GetColor(light);
2600 ok(color == 0xff7f7f7f, "wrong color (%x)\n", color);
2602 IDirect3DRMLight_Release(light);
2604 hr = IDirect3DRM_CreateLight(d3drm, D3DRMLIGHT_SPOT, 0x00c0c0c0, &light);
2605 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
2607 type = IDirect3DRMLight_GetType(light);
2608 ok(type == D3DRMLIGHT_SPOT, "Got unexpected type %#x.\n", type);
2610 color = IDirect3DRMLight_GetColor(light);
2611 ok(color == 0xffc0c0c0, "Got unexpected color 0x%08x.\n", color);
2613 IDirect3DRMLight_Release(light);
2615 IDirect3DRM_Release(d3drm);
2618 static void test_Material2(void)
2620 HRESULT hr;
2621 IDirect3DRM *d3drm;
2622 IDirect3DRM3 *d3drm3;
2623 IDirect3DRMMaterial2 *material2;
2624 D3DVALUE r, g, b;
2626 hr = Direct3DRMCreate(&d3drm);
2627 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
2629 if (FAILED(hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM3, (void **)&d3drm3)))
2631 win_skip("Cannot get IDirect3DRM3 interface (hr = %x), skipping tests\n", hr);
2632 IDirect3DRM_Release(d3drm);
2633 return;
2636 hr = IDirect3DRM3_CreateMaterial(d3drm3, 18.5f, &material2);
2637 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMaterial2 interface (hr = %x)\n", hr);
2639 test_class_name((IDirect3DRMObject *)material2, "Material");
2640 test_object_name((IDirect3DRMObject *)material2);
2642 r = IDirect3DRMMaterial2_GetPower(material2);
2643 ok(r == 18.5f, "wrong power (%f)\n", r);
2645 hr = IDirect3DRMMaterial2_GetEmissive(material2, &r, &g, &b);
2646 ok(hr == D3DRM_OK, "Cannot get emissive (hr = %x)\n", hr);
2647 ok(r == 0.0f && g == 0.0f && b == 0.0f, "wrong emissive r=%f g=%f b=%f, expected r=0.0 g=0.0 b=0.0\n", r, g, b);
2649 hr = IDirect3DRMMaterial2_GetSpecular(material2, &r, &g, &b);
2650 ok(hr == D3DRM_OK, "Cannot get emissive (hr = %x)\n", hr);
2651 ok(r == 1.0f && g == 1.0f && b == 1.0f, "wrong specular r=%f g=%f b=%f, expected r=1.0 g=1.0 b=1.0\n", r, g, b);
2653 hr = IDirect3DRMMaterial2_GetAmbient(material2, &r, &g, &b);
2654 ok(hr == D3DRM_OK, "Cannot get emissive (hr = %x)\n", hr);
2655 ok(r == 0.0f && g == 0.0f && b == 0.0f, "wrong ambient r=%f g=%f b=%f, expected r=0.0 g=0.0 b=0.0\n", r, g, b);
2657 hr = IDirect3DRMMaterial2_SetPower(material2, 5.87f);
2658 ok(hr == D3DRM_OK, "Cannot set power (hr = %x)\n", hr);
2659 r = IDirect3DRMMaterial2_GetPower(material2);
2660 ok(r == 5.87f, "wrong power (%f)\n", r);
2662 hr = IDirect3DRMMaterial2_SetEmissive(material2, 0.5f, 0.5f, 0.5f);
2663 ok(hr == D3DRM_OK, "Cannot set emissive (hr = %x)\n", hr);
2664 hr = IDirect3DRMMaterial2_GetEmissive(material2, &r, &g, &b);
2665 ok(hr == D3DRM_OK, "Cannot get emissive (hr = %x)\n", hr);
2666 ok(r == 0.5f && g == 0.5f && b == 0.5f, "wrong emissive r=%f g=%f b=%f, expected r=0.5 g=0.5 b=0.5\n", r, g, b);
2668 hr = IDirect3DRMMaterial2_SetSpecular(material2, 0.6f, 0.6f, 0.6f);
2669 ok(hr == D3DRM_OK, "Cannot set specular (hr = %x)\n", hr);
2670 hr = IDirect3DRMMaterial2_GetSpecular(material2, &r, &g, &b);
2671 ok(hr == D3DRM_OK, "Cannot get specular (hr = %x)\n", hr);
2672 ok(r == 0.6f && g == 0.6f && b == 0.6f, "wrong specular r=%f g=%f b=%f, expected r=0.6 g=0.6 b=0.6\n", r, g, b);
2674 hr = IDirect3DRMMaterial2_SetAmbient(material2, 0.7f, 0.7f, 0.7f);
2675 ok(hr == D3DRM_OK, "Cannot set ambient (hr = %x)\n", hr);
2676 hr = IDirect3DRMMaterial2_GetAmbient(material2, &r, &g, &b);
2677 ok(hr == D3DRM_OK, "Cannot get ambient (hr = %x)\n", hr);
2678 ok(r == 0.7f && g == 0.7f && b == 0.7f, "wrong ambient r=%f g=%f b=%f, expected r=0.7 g=0.7 b=0.7\n", r, g, b);
2680 IDirect3DRMMaterial2_Release(material2);
2682 IDirect3DRM3_Release(d3drm3);
2683 IDirect3DRM_Release(d3drm);
2686 static void test_Texture(void)
2688 HRESULT hr;
2689 IDirect3DRM *d3drm1;
2690 IDirect3DRM2 *d3drm2;
2691 IDirect3DRM3 *d3drm3;
2692 IDirect3DRMTexture *texture1;
2693 IDirect3DRMTexture2 *texture2;
2694 IDirect3DRMTexture3 *texture3;
2695 IDirectDrawSurface *surface;
2697 D3DRMIMAGE initimg =
2699 2, 2, 1, 1, 32,
2700 TRUE, 2 * sizeof(DWORD), NULL, NULL,
2701 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000, 0, NULL
2703 testimg =
2705 0, 0, 0, 0, 0,
2706 TRUE, 0, (void *)0xcafebabe, NULL,
2707 0x000000ff, 0x0000ff00, 0x00ff0000, 0, 0, NULL
2709 *d3drm_img = NULL;
2711 DWORD pixel[4] = { 20000, 30000, 10000, 0 };
2712 ULONG ref1, ref2, ref3, ref4;
2714 hr = Direct3DRMCreate(&d3drm1);
2715 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
2716 ref1 = get_refcount((IUnknown *)d3drm1);
2718 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
2719 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface (hr = %x).\n", hr);
2721 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
2722 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface (hr = %x).\n", hr);
2724 /* Test NULL params */
2725 texture1 = (IDirect3DRMTexture *)0xdeadbeef;
2726 hr = IDirect3DRM_CreateTexture(d3drm1, NULL, &texture1);
2727 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2728 ok(!texture1, "Expected texture returned == NULL, got %p.\n", texture1);
2729 hr = IDirect3DRM_CreateTexture(d3drm1, NULL, NULL);
2730 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2732 texture2 = (IDirect3DRMTexture2 *)0xdeadbeef;
2733 hr = IDirect3DRM2_CreateTexture(d3drm2, NULL, &texture2);
2734 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2735 ok(!texture2, "Expected texture returned == NULL, got %p.\n", texture2);
2736 hr = IDirect3DRM2_CreateTexture(d3drm2, NULL, NULL);
2737 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2739 texture3 = (IDirect3DRMTexture3 *)0xdeadbeef;
2740 hr = IDirect3DRM3_CreateTexture(d3drm3, NULL, &texture3);
2741 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2742 ok(!texture3, "Expected texture returned == NULL, got %p.\n", texture3);
2743 hr = IDirect3DRM3_CreateTexture(d3drm3, NULL, NULL);
2744 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2746 /* Tests for validation of D3DRMIMAGE struct */
2747 hr = IDirect3DRM_CreateTexture(d3drm1, &testimg, &texture1);
2748 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture interface (hr = %#x)\n", hr);
2749 hr = IDirect3DRM2_CreateTexture(d3drm2, &testimg, &texture2);
2750 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface (hr = %#x)\n", hr);
2751 hr = IDirect3DRM3_CreateTexture(d3drm3, &testimg, &texture3);
2752 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface (hr = %#x)\n", hr);
2753 IDirect3DRMTexture_Release(texture1);
2754 IDirect3DRMTexture2_Release(texture2);
2755 IDirect3DRMTexture3_Release(texture3);
2757 testimg.rgb = 0;
2758 testimg.palette = (void *)0xdeadbeef;
2759 testimg.palette_size = 0x39;
2760 hr = IDirect3DRM_CreateTexture(d3drm1, &testimg, &texture1);
2761 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture interface (hr = %#x)\n", hr);
2762 hr = IDirect3DRM2_CreateTexture(d3drm2, &testimg, &texture2);
2763 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface (hr = %#x)\n", hr);
2764 hr = IDirect3DRM3_CreateTexture(d3drm3, &testimg, &texture3);
2765 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface (hr = %#x)\n", hr);
2766 IDirect3DRMTexture_Release(texture1);
2767 IDirect3DRMTexture2_Release(texture2);
2768 IDirect3DRMTexture3_Release(texture3);
2770 initimg.rgb = 0;
2771 texture1 = (IDirect3DRMTexture *)0xdeadbeef;
2772 hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2773 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2774 ok(!texture1, "Expected texture == NULL, got %p.\n", texture1);
2775 texture2 = (IDirect3DRMTexture2 *)0xdeadbeef;
2776 hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2777 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2778 ok(!texture2, "Expected texture == NULL, got %p.\n", texture2);
2779 texture3 = (IDirect3DRMTexture3 *)0xdeadbeef;
2780 hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2781 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2782 ok(!texture3, "Expected texture == NULL, got %p.\n", texture3);
2783 initimg.rgb = 1;
2784 initimg.red_mask = 0;
2785 hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2786 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2787 hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2788 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2789 hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2790 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2791 initimg.red_mask = 0x000000ff;
2792 initimg.green_mask = 0;
2793 hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2794 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2795 hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2796 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2797 hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2798 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2799 initimg.green_mask = 0x0000ff00;
2800 initimg.blue_mask = 0;
2801 hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2802 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2803 hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2804 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2805 hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2806 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2807 initimg.blue_mask = 0x00ff0000;
2808 initimg.buffer1 = NULL;
2809 hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2810 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2811 hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2812 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2813 hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2814 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
2816 initimg.buffer1 = &pixel;
2817 hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2818 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture interface (hr = %#x)\n", hr);
2819 ref2 = get_refcount((IUnknown *)d3drm1);
2820 ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %u , ref2 = %u.\n", ref1, ref2);
2821 ref3 = get_refcount((IUnknown *)d3drm2);
2822 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
2823 ref4 = get_refcount((IUnknown *)d3drm3);
2824 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u , ref4 = %u.\n", ref1, ref4);
2825 hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2826 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface (hr = %#x)\n", hr);
2827 ref2 = get_refcount((IUnknown *)d3drm1);
2828 ok(ref2 > ref1 + 1, "expected ref2 > (ref1 + 1), got ref1 = %u , ref2 = %u.\n", ref1, ref2);
2829 ref3 = get_refcount((IUnknown *)d3drm2);
2830 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
2831 ref4 = get_refcount((IUnknown *)d3drm3);
2832 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u , ref4 = %u.\n", ref1, ref4);
2833 hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2834 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface (hr = %#x)\n", hr);
2835 ref2 = get_refcount((IUnknown *)d3drm1);
2836 ok(ref2 > ref1 + 2, "expected ref2 > (ref1 + 2), got ref1 = %u , ref2 = %u.\n", ref1, ref2);
2837 ref3 = get_refcount((IUnknown *)d3drm2);
2838 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
2839 ref4 = get_refcount((IUnknown *)d3drm3);
2840 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u , ref4 = %u.\n", ref1, ref4);
2842 /* Created from image, GetSurface() does not work. */
2843 hr = IDirect3DRMTexture3_GetSurface(texture3, 0, NULL);
2844 ok(hr == D3DRMERR_BADVALUE, "GetSurface() expected to fail, %#x\n", hr);
2846 hr = IDirect3DRMTexture3_GetSurface(texture3, 0, &surface);
2847 ok(hr == D3DRMERR_NOTCREATEDFROMDDS, "GetSurface() expected to fail, %#x\n", hr);
2849 /* Test all failures together */
2850 test_class_name((IDirect3DRMObject *)texture1, "Texture");
2851 test_class_name((IDirect3DRMObject *)texture2, "Texture");
2852 test_class_name((IDirect3DRMObject *)texture3, "Texture");
2853 test_object_name((IDirect3DRMObject *)texture1);
2854 test_object_name((IDirect3DRMObject *)texture2);
2855 test_object_name((IDirect3DRMObject *)texture3);
2857 d3drm_img = IDirect3DRMTexture_GetImage(texture1);
2858 ok(!!d3drm_img, "Failed to get image.\n");
2859 ok(d3drm_img == &initimg, "Expected image returned == %p, got %p.\n", &initimg, d3drm_img);
2861 IDirect3DRMTexture_Release(texture1);
2862 ref2 = get_refcount((IUnknown *)d3drm1);
2863 ok(ref2 - 2 == ref1, "expected (ref2 - 2) == ref1, got ref1 = %u, ref2 = %u.\n", ref1, ref2);
2864 ref3 = get_refcount((IUnknown *)d3drm2);
2865 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
2866 ref4 = get_refcount((IUnknown *)d3drm3);
2867 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2869 d3drm_img = NULL;
2870 d3drm_img = IDirect3DRMTexture2_GetImage(texture2);
2871 ok(!!d3drm_img, "Failed to get image.\n");
2872 ok(d3drm_img == &initimg, "Expected image returned == %p, got %p.\n", &initimg, d3drm_img);
2874 IDirect3DRMTexture2_Release(texture2);
2875 ref2 = get_refcount((IUnknown *)d3drm1);
2876 ok(ref2 - 1 == ref1, "expected (ref2 - 1) == ref1, got ref1 = %u, ref2 = %u.\n", ref1, ref2);
2877 ref3 = get_refcount((IUnknown *)d3drm2);
2878 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
2879 ref4 = get_refcount((IUnknown *)d3drm3);
2880 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2882 d3drm_img = NULL;
2883 d3drm_img = IDirect3DRMTexture3_GetImage(texture3);
2884 ok(!!d3drm_img, "Failed to get image.\n");
2885 ok(d3drm_img == &initimg, "Expected image returned == %p, got %p.\n", &initimg, d3drm_img);
2887 IDirect3DRMTexture3_Release(texture3);
2888 ref2 = get_refcount((IUnknown *)d3drm1);
2889 ok(ref2 == ref1, "expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", ref1, ref2);
2890 ref3 = get_refcount((IUnknown *)d3drm2);
2891 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
2892 ref4 = get_refcount((IUnknown *)d3drm3);
2893 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
2895 /* InitFromImage tests */
2896 /* Tests for validation of D3DRMIMAGE struct */
2897 testimg.rgb = 1;
2898 testimg.palette = NULL;
2899 testimg.palette_size = 0;
2900 hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture2,
2901 (void **)&texture2);
2902 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface (hr = %#x).\n", hr);
2903 hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture3,
2904 (void **)&texture3);
2905 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface (hr = %#x).\n", hr);
2906 hr = IDirect3DRMTexture2_InitFromImage(texture2, &testimg);
2907 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture2 interface (hr = %#x)\n", hr);
2908 hr = IDirect3DRMTexture3_InitFromImage(texture3, &testimg);
2909 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture3 interface (hr = %#x)\n", hr);
2910 IDirect3DRMTexture2_Release(texture2);
2911 IDirect3DRMTexture3_Release(texture3);
2913 testimg.rgb = 0;
2914 testimg.palette = (void *)0xdeadbeef;
2915 testimg.palette_size = 0x39;
2916 hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture2,
2917 (void **)&texture2);
2918 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface (hr = %#x).\n", hr);
2919 hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture3,
2920 (void **)&texture3);
2921 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface (hr = %#x).\n", hr);
2922 hr = IDirect3DRMTexture2_InitFromImage(texture2, &testimg);
2923 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture2 interface (hr = %#x)\n", hr);
2924 hr = IDirect3DRMTexture3_InitFromImage(texture3, &testimg);
2925 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture3 interface (hr = %#x)\n", hr);
2926 IDirect3DRMTexture2_Release(texture2);
2927 IDirect3DRMTexture3_Release(texture3);
2929 hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture2,
2930 (void **)&texture2);
2931 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface (hr = %#x).\n", hr);
2932 ref2 = get_refcount((IUnknown *)texture2);
2933 hr = IDirect3DRMTexture2_InitFromImage(texture2, NULL);
2934 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2935 ref3 = get_refcount((IUnknown *)texture2);
2936 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
2938 hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture3,
2939 (void **)&texture3);
2940 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface (hr = %#x).\n", hr);
2941 ref2 = get_refcount((IUnknown *)texture3);
2942 hr = IDirect3DRMTexture3_InitFromImage(texture3, NULL);
2943 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2944 ref3 = get_refcount((IUnknown *)texture3);
2945 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
2947 initimg.rgb = 0;
2948 hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
2949 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2950 hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
2951 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2952 initimg.rgb = 1;
2953 initimg.red_mask = 0;
2954 hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
2955 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2956 hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
2957 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2958 initimg.red_mask = 0x000000ff;
2959 initimg.green_mask = 0;
2960 hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
2961 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2962 hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
2963 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2964 initimg.green_mask = 0x0000ff00;
2965 initimg.blue_mask = 0;
2966 hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
2967 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2968 hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
2969 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2970 initimg.blue_mask = 0x00ff0000;
2971 initimg.buffer1 = NULL;
2972 hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
2973 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2974 hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
2975 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2976 initimg.buffer1 = &pixel;
2978 d3drm_img = NULL;
2979 hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
2980 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture2 from image (hr = %#x).\n", hr);
2981 ref2 = get_refcount((IUnknown *)d3drm1);
2982 ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %u , ref2 = %u.\n", ref1, ref2);
2983 ref3 = get_refcount((IUnknown *)d3drm2);
2984 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
2985 ref4 = get_refcount((IUnknown *)d3drm3);
2986 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u , ref4 = %u.\n", ref1, ref4);
2988 hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
2989 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
2990 /* Release leaked reference to d3drm1 */
2991 IDirect3DRM_Release(d3drm1);
2993 d3drm_img = IDirect3DRMTexture2_GetImage(texture2);
2994 ok(!!d3drm_img, "Failed to get image.\n");
2995 ok(d3drm_img == &initimg, "Expected image returned == %p, got %p.\n", &initimg, d3drm_img);
2996 IDirect3DRMTexture2_Release(texture2);
2997 ref2 = get_refcount((IUnknown *)d3drm1);
2998 ok(ref2 == ref1, "expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", ref1, ref2);
2999 ref3 = get_refcount((IUnknown *)d3drm2);
3000 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
3001 ref4 = get_refcount((IUnknown *)d3drm3);
3002 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
3004 d3drm_img = NULL;
3005 hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
3006 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture3 from image (hr = %#x).\n", hr);
3007 ref2 = get_refcount((IUnknown *)d3drm1);
3008 ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %u , ref2 = %u.\n", ref1, ref2);
3009 ref3 = get_refcount((IUnknown *)d3drm2);
3010 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
3011 ref4 = get_refcount((IUnknown *)d3drm3);
3012 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u , ref4 = %u.\n", ref1, ref4);
3014 hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
3015 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
3016 IDirect3DRM_Release(d3drm1);
3018 d3drm_img = IDirect3DRMTexture3_GetImage(texture3);
3019 ok(!!d3drm_img, "Failed to get image.\n");
3020 ok(d3drm_img == &initimg, "Expected image returned == %p, got %p.\n", &initimg, d3drm_img);
3021 IDirect3DRMTexture3_Release(texture3);
3022 ref2 = get_refcount((IUnknown *)d3drm1);
3023 ok(ref2 == ref1, "expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", ref1, ref2);
3024 ref3 = get_refcount((IUnknown *)d3drm2);
3025 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
3026 ref4 = get_refcount((IUnknown *)d3drm3);
3027 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4);
3029 IDirect3DRM3_Release(d3drm3);
3030 IDirect3DRM2_Release(d3drm2);
3031 IDirect3DRM_Release(d3drm1);
3034 static void test_Device(void)
3036 IDirectDrawClipper *pClipper;
3037 HRESULT hr;
3038 IDirect3DRM *d3drm;
3039 IDirect3DRMDevice *device;
3040 IDirect3DRMWinDevice *win_device;
3041 GUID driver;
3042 HWND window;
3043 RECT rc;
3045 window = create_window();
3046 GetClientRect(window, &rc);
3048 hr = Direct3DRMCreate(&d3drm);
3049 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
3051 hr = DirectDrawCreateClipper(0, &pClipper, NULL);
3052 ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface (hr = %x)\n", hr);
3054 hr = IDirectDrawClipper_SetHWnd(pClipper, 0, window);
3055 ok(hr == DD_OK, "Cannot set HWnd to Clipper (hr = %x)\n", hr);
3057 memcpy(&driver, &IID_IDirect3DRGBDevice, sizeof(GUID));
3058 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm, pClipper, &driver, rc.right, rc.bottom, &device);
3059 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMDevice interface (hr = %x)\n", hr);
3061 test_class_name((IDirect3DRMObject *)device, "Device");
3062 test_object_name((IDirect3DRMObject *)device);
3064 /* WinDevice */
3065 if (FAILED(hr = IDirect3DRMDevice_QueryInterface(device, &IID_IDirect3DRMWinDevice, (void **)&win_device)))
3067 win_skip("Cannot get IDirect3DRMWinDevice interface (hr = %x), skipping tests\n", hr);
3068 goto cleanup;
3071 test_class_name((IDirect3DRMObject *)win_device, "Device");
3072 test_object_name((IDirect3DRMObject *)win_device);
3073 IDirect3DRMWinDevice_Release(win_device);
3075 cleanup:
3076 IDirect3DRMDevice_Release(device);
3077 IDirectDrawClipper_Release(pClipper);
3079 IDirect3DRM_Release(d3drm);
3080 DestroyWindow(window);
3083 static void test_frame_transform(void)
3085 IDirect3DRMFrame *frame, *subframe;
3086 D3DRMMATRIX4D matrix, add_matrix;
3087 IDirect3DRM *d3drm;
3088 D3DVECTOR v1, v2;
3089 HRESULT hr;
3091 hr = Direct3DRMCreate(&d3drm);
3092 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3094 hr = IDirect3DRM_CreateFrame(d3drm, NULL, &frame);
3095 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3097 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3098 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3099 expect_matrix(matrix,
3100 1.0f, 0.0f, 0.0f, 0.0f,
3101 0.0f, 1.0f, 0.0f, 0.0f,
3102 0.0f, 0.0f, 1.0f, 0.0f,
3103 0.0f, 0.0f, 0.0f, 1.0f, 0);
3105 memcpy(add_matrix, identity, sizeof(add_matrix));
3106 add_matrix[3][0] = 3.0f;
3107 add_matrix[3][1] = 3.0f;
3108 add_matrix[3][2] = 3.0f;
3110 frame_set_transform(frame,
3111 2.0f, 0.0f, 0.0f, 0.0f,
3112 0.0f, 2.0f, 0.0f, 0.0f,
3113 0.0f, 0.0f, 2.0f, 0.0f,
3114 0.0f, 0.0f, 0.0f, 1.0f);
3115 hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_REPLACE, add_matrix);
3116 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3117 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3118 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3119 expect_matrix(matrix,
3120 1.0f, 0.0f, 0.0f, 0.0f,
3121 0.0f, 1.0f, 0.0f, 0.0f,
3122 0.0f, 0.0f, 1.0f, 0.0f,
3123 3.0f, 3.0f, 3.0f, 1.0f, 1);
3125 frame_set_transform(frame,
3126 2.0f, 0.0f, 0.0f, 0.0f,
3127 0.0f, 2.0f, 0.0f, 0.0f,
3128 0.0f, 0.0f, 2.0f, 0.0f,
3129 0.0f, 0.0f, 0.0f, 1.0f);
3130 hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_BEFORE, add_matrix);
3131 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3132 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3133 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3134 expect_matrix(matrix,
3135 2.0f, 0.0f, 0.0f, 0.0f,
3136 0.0f, 2.0f, 0.0f, 0.0f,
3137 0.0f, 0.0f, 2.0f, 0.0f,
3138 6.0f, 6.0f, 6.0f, 1.0f, 1);
3140 frame_set_transform(frame,
3141 2.0f, 0.0f, 0.0f, 0.0f,
3142 0.0f, 2.0f, 0.0f, 0.0f,
3143 0.0f, 0.0f, 2.0f, 0.0f,
3144 0.0f, 0.0f, 0.0f, 1.0f);
3145 hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_AFTER, add_matrix);
3146 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3147 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3148 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3149 expect_matrix(matrix,
3150 2.0f, 0.0f, 0.0f, 0.0f,
3151 0.0f, 2.0f, 0.0f, 0.0f,
3152 0.0f, 0.0f, 2.0f, 0.0f,
3153 3.0f, 3.0f, 3.0f, 1.0f, 1);
3155 add_matrix[3][3] = 2.0f;
3156 hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_REPLACE, add_matrix);
3157 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr);
3159 frame_set_transform(frame,
3160 2.0f, 0.0f, 0.0f, 0.0f,
3161 0.0f, 2.0f, 0.0f, 0.0f,
3162 0.0f, 0.0f, 2.0f, 0.0f,
3163 0.0f, 0.0f, 0.0f, 1.0f);
3164 hr = IDirect3DRMFrame_AddTranslation(frame, D3DRMCOMBINE_REPLACE, 3.0f, 3.0f, 3.0f);
3165 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3166 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3167 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3168 expect_matrix(matrix,
3169 1.0f, 0.0f, 0.0f, 0.0f,
3170 0.0f, 1.0f, 0.0f, 0.0f,
3171 0.0f, 0.0f, 1.0f, 0.0f,
3172 3.0f, 3.0f, 3.0f, 1.0f, 1);
3174 frame_set_transform(frame,
3175 2.0f, 0.0f, 0.0f, 0.0f,
3176 0.0f, 2.0f, 0.0f, 0.0f,
3177 0.0f, 0.0f, 2.0f, 0.0f,
3178 0.0f, 0.0f, 0.0f, 1.0f);
3179 hr = IDirect3DRMFrame_AddTranslation(frame, D3DRMCOMBINE_BEFORE, 3.0f, 3.0f, 3.0f);
3180 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3181 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3182 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3183 expect_matrix(matrix,
3184 2.0f, 0.0f, 0.0f, 0.0f,
3185 0.0f, 2.0f, 0.0f, 0.0f,
3186 0.0f, 0.0f, 2.0f, 0.0f,
3187 6.0f, 6.0f, 6.0f, 1.0f, 1);
3189 frame_set_transform(frame,
3190 2.0f, 0.0f, 0.0f, 0.0f,
3191 0.0f, 2.0f, 0.0f, 0.0f,
3192 0.0f, 0.0f, 2.0f, 0.0f,
3193 0.0f, 0.0f, 0.0f, 1.0f);
3194 hr = IDirect3DRMFrame_AddTranslation(frame, D3DRMCOMBINE_AFTER, 3.0f, 3.0f, 3.0f);
3195 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3196 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3197 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3198 expect_matrix(matrix,
3199 2.0f, 0.0f, 0.0f, 0.0f,
3200 0.0f, 2.0f, 0.0f, 0.0f,
3201 0.0f, 0.0f, 2.0f, 0.0f,
3202 3.0f, 3.0f, 3.0f, 1.0f, 1);
3204 frame_set_transform(frame,
3205 1.0f, 0.0f, 0.0f, 0.0f,
3206 0.0f, 1.0f, 0.0f, 0.0f,
3207 0.0f, 0.0f, 1.0f, 0.0f,
3208 3.0f, 3.0f, 3.0f, 1.0f);
3209 hr = IDirect3DRMFrame_AddScale(frame, D3DRMCOMBINE_REPLACE, 2.0f, 2.0f, 2.0f);
3210 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3211 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3212 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3213 expect_matrix(matrix,
3214 2.0f, 0.0f, 0.0f, 0.0f,
3215 0.0f, 2.0f, 0.0f, 0.0f,
3216 0.0f, 0.0f, 2.0f, 0.0f,
3217 0.0f, 0.0f, 0.0f, 1.0f, 1);
3219 frame_set_transform(frame,
3220 1.0f, 0.0f, 0.0f, 0.0f,
3221 0.0f, 1.0f, 0.0f, 0.0f,
3222 0.0f, 0.0f, 1.0f, 0.0f,
3223 3.0f, 3.0f, 3.0f, 1.0f);
3224 hr = IDirect3DRMFrame_AddScale(frame, D3DRMCOMBINE_BEFORE, 2.0f, 2.0f, 2.0f);
3225 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3226 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3227 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3228 expect_matrix(matrix,
3229 2.0f, 0.0f, 0.0f, 0.0f,
3230 0.0f, 2.0f, 0.0f, 0.0f,
3231 0.0f, 0.0f, 2.0f, 0.0f,
3232 3.0f, 3.0f, 3.0f, 1.0f, 1);
3234 frame_set_transform(frame,
3235 1.0f, 0.0f, 0.0f, 0.0f,
3236 0.0f, 1.0f, 0.0f, 0.0f,
3237 0.0f, 0.0f, 1.0f, 0.0f,
3238 3.0f, 3.0f, 3.0f, 1.0f);
3239 hr = IDirect3DRMFrame_AddScale(frame, D3DRMCOMBINE_AFTER, 2.0f, 2.0f, 2.0f);
3240 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3241 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3242 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3243 expect_matrix(matrix,
3244 2.0f, 0.0f, 0.0f, 0.0f,
3245 0.0f, 2.0f, 0.0f, 0.0f,
3246 0.0f, 0.0f, 2.0f, 0.0f,
3247 6.0f, 6.0f, 6.0f, 1.0f, 1);
3249 frame_set_transform(frame,
3250 1.0f, 0.0f, 0.0f, 0.0f,
3251 0.0f, 1.0f, 0.0f, 0.0f,
3252 0.0f, 0.0f, 1.0f, 0.0f,
3253 3.0f, 3.0f, 3.0f, 1.0f);
3254 hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 1.0f, 0.0f, 0.0f, M_PI_2);
3255 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3256 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3257 matrix_sanitise(matrix);
3258 expect_matrix(matrix,
3259 1.0f, 0.0f, 0.0f, 0.0f,
3260 0.0f, 0.0f, 1.0f, 0.0f,
3261 0.0f, -1.0f, 0.0f, 0.0f,
3262 0.0f, 0.0f, 0.0f, 1.0f, 1);
3264 frame_set_transform(frame,
3265 1.0f, 0.0f, 0.0f, 0.0f,
3266 0.0f, 1.0f, 0.0f, 0.0f,
3267 0.0f, 0.0f, 1.0f, 0.0f,
3268 3.0f, 3.0f, 3.0f, 1.0f);
3269 hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_BEFORE, 1.0f, 0.0f, 0.0f, M_PI_2);
3270 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3271 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3272 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3273 matrix_sanitise(matrix);
3274 expect_matrix(matrix,
3275 1.0f, 0.0f, 0.0f, 0.0f,
3276 0.0f, 0.0f, 1.0f, 0.0f,
3277 0.0f, -1.0f, 0.0f, 0.0f,
3278 3.0f, 3.0f, 3.0f, 1.0f, 1);
3280 frame_set_transform(frame,
3281 1.0f, 0.0f, 0.0f, 0.0f,
3282 0.0f, 1.0f, 0.0f, 0.0f,
3283 0.0f, 0.0f, 1.0f, 0.0f,
3284 3.0f, 3.0f, 3.0f, 1.0f);
3285 hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_AFTER, 1.0f, 0.0f, 0.0f, M_PI_2);
3286 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3287 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3288 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3289 matrix_sanitise(matrix);
3290 expect_matrix(matrix,
3291 1.0f, 0.0f, 0.0f, 0.0f,
3292 0.0f, 0.0f, 1.0f, 0.0f,
3293 0.0f, -1.0f, 0.0f, 0.0f,
3294 3.0f, -3.0f, 3.0f, 1.0f, 1);
3296 hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 0.0f, 0.0f, 1.0f, M_PI_2);
3297 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3298 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3299 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3300 matrix_sanitise(matrix);
3301 expect_matrix(matrix,
3302 0.0f, 1.0f, 0.0f, 0.0f,
3303 -1.0f, 0.0f, 0.0f, 0.0f,
3304 0.0f, 0.0f, 1.0f, 0.0f,
3305 0.0f, 0.0f, 0.0f, 1.0f, 1);
3307 hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 0.0f, 0.0f, 0.0f, M_PI_2);
3308 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3309 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3310 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3311 matrix_sanitise(matrix);
3312 expect_matrix(matrix,
3313 1.0f, 0.0f, 0.0f, 0.0f,
3314 0.0f, 0.0f, 1.0f, 0.0f,
3315 0.0f, -1.0f, 0.0f, 0.0f,
3316 0.0f, 0.0f, 0.0f, 1.0f, 1);
3318 frame_set_transform(frame,
3319 2.0f, 0.0f, 0.0f, 0.0f,
3320 0.0f, 4.0f, 0.0f, 0.0f,
3321 0.0f, 0.0f, 8.0f, 0.0f,
3322 64.0f, 64.0f, 64.0f, 1.0f);
3323 hr = IDirect3DRM_CreateFrame(d3drm, frame, &subframe);
3324 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3325 frame_set_transform(subframe,
3326 1.0f, 0.0f, 0.0f, 0.0f,
3327 0.0f, 1.0f, 0.0f, 0.0f,
3328 0.0f, 0.0f, 1.0f, 0.0f,
3329 11.0f, 11.0f, 11.0f, 1.0f);
3330 set_vector(&v1, 3.0f, 5.0f, 7.0f);
3332 hr = IDirect3DRMFrame_Transform(frame, &v2, &v1);
3333 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3334 expect_vector(&v2, 70.0f, 84.0f, 120.0f, 1);
3336 hr = IDirect3DRMFrame_Transform(subframe, &v2, &v1);
3337 ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
3338 expect_vector(&v2, 92.0f, 128.0f, 208.0f, 1);
3340 IDirect3DRMFrame_Release(subframe);
3341 IDirect3DRMFrame_Release(frame);
3342 IDirect3DRM_Release(d3drm);
3345 static int nb_objects = 0;
3346 static const GUID* refiids[] =
3348 &IID_IDirect3DRMMeshBuilder,
3349 &IID_IDirect3DRMMeshBuilder,
3350 &IID_IDirect3DRMFrame,
3351 &IID_IDirect3DRMMaterial /* Not taken into account and not notified */
3354 static void __cdecl object_load_callback(IDirect3DRMObject *object, REFIID objectguid, void *arg)
3356 ok(object != NULL, "Arg 1 should not be null\n");
3357 ok(IsEqualGUID(objectguid, refiids[nb_objects]), "Arg 2 is incorrect\n");
3358 ok(arg == (void *)0xdeadbeef, "Arg 3 should be 0xdeadbeef (got %p)\n", arg);
3359 nb_objects++;
3362 static void test_d3drm_load(void)
3364 HRESULT hr;
3365 IDirect3DRM *d3drm;
3366 D3DRMLOADMEMORY info;
3367 const GUID* req_refiids[] = { &IID_IDirect3DRMMeshBuilder, &IID_IDirect3DRMFrame, &IID_IDirect3DRMMaterial };
3369 hr = Direct3DRMCreate(&d3drm);
3370 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
3372 info.lpMemory = data_d3drm_load;
3373 info.dSize = strlen(data_d3drm_load);
3374 hr = IDirect3DRM_Load(d3drm, &info, NULL, (GUID **)req_refiids, 3, D3DRMLOAD_FROMMEMORY,
3375 object_load_callback, (void *)0xdeadbeef, NULL, NULL, NULL);
3376 ok(hr == D3DRM_OK, "Cannot load data (hr = %x)\n", hr);
3377 ok(nb_objects == 3, "Should have loaded 3 objects (got %d)\n", nb_objects);
3379 IDirect3DRM_Release(d3drm);
3382 IDirect3DRMMeshBuilder *mesh_builder = NULL;
3384 static void __cdecl object_load_callback_frame(IDirect3DRMObject *object, REFIID object_guid, void *arg)
3386 HRESULT hr;
3387 IDirect3DRMFrame *frame;
3388 IDirect3DRMVisualArray *array;
3389 IDirect3DRMVisual *visual;
3390 ULONG size;
3391 char name[128];
3393 hr = IDirect3DRMObject_QueryInterface(object, &IID_IDirect3DRMFrame, (void**)&frame);
3394 ok(hr == D3DRM_OK, "IDirect3DRMObject_QueryInterface returned %x\n", hr);
3396 hr = IDirect3DRMFrame_GetVisuals(frame, &array);
3397 ok(hr == D3DRM_OK, "IDirect3DRMFrame_GetVisuals returned %x\n", hr);
3399 size = IDirect3DRMVisualArray_GetSize(array);
3400 ok(size == 1, "Wrong size %u returned, expected 1\n", size);
3402 hr = IDirect3DRMVisualArray_GetElement(array, 0, &visual);
3403 ok(hr == D3DRM_OK, "IDirect3DRMVisualArray_GetElement returned %x\n", hr);
3405 hr = IDirect3DRMVisual_QueryInterface(visual, &IID_IDirect3DRMMeshBuilder, (void**)&mesh_builder);
3406 ok(hr == D3DRM_OK, "IDirect3DRMVisualArray_GetSize returned %x\n", hr);
3408 size = sizeof(name);
3409 hr = IDirect3DRMMeshBuilder_GetName(mesh_builder, &size, name);
3410 ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_GetName returned %x\n", hr);
3411 ok(!strcmp(name, "mesh1"), "Wrong name %s, expected mesh1\n", name);
3413 IDirect3DRMVisual_Release(visual);
3414 IDirect3DRMVisualArray_Release(array);
3415 IDirect3DRMFrame_Release(frame);
3418 struct {
3419 int vertex_count;
3420 int face_count;
3421 int vertex_per_face;
3422 int face_data_size;
3423 DWORD color;
3424 float power;
3425 float specular[3];
3426 float emissive[3];
3427 } groups[3] = {
3428 { 4, 3, 3, 9, 0x4c0000ff, 30.0f, { 0.31f, 0.32f, 0.33f }, { 0.34f, 0.35f, 0.36f } },
3429 { 4, 2, 3, 6, 0x3300ff00, 20.0f, { 0.21f, 0.22f, 0.23f }, { 0.24f, 0.25f, 0.26f } },
3430 { 3, 1, 3, 3, 0x19ff0000, 10.0f, { 0.11f, 0.12f, 0.13f }, { 0.14f, 0.15f, 0.16f } }
3433 static void test_frame_mesh_materials(void)
3435 HRESULT hr;
3436 IDirect3DRM *d3drm;
3437 D3DRMLOADMEMORY info;
3438 const GUID *req_refiids[] = { &IID_IDirect3DRMFrame };
3439 IDirect3DRMMesh *mesh;
3440 ULONG size;
3441 IDirect3DRMMaterial *material;
3442 IDirect3DRMTexture *texture;
3443 int i;
3445 hr = Direct3DRMCreate(&d3drm);
3446 ok(hr == D3DRM_OK, "Direct3DRMCreate returned %x\n", hr);
3448 info.lpMemory = data_frame_mesh_materials;
3449 info.dSize = strlen(data_frame_mesh_materials);
3450 hr = IDirect3DRM_Load(d3drm, &info, NULL, (GUID**)req_refiids, 1, D3DRMLOAD_FROMMEMORY, object_load_callback_frame, (void*)0xdeadbeef, NULL, NULL, NULL);
3451 ok(hr == D3DRM_OK, "Cannot load data (hr = %x)\n", hr);
3453 hr = IDirect3DRMMeshBuilder_CreateMesh(mesh_builder, &mesh);
3454 ok(hr == D3DRM_OK, "IDirect3DRMMeshBuilder_CreateMesh returned %x\n", hr);
3456 size = IDirect3DRMMesh_GetGroupCount(mesh);
3457 ok(size == 3, "Wrong size %u returned, expected 3\n", size);
3459 for (i = 0; i < size; i++)
3461 D3DVALUE red, green, blue, power;
3462 D3DCOLOR color;
3463 unsigned vertex_count, face_count, vertex_per_face;
3464 DWORD face_data_size;
3466 hr = IDirect3DRMMesh_GetGroup(mesh, i, &vertex_count, &face_count, &vertex_per_face, &face_data_size, NULL);
3467 ok(hr == D3DRM_OK, "Group %d: IDirect3DRMMesh_GetGroup returned %x\n", i, hr);
3468 ok(vertex_count == groups[i].vertex_count, "Group %d: Wrong vertex count %d, expected %d\n", i, vertex_count, groups[i].vertex_count);
3469 ok(face_count == groups[i].face_count, "Group %d: Wrong face count %d; expected %d\n", i, face_count, groups[i].face_count);
3470 ok(vertex_per_face == groups[i].vertex_per_face, "Group %d: Wrong vertex per face %d, expected %d\n", i, vertex_per_face, groups[i].vertex_per_face);
3471 ok(face_data_size == groups[i].face_data_size, "Group %d: Wrong face data size %d, expected %d\n", i, face_data_size, groups[i].face_data_size);
3473 color = IDirect3DRMMesh_GetGroupColor(mesh, i);
3474 ok(color == groups[i].color, "Group %d: Wrong color %x, expected %x\n", i, color, groups[i].color);
3476 hr = IDirect3DRMMesh_GetGroupMaterial(mesh, i, &material);
3477 ok(hr == D3DRM_OK, "Group %d: IDirect3DRMMesh_GetGroupMaterial returned %x\n", i, hr);
3478 ok(material != NULL, "Group %d: No material\n", i);
3479 power = IDirect3DRMMaterial_GetPower(material);
3480 ok(power == groups[i].power, "Group %d: Wrong power %f, expected %f\n", i, power, groups[i].power);
3481 hr = IDirect3DRMMaterial_GetSpecular(material, &red, &green, &blue);
3482 ok(hr == D3DRM_OK, "Group %d: IDirect3DRMMaterial_GetSpecular returned %x\n", i, hr);
3483 ok(red == groups[i].specular[0], "Group %d: Wrong specular red %f, expected %f\n", i, red, groups[i].specular[0]);
3484 ok(green == groups[i].specular[1], "Group %d: Wrong specular green %f, pD3DRMexpected %f\n", i, green, groups[i].specular[1]);
3485 ok(blue == groups[i].specular[2], "Group %d: Wrong specular blue %f, expected %f\n", i, blue, groups[i].specular[2]);
3486 hr = IDirect3DRMMaterial_GetEmissive(material, &red, &green, &blue);
3487 ok(hr == D3DRM_OK, "Group %d: IDirect3DRMMaterial_GetEmissive returned %x\n", i, hr);
3488 ok(red == groups[i].emissive[0], "Group %d: Wrong emissive red %f, expected %f\n", i, red, groups[i].emissive[0]);
3489 ok(green == groups[i].emissive[1], "Group %d: Wrong emissive green %f, expected %f\n", i, green, groups[i].emissive[1]);
3490 ok(blue == groups[i].emissive[2], "Group %d: Wrong emissive blue %f, expected %f\n", i, blue, groups[i].emissive[2]);
3492 hr = IDirect3DRMMesh_GetGroupTexture(mesh, i, &texture);
3493 ok(hr == D3DRM_OK, "Group %d: IDirect3DRMMesh_GetGroupTexture returned %x\n", i, hr);
3494 ok(!texture, "Group %d: Unexpected texture\n", i);
3496 if (material)
3497 IDirect3DRMMaterial_Release(material);
3498 if (texture)
3499 IDirect3DRMTexture_Release(texture);
3502 IDirect3DRMMesh_Release(mesh);
3503 IDirect3DRMMeshBuilder_Release(mesh_builder);
3504 IDirect3DRM_Release(d3drm);
3507 struct qi_test
3509 REFIID iid;
3510 REFIID refcount_iid;
3511 REFIID vtable_iid;
3512 HRESULT hr;
3515 static void test_qi(const char *test_name, IUnknown *base_iface,
3516 REFIID refcount_iid, const struct qi_test *tests, UINT entry_count)
3518 ULONG refcount, expected_refcount;
3519 IUnknown *iface1, *iface2;
3520 HRESULT hr;
3521 UINT i, j;
3523 for (i = 0; i < entry_count; ++i)
3525 hr = IUnknown_QueryInterface(base_iface, tests[i].iid, (void **)&iface1);
3526 ok(hr == tests[i].hr, "Got hr %#x for test \"%s\" %u.\n", hr, test_name, i);
3527 if (SUCCEEDED(hr))
3529 for (j = 0; j < entry_count; ++j)
3531 hr = IUnknown_QueryInterface(iface1, tests[j].iid, (void **)&iface2);
3532 ok(hr == tests[j].hr, "Got hr %#x for test \"%s\" %u, %u.\n", hr, test_name, i, j);
3533 if (SUCCEEDED(hr))
3535 expected_refcount = 0;
3536 if (IsEqualGUID(refcount_iid, tests[j].refcount_iid))
3537 ++expected_refcount;
3538 if (IsEqualGUID(tests[i].refcount_iid, tests[j].refcount_iid))
3539 ++expected_refcount;
3540 refcount = IUnknown_Release(iface2);
3541 ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
3542 refcount, test_name, i, j, expected_refcount);
3543 if (tests[i].vtable_iid && tests[j].vtable_iid && IsEqualGUID(tests[i].vtable_iid, tests[j].vtable_iid))
3544 ok(iface1 == iface2,
3545 "Expected iface1 == iface2 for test \"%s\" %u, %u. Got iface1 = %p, iface 2 = %p.\n",
3546 test_name, i, j, iface1, iface2);
3547 else if (tests[i].vtable_iid && tests[j].vtable_iid)
3548 ok(iface1 != iface2,
3549 "Expected iface1 != iface2 for test \"%s\" %u, %u. Got iface1 == iface2 == %p.\n",
3550 test_name, i, j, iface1);
3554 expected_refcount = 0;
3555 if (IsEqualGUID(refcount_iid, tests[i].refcount_iid))
3556 ++expected_refcount;
3557 refcount = IUnknown_Release(iface1);
3558 ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, expected %u.\n",
3559 refcount, test_name, i, expected_refcount);
3564 static void test_d3drm_qi(void)
3566 static const struct qi_test tests[] =
3568 { &IID_IDirect3DRM3, &IID_IDirect3DRM3, &IID_IDirect3DRM3, S_OK },
3569 { &IID_IDirect3DRM2, &IID_IDirect3DRM2, &IID_IDirect3DRM2, S_OK },
3570 { &IID_IDirect3DRM, &IID_IDirect3DRM, &IID_IDirect3DRM, S_OK },
3571 { &IID_IDirect3DRMDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3572 { &IID_IDirect3DRMObject, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3573 { &IID_IDirect3DRMObject2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3574 { &IID_IDirect3DRMDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3575 { &IID_IDirect3DRMDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3576 { &IID_IDirect3DRMViewport, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3577 { &IID_IDirect3DRMViewport2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3578 { &IID_IDirect3DRMFrame, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3579 { &IID_IDirect3DRMFrame2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3580 { &IID_IDirect3DRMFrame3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3581 { &IID_IDirect3DRMVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3582 { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3583 { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3584 { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3585 { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3586 { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3587 { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3588 { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3589 { &IID_IDirect3DRMTexture, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3590 { &IID_IDirect3DRMTexture2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3591 { &IID_IDirect3DRMTexture3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3592 { &IID_IDirect3DRMWrap, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3593 { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3594 { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3595 { &IID_IDirect3DRMAnimation, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3596 { &IID_IDirect3DRMAnimation2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3597 { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3598 { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3599 { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3600 { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3601 { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3602 { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3603 { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3604 { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3605 { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3606 { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3607 { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3608 { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3609 { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3610 { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3611 { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3612 { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3613 { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3614 { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3615 { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3616 { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3617 { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3618 { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3619 { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3620 { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3621 { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3622 { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3623 { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3624 { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3625 { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3626 { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3627 { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3628 { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3629 { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3630 { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3631 { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3632 { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3633 { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3634 { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3635 { &IID_IUnknown, &IID_IDirect3DRM, &IID_IDirect3DRM, S_OK },
3637 HRESULT hr;
3638 IDirect3DRM *d3drm;
3640 hr = Direct3DRMCreate(&d3drm);
3641 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
3643 test_qi("d3drm_qi", (IUnknown *)d3drm, &IID_IDirect3DRM, tests, ARRAY_SIZE(tests));
3645 IDirect3DRM_Release(d3drm);
3648 static void test_frame_qi(void)
3650 static const struct qi_test tests[] =
3652 { &IID_IDirect3DRMFrame3, &IID_IUnknown, &IID_IDirect3DRMFrame3, S_OK },
3653 { &IID_IDirect3DRMFrame2, &IID_IUnknown, &IID_IDirect3DRMFrame2, S_OK },
3654 { &IID_IDirect3DRMFrame, &IID_IUnknown, &IID_IDirect3DRMFrame, S_OK },
3655 { &IID_IDirect3DRM, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3656 { &IID_IDirect3DRMDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3657 { &IID_IDirect3DRMObject, &IID_IUnknown, &IID_IDirect3DRMFrame, S_OK },
3658 { &IID_IDirect3DRMDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3659 { &IID_IDirect3DRMDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3660 { &IID_IDirect3DRMViewport, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3661 { &IID_IDirect3DRMViewport2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3662 { &IID_IDirect3DRM3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3663 { &IID_IDirect3DRM2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3664 { &IID_IDirect3DRMVisual, &IID_IUnknown, &IID_IDirect3DRMFrame, S_OK },
3665 { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3666 { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3667 { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3668 { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3669 { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3670 { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3671 { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3672 { &IID_IDirect3DRMTexture, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3673 { &IID_IDirect3DRMTexture2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3674 { &IID_IDirect3DRMTexture3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3675 { &IID_IDirect3DRMWrap, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3676 { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3677 { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3678 { &IID_IDirect3DRMAnimation, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3679 { &IID_IDirect3DRMAnimation2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3680 { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3681 { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3682 { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3683 { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3684 { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3685 { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3686 { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3687 { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3688 { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3689 { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3690 { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3691 { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3692 { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3693 { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3694 { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3695 { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3696 { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3697 { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3698 { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3699 { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3700 { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3701 { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3702 { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3703 { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3704 { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3705 { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3706 { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3707 { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3708 { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3709 { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3710 { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3711 { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3712 { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3713 { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3714 { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3715 { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3716 { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3717 { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3718 { &IID_IUnknown, &IID_IUnknown, NULL, S_OK },
3720 HRESULT hr;
3721 IDirect3DRM *d3drm1;
3722 IDirect3DRM2 *d3drm2;
3723 IDirect3DRM3 *d3drm3;
3724 IDirect3DRMFrame *frame1;
3725 IDirect3DRMFrame2 *frame2;
3726 IDirect3DRMFrame3 *frame3;
3727 IUnknown *unknown;
3729 hr = Direct3DRMCreate(&d3drm1);
3730 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
3732 hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &frame1);
3733 ok(hr == D3DRM_OK, "Failed to create frame1 (hr = %x)\n", hr);
3734 hr = IDirect3DRMFrame_QueryInterface(frame1, &IID_IUnknown, (void **)&unknown);
3735 ok(hr == D3DRM_OK, "Failed to create IUnknown from frame1 (hr = %x)\n", hr);
3736 IDirect3DRMFrame_Release(frame1);
3737 test_qi("frame1_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
3738 IUnknown_Release(unknown);
3740 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
3741 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM2 interface (hr = %x).\n", hr);
3742 hr = IDirect3DRM2_CreateFrame(d3drm2, NULL, &frame2);
3743 ok(hr == D3DRM_OK, "Failed to create frame2 (hr = %x)\n", hr);
3744 hr = IDirect3DRMFrame2_QueryInterface(frame2, &IID_IUnknown, (void **)&unknown);
3745 ok(hr == D3DRM_OK, "Failed to create IUnknown from frame2 (hr = %x)\n", hr);
3746 IDirect3DRMFrame2_Release(frame2);
3747 test_qi("frame2_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
3748 IUnknown_Release(unknown);
3750 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
3751 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface (hr = %x).\n", hr);
3752 hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &frame3);
3753 ok(hr == D3DRM_OK, "Failed to create frame3 (hr = %x)\n", hr);
3754 hr = IDirect3DRMFrame3_QueryInterface(frame3, &IID_IUnknown, (void **)&unknown);
3755 ok(hr == D3DRM_OK, "Failed to create IUnknown from frame3 (hr = %x)\n", hr);
3756 IDirect3DRMFrame3_Release(frame3);
3757 test_qi("frame3_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
3758 IUnknown_Release(unknown);
3760 IDirect3DRM3_Release(d3drm3);
3761 IDirect3DRM2_Release(d3drm2);
3762 IDirect3DRM_Release(d3drm1);
3765 static void test_device_qi(void)
3767 static const struct qi_test tests[] =
3769 { &IID_IDirect3DRM3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3770 { &IID_IDirect3DRM2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3771 { &IID_IDirect3DRM, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3772 { &IID_IDirect3DRMDevice, &IID_IUnknown, &IID_IDirect3DRMDevice, S_OK, },
3773 { &IID_IDirect3DRMDevice2, &IID_IUnknown, &IID_IDirect3DRMDevice2, S_OK, },
3774 { &IID_IDirect3DRMDevice3, &IID_IUnknown, &IID_IDirect3DRMDevice3, S_OK, },
3775 { &IID_IDirect3DRMWinDevice, &IID_IUnknown, &IID_IDirect3DRMWinDevice, S_OK, },
3776 { &IID_IDirect3DRMObject, &IID_IUnknown, &IID_IDirect3DRMDevice, S_OK, },
3777 { &IID_IDirect3DRMViewport, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3778 { &IID_IDirect3DRMViewport2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3779 { &IID_IDirect3DRMFrame, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3780 { &IID_IDirect3DRMFrame2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3781 { &IID_IDirect3DRMFrame3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3782 { &IID_IDirect3DRMVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3783 { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3784 { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3785 { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3786 { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3787 { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3788 { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3789 { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3790 { &IID_IDirect3DRMTexture, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3791 { &IID_IDirect3DRMTexture2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3792 { &IID_IDirect3DRMTexture3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3793 { &IID_IDirect3DRMWrap, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3794 { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3795 { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3796 { &IID_IDirect3DRMAnimation, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3797 { &IID_IDirect3DRMAnimation2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3798 { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3799 { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3800 { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3801 { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3802 { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3803 { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3804 { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3805 { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3806 { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3807 { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3808 { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3809 { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3810 { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3811 { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3812 { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3813 { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3814 { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3815 { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3816 { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3817 { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3818 { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3819 { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3820 { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3821 { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3822 { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3823 { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3824 { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3825 { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3826 { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3827 { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3828 { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3829 { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3830 { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3831 { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3832 { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3833 { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3834 { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3835 { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3836 { &IID_IUnknown, &IID_IUnknown, NULL, S_OK, },
3838 HRESULT hr;
3839 IDirect3DRM *d3drm1;
3840 IDirect3DRM2 *d3drm2;
3841 IDirect3DRM3 *d3drm3;
3842 IDirectDrawClipper *clipper;
3843 IDirect3DRMDevice *device1;
3844 IDirect3DRMDevice2 *device2;
3845 IDirect3DRMDevice3 *device3;
3846 IUnknown *unknown;
3847 HWND window;
3848 GUID driver;
3849 RECT rc;
3851 window = create_window();
3852 GetClientRect(window, &rc);
3853 hr = DirectDrawCreateClipper(0, &clipper, NULL);
3854 ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface (hr = %x)\n", hr);
3855 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
3856 ok(hr == DD_OK, "Cannot set HWnd to Clipper (hr = %x)\n", hr);
3858 hr = Direct3DRMCreate(&d3drm1);
3859 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
3860 memcpy(&driver, &IID_IDirect3DRGBDevice, sizeof(GUID));
3861 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, rc.right, rc.bottom, &device1);
3862 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface (hr = %x)\n", hr);
3863 hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IUnknown, (void **)&unknown);
3864 ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMDevice (hr = %x)\n", hr);
3865 IDirect3DRMDevice_Release(device1);
3866 test_qi("device1_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
3867 IUnknown_Release(unknown);
3869 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
3870 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface (hr = %x).\n", hr);
3871 hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, clipper, &driver, rc.right, rc.bottom, &device2);
3872 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice2 interface (hr = %x)\n", hr);
3873 hr = IDirect3DRMDevice2_QueryInterface(device2, &IID_IUnknown, (void **)&unknown);
3874 ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMDevice2 (hr = %x)\n", hr);
3875 IDirect3DRMDevice2_Release(device2);
3876 test_qi("device2_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
3877 IUnknown_Release(unknown);
3879 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
3880 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface (hr = %x).\n", hr);
3881 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, rc.right, rc.bottom, &device3);
3882 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface (hr = %x)\n", hr);
3883 hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IUnknown, (void **)&unknown);
3884 ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMDevice3 (hr = %x)\n", hr);
3885 IDirect3DRMDevice3_Release(device3);
3886 test_qi("device3_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
3887 IUnknown_Release(unknown);
3889 IDirectDrawClipper_Release(clipper);
3890 IDirect3DRM3_Release(d3drm3);
3891 IDirect3DRM2_Release(d3drm2);
3892 IDirect3DRM_Release(d3drm1);
3893 DestroyWindow(window);
3897 static HRESULT CALLBACK surface_callback(IDirectDrawSurface *surface, DDSURFACEDESC *desc, void *context)
3899 IDirectDrawSurface **primary = context;
3901 if (desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
3903 *primary = surface;
3904 return DDENUMRET_CANCEL;
3906 IDirectDrawSurface_Release(surface);
3908 return DDENUMRET_OK;
3911 static void test_create_device_from_clipper1(void)
3913 DDSCAPS caps = { DDSCAPS_ZBUFFER };
3914 IDirect3DRM *d3drm1 = NULL;
3915 IDirectDraw *ddraw = NULL;
3916 IUnknown *unknown = NULL;
3917 IDirect3DRMDevice *device1 = (IDirect3DRMDevice *)0xdeadbeef;
3918 IDirect3DDevice *d3ddevice1 = NULL;
3919 IDirectDrawClipper *clipper = NULL, *d3drm_clipper = NULL;
3920 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_primary = NULL;
3921 IDirectDrawSurface7 *surface7 = NULL;
3922 DDSURFACEDESC desc, surface_desc;
3923 DWORD expected_flags, ret_val;
3924 HWND window;
3925 GUID driver = IID_IDirect3DRGBDevice;
3926 HRESULT hr;
3927 ULONG ref1, ref2, cref1, cref2;
3928 RECT rc;
3930 window = create_window();
3931 GetClientRect(window, &rc);
3932 hr = DirectDrawCreateClipper(0, &clipper, NULL);
3933 ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface (hr = %x).\n", hr);
3934 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
3935 ok(hr == DD_OK, "Cannot set HWnd to Clipper (hr = %x).\n", hr);
3937 hr = Direct3DRMCreate(&d3drm1);
3938 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr);
3939 ref1 = get_refcount((IUnknown *)d3drm1);
3940 cref1 = get_refcount((IUnknown *)clipper);
3942 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, 0, 0, &device1);
3943 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
3944 ok(device1 == NULL, "Expected device returned == NULL, got %p.\n", device1);
3946 /* If NULL is passed for clipper, CreateDeviceFromClipper returns D3DRMERR_BADVALUE */
3947 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, NULL, &driver, 300, 200, &device1);
3948 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
3950 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, 300, 200, NULL);
3951 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
3953 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, 300, 200, &device1);
3954 ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice interface (hr = %x).\n", hr);
3955 ref2 = get_refcount((IUnknown *)d3drm1);
3956 ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %u , ref2 = %u.\n", ref1, ref2);
3957 cref2 = get_refcount((IUnknown *)clipper);
3958 ok(cref2 > cref1, "expected cref2 > cref1, got cref1 = %u , cref2 = %u.\n", cref1, cref2);
3959 ret_val = IDirect3DRMDevice_GetWidth(device1);
3960 ok(ret_val == 300, "Expected device width = 300, got %u.\n", ret_val);
3961 ret_val = IDirect3DRMDevice_GetHeight(device1);
3962 ok(ret_val == 200, "Expected device height == 200, got %u.\n", ret_val);
3964 /* Fetch immediate mode device in order to access render target */
3965 hr = IDirect3DRMDevice_GetDirect3DDevice(device1, &d3ddevice1);
3966 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice interface (hr = %x).\n", hr);
3968 hr = IDirect3DDevice_QueryInterface(d3ddevice1, &IID_IDirectDrawSurface, (void **)&surface);
3969 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
3971 hr = IDirectDrawSurface_GetClipper(surface, &d3drm_clipper);
3972 ok(hr == DDERR_NOCLIPPERATTACHED, "Expected hr == DDERR_NOCLIPPERATTACHED, got %x.\n", hr);
3974 /* Check if CreateDeviceFromClipper creates a primary surface and attaches the clipper to it */
3975 hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **)&surface7);
3976 ok(hr == DD_OK, "Cannot get IDirectDrawSurface7 interface (hr = %x).\n", hr);
3977 IDirectDrawSurface7_GetDDInterface(surface7, (void **)&unknown);
3978 hr = IUnknown_QueryInterface(unknown, &IID_IDirectDraw, (void **)&ddraw);
3979 ok(hr == DD_OK, "Cannot get IDirectDraw interface (hr = %x).\n", hr);
3980 IUnknown_Release(unknown);
3981 hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
3982 NULL, &d3drm_primary, surface_callback);
3983 ok(hr == DD_OK, "Failed to enumerate surfaces (hr = %x).\n", hr);
3984 ok(d3drm_primary != NULL, "No primary surface was enumerated.\n");
3985 hr = IDirectDrawSurface_GetClipper(d3drm_primary, &d3drm_clipper);
3986 ok(hr == DD_OK, "Cannot get attached clipper from primary surface (hr = %x).\n", hr);
3987 ok(d3drm_clipper == clipper, "Expected clipper returned == %p, got %p.\n", clipper , d3drm_clipper);
3989 IDirectDrawClipper_Release(d3drm_clipper);
3990 IDirectDrawSurface_Release(d3drm_primary);
3991 IDirectDrawSurface7_Release(surface7);
3992 IDirectDraw_Release(ddraw);
3994 /* Check properties of render target and depth surface */
3995 surface_desc.dwSize = sizeof(surface_desc);
3996 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &surface_desc);
3997 ok(hr == DD_OK, "Cannot get surface desc structure (hr = %x).\n", hr);
3999 ok((surface_desc.dwWidth == 300) && (surface_desc.dwHeight == 200), "Expected surface dimensions = 300, 200, got %u, %u.\n",
4000 surface_desc.dwWidth, surface_desc.dwHeight);
4001 ok((surface_desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE),
4002 "Expected caps containing %x, got %x.\n", DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE, surface_desc.ddsCaps.dwCaps);
4003 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4004 ok(surface_desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, surface_desc.dwFlags);
4006 hr = DirectDrawCreate(NULL, &ddraw, NULL);
4007 ok(hr == DD_OK, "Cannot get IDirectDraw interface (hr = %x).\n", hr);
4008 desc.dwSize = sizeof(desc);
4009 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4010 ok(hr == DD_OK, "Cannot get IDirectDraw display mode (hr = %x)\n", hr);
4011 ok(desc.ddpfPixelFormat.dwRGBBitCount == surface_desc.ddpfPixelFormat.dwRGBBitCount, "Expected %u bpp, got %u bpp.\n",
4012 surface_desc.ddpfPixelFormat.dwRGBBitCount, desc.ddpfPixelFormat.dwRGBBitCount);
4014 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4015 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4017 desc.dwSize = sizeof(desc);
4018 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
4019 ok(hr == DD_OK, "Cannot get z surface desc structure (hr = %x).\n", hr);
4021 ok((desc.dwWidth == 300) && (desc.dwHeight == 200), "Expected surface dimensions = 300, 200, got %u, %u.\n",
4022 desc.dwWidth, desc.dwHeight);
4023 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Expected caps containing %x, got %x.\n", DDSCAPS_ZBUFFER, desc.ddsCaps.dwCaps);
4024 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4025 ok(desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, desc.dwFlags);
4026 ok(desc.dwZBufferBitDepth == 16, "Expected 16 for Z buffer bit depth, got %u.\n", desc.dwZBufferBitDepth);
4027 ok(desc.ddpfPixelFormat.dwStencilBitMask == 0, "Expected 0 stencil bits, got %x.\n", desc.ddpfPixelFormat.dwStencilBitMask);
4029 /* Release old objects and check refcount of device and clipper */
4030 IDirectDrawSurface_Release(ds);
4031 ds = NULL;
4032 IDirectDrawSurface_Release(surface);
4033 surface = NULL;
4034 IDirect3DDevice_Release(d3ddevice1);
4035 d3ddevice1 = NULL;
4036 IDirect3DRMDevice_Release(device1);
4037 ref2 = get_refcount((IUnknown *)d3drm1);
4038 ok(ref1 == ref2, "expected ref1 == ref2, got ref1 = %u, ref2 = %u.\n", ref1, ref2);
4039 cref2 = get_refcount((IUnknown *)clipper);
4040 ok(cref1 == cref2, "expected cref1 == cref2, got cref1 = %u, cref2 = %u.\n", cref1, cref2);
4042 /* Test if render target format follows the screen format */
4043 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4044 ok(hr == DD_OK, "Cannot get IDirectDraw display mode (hr = %x)\n", hr);
4045 hr = IDirectDraw_SetDisplayMode(ddraw, desc.dwWidth, desc.dwHeight, 16);
4046 ok(hr == DD_OK, "Cannot set display mode to 16bpp (hr = %x).\n", hr);
4048 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4049 ok(hr == DD_OK, "Cannot get IDirectDraw display mode (hr = %x)\n", hr);
4050 ok(desc.ddpfPixelFormat.dwRGBBitCount == 16, "Expected 16 bpp, got %u.\n", desc.ddpfPixelFormat.dwRGBBitCount);
4052 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, rc.right, rc.bottom, &device1);
4053 ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice interface (hr = %x).\n", hr);
4055 hr = IDirect3DRMDevice_GetDirect3DDevice(device1, &d3ddevice1);
4056 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice interface (hr = %x).\n", hr);
4058 hr = IDirect3DDevice_QueryInterface(d3ddevice1, &IID_IDirectDrawSurface, (void **)&surface);
4059 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
4061 surface_desc.dwSize = sizeof(surface_desc);
4062 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &surface_desc);
4063 ok(hr == DD_OK, "Cannot get surface desc structure (hr = %x).\n", hr);
4064 ok(surface_desc.ddpfPixelFormat.dwRGBBitCount == 16, "Expected 16bpp, got %ubpp.\n",
4065 surface_desc.ddpfPixelFormat.dwRGBBitCount);
4067 hr = IDirectDraw2_RestoreDisplayMode(ddraw);
4068 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4070 if (ds)
4071 IDirectDrawSurface_Release(ds);
4072 IDirectDrawSurface_Release(surface);
4073 IDirect3DDevice_Release(d3ddevice1);
4074 IDirect3DRMDevice_Release(device1);
4075 IDirect3DRM_Release(d3drm1);
4076 IDirectDrawClipper_Release(clipper);
4077 IDirectDraw_Release(ddraw);
4078 DestroyWindow(window);
4081 static void test_create_device_from_clipper2(void)
4083 DDSCAPS caps = { DDSCAPS_ZBUFFER };
4084 IDirect3DRM *d3drm1 = NULL;
4085 IDirect3DRM2 *d3drm2 = NULL;
4086 IDirectDraw *ddraw = NULL;
4087 IUnknown *unknown = NULL;
4088 IDirect3DRMDevice2 *device2 = (IDirect3DRMDevice2 *)0xdeadbeef;
4089 IDirect3DDevice2 *d3ddevice2 = NULL;
4090 IDirectDrawClipper *clipper = NULL, *d3drm_clipper = NULL;
4091 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_primary = NULL;
4092 IDirectDrawSurface7 *surface7 = NULL;
4093 DDSURFACEDESC desc, surface_desc;
4094 DWORD expected_flags, ret_val;
4095 HWND window;
4096 GUID driver = IID_IDirect3DRGBDevice;
4097 HRESULT hr;
4098 ULONG ref1, ref2, ref3, cref1, cref2;
4099 RECT rc;
4101 window = create_window();
4102 GetClientRect(window, &rc);
4103 hr = DirectDrawCreateClipper(0, &clipper, NULL);
4104 ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface (hr = %x).\n", hr);
4105 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
4106 ok(hr == DD_OK, "Cannot set HWnd to Clipper (hr = %x).\n", hr);
4108 hr = Direct3DRMCreate(&d3drm1);
4109 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr);
4110 ref1 = get_refcount((IUnknown *)d3drm1);
4111 cref1 = get_refcount((IUnknown *)clipper);
4113 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
4114 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM2 interface (hr = %x).\n", hr);
4115 ref2 = get_refcount((IUnknown *)d3drm2);
4117 hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, clipper, &driver, 0, 0, &device2);
4118 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
4119 ok(device2 == NULL, "Expected device returned == NULL, got %p.\n", device2);
4121 /* If NULL is passed for clipper, CreateDeviceFromClipper returns D3DRMERR_BADVALUE */
4122 hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, NULL, &driver, 300, 200, &device2);
4123 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
4125 hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, clipper, &driver, 300, 200, NULL);
4126 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
4128 hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, clipper, &driver, 300, 200, &device2);
4129 ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice2 interface (hr = %x).\n", hr);
4130 ref3 = get_refcount((IUnknown *)d3drm1);
4131 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
4132 ref3 = get_refcount((IUnknown *)d3drm2);
4133 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
4134 cref2 = get_refcount((IUnknown *)clipper);
4135 ok(cref2 > cref1, "expected cref2 > cref1, got cref1 = %u , cref2 = %u.\n", cref1, cref2);
4136 ret_val = IDirect3DRMDevice2_GetWidth(device2);
4137 ok(ret_val == 300, "Expected device width = 300, got %u.\n", ret_val);
4138 ret_val = IDirect3DRMDevice2_GetHeight(device2);
4139 ok(ret_val == 200, "Expected device height == 200, got %u.\n", ret_val);
4141 /* Fetch immediate mode device in order to access render target */
4142 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3ddevice2);
4143 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface (hr = %x).\n", hr);
4145 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &surface);
4146 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
4148 hr = IDirectDrawSurface_GetClipper(surface, &d3drm_clipper);
4149 ok(hr == DDERR_NOCLIPPERATTACHED, "Expected hr == DDERR_NOCLIPPERATTACHED, got %x.\n", hr);
4151 /* Check if CreateDeviceFromClipper creates a primary surface and attaches the clipper to it */
4152 hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **)&surface7);
4153 ok(hr == DD_OK, "Cannot get IDirectDrawSurface7 interface (hr = %x).\n", hr);
4154 IDirectDrawSurface7_GetDDInterface(surface7, (void **)&unknown);
4155 hr = IUnknown_QueryInterface(unknown, &IID_IDirectDraw, (void **)&ddraw);
4156 ok(hr == DD_OK, "Cannot get IDirectDraw interface (hr = %x).\n", hr);
4157 IUnknown_Release(unknown);
4158 hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
4159 NULL, &d3drm_primary, surface_callback);
4160 ok(hr == DD_OK, "Failed to enumerate surfaces (hr = %x).\n", hr);
4161 ok(d3drm_primary != NULL, "No primary surface was enumerated.\n");
4162 hr = IDirectDrawSurface_GetClipper(d3drm_primary, &d3drm_clipper);
4163 ok(hr == DD_OK, "Cannot get attached clipper from primary surface (hr = %x).\n", hr);
4164 ok(d3drm_clipper == clipper, "Expected clipper returned == %p, got %p.\n", clipper , d3drm_clipper);
4166 IDirectDrawClipper_Release(d3drm_clipper);
4167 IDirectDrawSurface_Release(d3drm_primary);
4168 IDirectDrawSurface7_Release(surface7);
4169 IDirectDraw_Release(ddraw);
4171 /* Check properties of render target and depth surface */
4172 surface_desc.dwSize = sizeof(surface_desc);
4173 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &surface_desc);
4174 ok(hr == DD_OK, "Cannot get surface desc structure (hr = %x).\n", hr);
4176 ok((surface_desc.dwWidth == 300) && (surface_desc.dwHeight == 200), "Expected surface dimensions = 300, 200, got %u, %u.\n",
4177 surface_desc.dwWidth, surface_desc.dwHeight);
4178 ok((surface_desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE),
4179 "Expected caps containing %x, got %x.\n", DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE, surface_desc.ddsCaps.dwCaps);
4180 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4181 ok(surface_desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, surface_desc.dwFlags);
4183 hr = DirectDrawCreate(NULL, &ddraw, NULL);
4184 ok(hr == DD_OK, "Cannot get IDirectDraw interface (hr = %x).\n", hr);
4185 desc.dwSize = sizeof(desc);
4186 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4187 ok(hr == DD_OK, "Cannot get IDirectDraw display mode (hr = %x)\n", hr);
4188 ok(desc.ddpfPixelFormat.dwRGBBitCount == surface_desc.ddpfPixelFormat.dwRGBBitCount, "Expected %u bpp, got %u bpp.\n",
4189 surface_desc.ddpfPixelFormat.dwRGBBitCount, desc.ddpfPixelFormat.dwRGBBitCount);
4191 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4192 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4194 desc.dwSize = sizeof(desc);
4195 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
4196 ok(hr == DD_OK, "Cannot get z surface desc structure (hr = %x).\n", hr);
4198 ok((desc.dwWidth == 300) && (desc.dwHeight == 200), "Expected surface dimensions = 300, 200, got %u, %u.\n",
4199 desc.dwWidth, desc.dwHeight);
4200 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Expected caps containing %x, got %x.\n", DDSCAPS_ZBUFFER, desc.ddsCaps.dwCaps);
4201 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4202 ok(desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, desc.dwFlags);
4203 ok(desc.dwZBufferBitDepth == 16, "Expected 16 for Z buffer bit depth, got %u.\n", desc.dwZBufferBitDepth);
4204 ok(desc.ddpfPixelFormat.dwStencilBitMask == 0, "Expected 0 stencil bits, got %x.\n", desc.ddpfPixelFormat.dwStencilBitMask);
4206 /* Release old objects and check refcount of device and clipper */
4207 IDirectDrawSurface_Release(ds);
4208 ds = NULL;
4209 IDirectDrawSurface_Release(surface);
4210 surface = NULL;
4211 IDirect3DDevice2_Release(d3ddevice2);
4212 d3ddevice2 = NULL;
4213 IDirect3DRMDevice2_Release(device2);
4214 ref3 = get_refcount((IUnknown *)d3drm1);
4215 ok(ref1 == ref3, "expected ref1 == ref3, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
4216 ref3 = get_refcount((IUnknown *)d3drm2);
4217 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
4218 cref2 = get_refcount((IUnknown *)clipper);
4219 ok(cref1 == cref2, "expected cref1 == cref2, got cref1 = %u, cref2 = %u.\n", cref1, cref2);
4221 /* Test if render target format follows the screen format */
4222 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4223 ok(hr == DD_OK, "Cannot get IDirectDraw display mode (hr = %x)\n", hr);
4224 hr = IDirectDraw_SetDisplayMode(ddraw, desc.dwWidth, desc.dwHeight, 16);
4225 ok(hr == DD_OK, "Cannot set display mode to 16bpp (hr = %x).\n", hr);
4227 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4228 ok(hr == DD_OK, "Cannot get IDirectDraw display mode (hr = %x)\n", hr);
4229 ok(desc.ddpfPixelFormat.dwRGBBitCount == 16, "Expected 16 bpp, got %u.\n", desc.ddpfPixelFormat.dwRGBBitCount);
4231 hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, clipper, &driver, rc.right, rc.bottom, &device2);
4232 ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice2 interface (hr = %x).\n", hr);
4234 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3ddevice2);
4235 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface (hr = %x).\n", hr);
4237 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &surface);
4238 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
4240 surface_desc.dwSize = sizeof(surface_desc);
4241 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &surface_desc);
4242 ok(hr == DD_OK, "Cannot get surface desc structure (hr = %x).\n", hr);
4243 ok(surface_desc.ddpfPixelFormat.dwRGBBitCount == 16, "Expected 16bpp, got %ubpp.\n",
4244 surface_desc.ddpfPixelFormat.dwRGBBitCount);
4246 hr = IDirectDraw2_RestoreDisplayMode(ddraw);
4247 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4249 IDirectDrawSurface_Release(surface);
4250 IDirect3DDevice2_Release(d3ddevice2);
4251 IDirect3DRMDevice2_Release(device2);
4252 IDirect3DRM2_Release(d3drm2);
4253 IDirect3DRM_Release(d3drm1);
4254 IDirectDrawClipper_Release(clipper);
4255 IDirectDraw_Release(ddraw);
4256 DestroyWindow(window);
4259 static void test_create_device_from_clipper3(void)
4261 DDSCAPS caps = { DDSCAPS_ZBUFFER };
4262 IDirect3DRM *d3drm1 = NULL;
4263 IDirect3DRM3 *d3drm3 = NULL;
4264 IDirectDraw *ddraw = NULL;
4265 IUnknown *unknown = NULL;
4266 IDirect3DRMDevice3 *device3 = (IDirect3DRMDevice3 *)0xdeadbeef;
4267 IDirect3DDevice2 *d3ddevice2 = NULL;
4268 IDirectDrawClipper *clipper = NULL, *d3drm_clipper = NULL;
4269 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_primary = NULL;
4270 IDirectDrawSurface7 *surface7 = NULL;
4271 DDSURFACEDESC desc, surface_desc;
4272 DWORD expected_flags, ret_val;
4273 HWND window;
4274 GUID driver = IID_IDirect3DRGBDevice;
4275 HRESULT hr;
4276 ULONG ref1, ref2, ref3, cref1, cref2;
4277 RECT rc;
4279 window = create_window();
4280 GetClientRect(window, &rc);
4281 hr = DirectDrawCreateClipper(0, &clipper, NULL);
4282 ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface (hr = %x).\n", hr);
4283 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
4284 ok(hr == DD_OK, "Cannot set HWnd to Clipper (hr = %x).\n", hr);
4286 hr = Direct3DRMCreate(&d3drm1);
4287 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr);
4288 ref1 = get_refcount((IUnknown *)d3drm1);
4289 cref1 = get_refcount((IUnknown *)clipper);
4291 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
4292 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface (hr = %x).\n", hr);
4293 ref2 = get_refcount((IUnknown *)d3drm3);
4295 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, 0, 0, &device3);
4296 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
4297 ok(device3 == NULL, "Expected device returned == NULL, got %p.\n", device3);
4299 /* If NULL is passed for clipper, CreateDeviceFromClipper returns D3DRMERR_BADVALUE */
4300 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, NULL, &driver, 300, 200, &device3);
4301 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
4303 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, 300, 200, NULL);
4304 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
4306 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, 300, 200, &device3);
4307 ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice3 interface (hr = %x).\n", hr);
4308 ref3 = get_refcount((IUnknown *)d3drm1);
4309 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
4310 ref3 = get_refcount((IUnknown *)d3drm3);
4311 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
4312 cref2 = get_refcount((IUnknown *)clipper);
4313 ok(cref2 > cref1, "expected cref2 > cref1, got cref1 = %u , cref2 = %u.\n", cref1, cref2);
4314 ret_val = IDirect3DRMDevice3_GetWidth(device3);
4315 ok(ret_val == 300, "Expected device width = 300, got %u.\n", ret_val);
4316 ret_val = IDirect3DRMDevice3_GetHeight(device3);
4317 ok(ret_val == 200, "Expected device height == 200, got %u.\n", ret_val);
4319 /* Fetch immediate mode device in order to access render target */
4320 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
4321 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface (hr = %x).\n", hr);
4323 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &surface);
4324 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
4326 hr = IDirectDrawSurface_GetClipper(surface, &d3drm_clipper);
4327 ok(hr == DDERR_NOCLIPPERATTACHED, "Expected hr == DDERR_NOCLIPPERATTACHED, got %x.\n", hr);
4329 /* Check if CreateDeviceFromClipper creates a primary surface and attaches the clipper to it */
4330 hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **)&surface7);
4331 ok(hr == DD_OK, "Cannot get IDirectDrawSurface7 interface (hr = %x).\n", hr);
4332 IDirectDrawSurface7_GetDDInterface(surface7, (void **)&unknown);
4333 hr = IUnknown_QueryInterface(unknown, &IID_IDirectDraw, (void **)&ddraw);
4334 ok(hr == DD_OK, "Cannot get IDirectDraw interface (hr = %x).\n", hr);
4335 IUnknown_Release(unknown);
4336 hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
4337 NULL, &d3drm_primary, surface_callback);
4338 ok(hr == DD_OK, "Failed to enumerate surfaces (hr = %x).\n", hr);
4339 ok(d3drm_primary != NULL, "No primary surface was enumerated.\n");
4340 hr = IDirectDrawSurface_GetClipper(d3drm_primary, &d3drm_clipper);
4341 ok(hr == DD_OK, "Cannot get attached clipper from primary surface (hr = %x).\n", hr);
4342 ok(d3drm_clipper == clipper, "Expected clipper returned == %p, got %p.\n", clipper , d3drm_clipper);
4344 IDirectDrawClipper_Release(d3drm_clipper);
4345 IDirectDrawSurface_Release(d3drm_primary);
4346 IDirectDrawSurface7_Release(surface7);
4347 IDirectDraw_Release(ddraw);
4349 /* Check properties of render target and depth surface */
4350 surface_desc.dwSize = sizeof(surface_desc);
4351 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &surface_desc);
4352 ok(hr == DD_OK, "Cannot get surface desc structure (hr = %x).\n", hr);
4354 ok((surface_desc.dwWidth == 300) && (surface_desc.dwHeight == 200), "Expected surface dimensions = 300, 200, got %u, %u.\n",
4355 surface_desc.dwWidth, surface_desc.dwHeight);
4356 ok((surface_desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE),
4357 "Expected caps containing %x, got %x.\n", DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE, surface_desc.ddsCaps.dwCaps);
4358 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4359 ok(surface_desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, surface_desc.dwFlags);
4361 hr = DirectDrawCreate(NULL, &ddraw, NULL);
4362 ok(hr == DD_OK, "Cannot get IDirectDraw interface (hr = %x).\n", hr);
4363 desc.dwSize = sizeof(desc);
4364 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4365 ok(hr == DD_OK, "Cannot get IDirectDraw display mode (hr = %x)\n", hr);
4366 ok(desc.ddpfPixelFormat.dwRGBBitCount == surface_desc.ddpfPixelFormat.dwRGBBitCount, "Expected %u bpp, got %u bpp.\n",
4367 surface_desc.ddpfPixelFormat.dwRGBBitCount, desc.ddpfPixelFormat.dwRGBBitCount);
4369 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4370 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4372 desc.dwSize = sizeof(desc);
4373 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
4374 ok(hr == DD_OK, "Cannot get z surface desc structure (hr = %x).\n", hr);
4376 ok((desc.dwWidth == 300) && (desc.dwHeight == 200), "Expected surface dimensions = 300, 200, got %u, %u.\n",
4377 desc.dwWidth, desc.dwHeight);
4378 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Expected caps containing %x, got %x.\n", DDSCAPS_ZBUFFER, desc.ddsCaps.dwCaps);
4379 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4380 ok(desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, desc.dwFlags);
4381 ok(desc.dwZBufferBitDepth == 16, "Expected 16 for Z buffer bit depth, got %u.\n", desc.dwZBufferBitDepth);
4382 ok(desc.ddpfPixelFormat.dwStencilBitMask == 0, "Expected 0 stencil bits, got %x.\n", desc.ddpfPixelFormat.dwStencilBitMask);
4384 /* Release old objects and check refcount of device and clipper */
4385 IDirectDrawSurface_Release(ds);
4386 ds = NULL;
4387 IDirectDrawSurface_Release(surface);
4388 surface = NULL;
4389 IDirect3DDevice2_Release(d3ddevice2);
4390 d3ddevice2 = NULL;
4391 IDirect3DRMDevice3_Release(device3);
4392 ref3 = get_refcount((IUnknown *)d3drm1);
4393 ok(ref1 == ref3, "expected ref1 == ref3, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
4394 ref3 = get_refcount((IUnknown *)d3drm3);
4395 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
4396 cref2 = get_refcount((IUnknown *)clipper);
4397 ok(cref1 == cref2, "expected cref1 == cref2, got cref1 = %u, cref2 = %u.\n", cref1, cref2);
4399 /* Test if render target format follows the screen format */
4400 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4401 ok(hr == DD_OK, "Cannot get IDirectDraw display mode (hr = %x)\n", hr);
4402 hr = IDirectDraw_SetDisplayMode(ddraw, desc.dwWidth, desc.dwHeight, 16);
4403 ok(hr == DD_OK, "Cannot set display mode to 16bpp (hr = %x).\n", hr);
4405 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4406 ok(hr == DD_OK, "Cannot get IDirectDraw display mode (hr = %x)\n", hr);
4407 ok(desc.ddpfPixelFormat.dwRGBBitCount == 16, "Expected 16 bpp, got %u.\n", desc.ddpfPixelFormat.dwRGBBitCount);
4409 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, rc.right, rc.bottom, &device3);
4410 ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice3 interface (hr = %x).\n", hr);
4412 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
4413 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface (hr = %x).\n", hr);
4415 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &surface);
4416 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
4418 surface_desc.dwSize = sizeof(surface_desc);
4419 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &surface_desc);
4420 ok(hr == DD_OK, "Cannot get surface desc structure (hr = %x).\n", hr);
4421 ok(surface_desc.ddpfPixelFormat.dwRGBBitCount == 16, "Expected 16bpp, got %ubpp.\n",
4422 surface_desc.ddpfPixelFormat.dwRGBBitCount);
4424 hr = IDirectDraw2_RestoreDisplayMode(ddraw);
4425 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4427 IDirectDrawSurface_Release(surface);
4428 IDirect3DDevice2_Release(d3ddevice2);
4429 IDirect3DRMDevice3_Release(device3);
4430 IDirect3DRM3_Release(d3drm3);
4431 IDirect3DRM_Release(d3drm1);
4432 IDirectDrawClipper_Release(clipper);
4433 IDirectDraw_Release(ddraw);
4434 DestroyWindow(window);
4437 static void test_create_device_from_surface1(void)
4439 DDSCAPS caps = { DDSCAPS_ZBUFFER };
4440 DDSURFACEDESC desc;
4441 IDirectDraw *ddraw = NULL;
4442 IDirect3DRM *d3drm1 = NULL;
4443 IDirect3DRMDevice *device1 = (IDirect3DRMDevice *)0xdeadbeef;
4444 IDirect3DDevice *d3ddevice1 = NULL;
4445 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_surface = NULL, *d3drm_ds = NULL;
4446 DWORD expected_flags, ret_val;
4447 HWND window;
4448 GUID driver = IID_IDirect3DRGBDevice;
4449 ULONG ref1, ref2, surface_ref1, surface_ref2;
4450 RECT rc;
4451 BOOL use_sysmem_zbuffer = FALSE;
4452 HRESULT hr;
4454 hr = DirectDrawCreate(NULL, &ddraw, NULL);
4455 ok(hr == DD_OK, "Cannot get IDirectDraw interface (hr = %x).\n", hr);
4457 window = create_window();
4458 GetClientRect(window, &rc);
4460 hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
4461 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
4463 hr = Direct3DRMCreate(&d3drm1);
4464 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr);
4465 ref1 = get_refcount((IUnknown *)d3drm1);
4467 /* Create a surface and use it to create the retained mode device. */
4468 memset(&desc, 0, sizeof(desc));
4469 desc.dwSize = sizeof(desc);
4470 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4471 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
4472 desc.dwWidth = rc.right;
4473 desc.dwHeight = rc.bottom;
4475 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4476 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
4478 hr = IDirect3DRM_CreateDeviceFromSurface(d3drm1, &driver, ddraw, surface, &device1);
4479 ok(hr == DDERR_INVALIDCAPS, "Expected hr == DDERR_INVALIDCAPS, got %x.\n", hr);
4480 ok(device1 == NULL, "Expected device returned == NULL, got %p.\n", device1);
4481 IDirectDrawSurface_Release(surface);
4483 desc.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE;
4484 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4485 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
4486 surface_ref1 = get_refcount((IUnknown *)surface);
4488 hr = IDirect3DRM_CreateDeviceFromSurface(d3drm1, &driver, ddraw, surface, NULL);
4489 ok(hr == D3DRMERR_BADVALUE, "Expected hr == DDERR_BADVALUE, got %x.\n", hr);
4490 hr = IDirect3DRM_CreateDeviceFromSurface(d3drm1, &driver, ddraw, NULL, &device1);
4491 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == DDERR_BADDEVICE, got %x.\n", hr);
4492 hr = IDirect3DRM_CreateDeviceFromSurface(d3drm1, &driver, NULL, surface, &device1);
4493 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == DDERR_BADDEVICE, got %x.\n", hr);
4495 hr = IDirect3DRM_CreateDeviceFromSurface(d3drm1, &driver, ddraw, surface, &device1);
4496 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice interface (hr = %x).\n", hr);
4497 ref2 = get_refcount((IUnknown *)d3drm1);
4498 ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %u , ref2 = %u.\n", ref1, ref2);
4499 surface_ref2 = get_refcount((IUnknown *)surface);
4500 ok(surface_ref2 > surface_ref1, "Expected surface_ref2 > surface_ref1, got surface_ref1 = %u, surface_ref2 = %u.\n", surface_ref1, surface_ref2);
4501 ret_val = IDirect3DRMDevice_GetWidth(device1);
4502 ok(ret_val == rc.right, "Expected device width = 300, got %u.\n", ret_val);
4503 ret_val = IDirect3DRMDevice_GetHeight(device1);
4504 ok(ret_val == rc.bottom, "Expected device height == 200, got %u.\n", ret_val);
4506 /* Check if CreateDeviceFromSurface creates a primary surface */
4507 hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
4508 NULL, &d3drm_surface, surface_callback);
4509 ok(hr == DD_OK, "Failed to enumerate surfaces (hr = %x).\n", hr);
4510 ok(d3drm_surface == NULL, "No primary surface should have enumerated (%p).\n", d3drm_surface);
4512 hr = IDirect3DRMDevice_GetDirect3DDevice(device1, &d3ddevice1);
4513 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice interface (hr = %x).\n", hr);
4515 hr = IDirect3DDevice_QueryInterface(d3ddevice1, &IID_IDirectDrawSurface, (void **)&d3drm_surface);
4516 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
4517 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
4519 /* Check properties of attached depth surface */
4520 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &ds);
4521 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4523 memset(&desc, 0, sizeof(desc));
4524 desc.dwSize = sizeof(desc);
4525 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
4526 ok(hr == DD_OK, "Cannot get z surface desc structure (hr = %x).\n", hr);
4528 use_sysmem_zbuffer = desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY;
4529 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %u, %u, got %u, %u.\n",
4530 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
4531 ok(desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER, "Expected caps containing %x, got %x.\n", DDSCAPS_ZBUFFER, desc.ddsCaps.dwCaps);
4532 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4533 ok(desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, desc.dwFlags);
4535 IDirectDrawSurface_Release(ds);
4536 IDirect3DDevice_Release(d3ddevice1);
4537 IDirectDrawSurface_Release(d3drm_surface);
4539 IDirect3DRMDevice_Release(device1);
4540 ref2 = get_refcount((IUnknown *)d3drm1);
4541 ok(ref1 == ref2, "expected ref1 == ref2, got ref1 = %u, ref2 = %u.\n", ref1, ref2);
4542 surface_ref2 = get_refcount((IUnknown *)surface);
4543 ok(surface_ref2 == surface_ref1, "Expected surface_ref2 == surface_ref1, got surface_ref1 = %u, surface_ref2 = %u.\n",
4544 surface_ref1, surface_ref2);
4545 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4546 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4547 /*The render target still holds a reference to ds as the depth surface remains attached to it, so refcount will be 1*/
4548 ref1 = IDirectDrawSurface_Release(ds);
4549 ok(ref1 == 1, "Expected ref1 == 1, got %u.\n", ref1);
4550 ref1 = IDirectDrawSurface_Release(surface);
4551 ok(ref1 == 0, "Expected Render target refcount == 0, got %u.\n", ref1);
4553 memset(&desc, 0, sizeof(desc));
4554 desc.dwSize = sizeof(desc);
4555 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4556 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
4557 desc.dwWidth = rc.right;
4558 desc.dwHeight = rc.bottom;
4560 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4561 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
4563 memset(&desc, 0, sizeof(desc));
4564 desc.dwSize = sizeof(desc);
4565 desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT;
4566 desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | (use_sysmem_zbuffer ? DDSCAPS_SYSTEMMEMORY : 0);
4567 desc.dwZBufferBitDepth = 16;
4568 desc.dwWidth = rc.right;
4569 desc.dwHeight = rc.bottom;
4570 hr = IDirectDraw_CreateSurface(ddraw, &desc, &ds, NULL);
4571 ok(hr == DD_OK, "Cannot create depth surface (hr = %x).\n", hr);
4572 hr = IDirectDrawSurface_AddAttachedSurface(surface, ds);
4573 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#x.\n", hr);
4575 hr = IDirect3DRM_CreateDeviceFromSurface(d3drm1, &driver, ddraw, surface, &device1);
4576 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice interface (hr = %x).\n", hr);
4578 hr = IDirect3DRMDevice2_GetDirect3DDevice(device1, &d3ddevice1);
4579 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice interface (hr = %x).\n", hr);
4581 hr = IDirect3DDevice_QueryInterface(d3ddevice1, &IID_IDirectDrawSurface, (void **)&d3drm_surface);
4582 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
4583 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
4585 /* Check if depth surface matches the one we created */
4586 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &d3drm_ds);
4587 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4588 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
4590 IDirectDrawSurface_Release(d3drm_ds);
4591 IDirectDrawSurface_Release(d3drm_surface);
4592 IDirectDrawSurface_Release(ds);
4594 IDirect3DDevice_Release(d3ddevice1);
4595 IDirect3DRMDevice_Release(device1);
4596 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4597 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4598 /*The render target still holds a reference to ds as the depth surface remains attached to it, so refcount will be 1*/
4599 ref1 = IDirectDrawSurface_Release(ds);
4600 ok(ref1 == 1, "Expected ref1 == 1, got %u.\n", ref1);
4601 ref1 = IDirectDrawSurface_Release(surface);
4602 ok(ref1 == 0, "Expected Render target refcount == 0, got %u.\n", ref1);
4603 IDirect3DRM_Release(d3drm1);
4604 IDirectDraw_Release(ddraw);
4605 DestroyWindow(window);
4608 static void test_create_device_from_surface2(void)
4610 DDSCAPS caps = { DDSCAPS_ZBUFFER };
4611 DDSURFACEDESC desc;
4612 IDirectDraw *ddraw = NULL;
4613 IDirect3DRM *d3drm1 = NULL;
4614 IDirect3DRM2 *d3drm2 = NULL;
4615 IDirect3DRMDevice2 *device2 = (IDirect3DRMDevice2 *)0xdeadbeef;
4616 IDirect3DDevice2 *d3ddevice2 = NULL;
4617 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_surface = NULL, *d3drm_ds = NULL;
4618 DWORD expected_flags, ret_val;
4619 HWND window;
4620 GUID driver = IID_IDirect3DRGBDevice;
4621 ULONG ref1, ref2, ref3, surface_ref1, surface_ref2;
4622 RECT rc;
4623 BOOL use_sysmem_zbuffer = FALSE;
4624 HRESULT hr;
4626 hr = DirectDrawCreate(NULL, &ddraw, NULL);
4627 ok(hr == DD_OK, "Cannot get IDirectDraw interface (hr = %x).\n", hr);
4629 window = create_window();
4630 GetClientRect(window, &rc);
4632 hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
4633 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
4635 hr = Direct3DRMCreate(&d3drm1);
4636 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr);
4637 ref1 = get_refcount((IUnknown *)d3drm1);
4639 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
4640 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM2 interface (hr = %x).\n", hr);
4641 ref2 = get_refcount((IUnknown *)d3drm2);
4643 /* Create a surface and use it to create the retained mode device. */
4644 memset(&desc, 0, sizeof(desc));
4645 desc.dwSize = sizeof(desc);
4646 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4647 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
4648 desc.dwWidth = rc.right;
4649 desc.dwHeight = rc.bottom;
4651 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4652 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
4654 hr = IDirect3DRM2_CreateDeviceFromSurface(d3drm2, &driver, ddraw, surface, &device2);
4655 ok(hr == DDERR_INVALIDCAPS, "Expected hr == DDERR_INVALIDCAPS, got %x.\n", hr);
4656 ok(device2 == NULL, "Expected device returned == NULL, got %p.\n", device2);
4657 IDirectDrawSurface_Release(surface);
4659 desc.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE;
4660 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4661 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
4662 surface_ref1 = get_refcount((IUnknown *)surface);
4664 hr = IDirect3DRM2_CreateDeviceFromSurface(d3drm2, &driver, ddraw, surface, NULL);
4665 ok(hr == D3DRMERR_BADVALUE, "Expected hr == DDERR_BADVALUE, got %x.\n", hr);
4666 hr = IDirect3DRM2_CreateDeviceFromSurface(d3drm2, &driver, ddraw, NULL, &device2);
4667 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == DDERR_BADDEVICE, got %x.\n", hr);
4668 hr = IDirect3DRM2_CreateDeviceFromSurface(d3drm2, &driver, NULL, surface, &device2);
4669 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == DDERR_BADDEVICE, got %x.\n", hr);
4671 hr = IDirect3DRM2_CreateDeviceFromSurface(d3drm2, &driver, ddraw, surface, &device2);
4672 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice2 interface (hr = %x).\n", hr);
4673 ref3 = get_refcount((IUnknown *)d3drm1);
4674 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
4675 ref3 = get_refcount((IUnknown *)d3drm2);
4676 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
4677 surface_ref2 = get_refcount((IUnknown *)surface);
4678 ok(surface_ref2 > surface_ref1, "Expected surface_ref2 > surface_ref1, got surface_ref1 = %u, surface_ref2 = %u.\n", surface_ref1, surface_ref2);
4679 ret_val = IDirect3DRMDevice2_GetWidth(device2);
4680 ok(ret_val == rc.right, "Expected device width = 300, got %u.\n", ret_val);
4681 ret_val = IDirect3DRMDevice2_GetHeight(device2);
4682 ok(ret_val == rc.bottom, "Expected device height == 200, got %u.\n", ret_val);
4684 /* Check if CreateDeviceFromSurface creates a primary surface */
4685 hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
4686 NULL, &d3drm_surface, surface_callback);
4687 ok(hr == DD_OK, "Failed to enumerate surfaces (hr = %x).\n", hr);
4688 ok(d3drm_surface == NULL, "No primary surface should have enumerated (%p).\n", d3drm_surface);
4690 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3ddevice2);
4691 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface (hr = %x).\n", hr);
4693 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &d3drm_surface);
4694 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
4695 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
4697 /* Check properties of attached depth surface */
4698 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &ds);
4699 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4701 memset(&desc, 0, sizeof(desc));
4702 desc.dwSize = sizeof(desc);
4703 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
4704 ok(hr == DD_OK, "Cannot get z surface desc structure (hr = %x).\n", hr);
4706 use_sysmem_zbuffer = desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY;
4707 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %u, %u, got %u, %u.\n",
4708 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
4709 ok(desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER, "Expected caps containing %x, got %x.\n", DDSCAPS_ZBUFFER, desc.ddsCaps.dwCaps);
4710 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4711 ok(desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, desc.dwFlags);
4713 IDirectDrawSurface_Release(ds);
4714 IDirect3DDevice2_Release(d3ddevice2);
4715 IDirectDrawSurface_Release(d3drm_surface);
4717 IDirect3DRMDevice2_Release(device2);
4718 ref3 = get_refcount((IUnknown *)d3drm1);
4719 ok(ref1 == ref3, "expected ref1 == ref3, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
4720 ref3 = get_refcount((IUnknown *)d3drm2);
4721 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
4722 surface_ref2 = get_refcount((IUnknown *)surface);
4723 ok(surface_ref2 == surface_ref1, "Expected surface_ref2 == surface_ref1, got surface_ref1 = %u, surface_ref2 = %u.\n",
4724 surface_ref1, surface_ref2);
4725 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4726 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4727 /*The render target still holds a reference to ds as the depth surface remains attached to it, so refcount will be 1*/
4728 ref1 = IDirectDrawSurface_Release(ds);
4729 ok(ref1 == 1, "Expected ref1 == 1, got %u.\n", ref1);
4731 ref1 = IDirectDrawSurface_Release(surface);
4732 ok(ref1 == 0, "Expected Render target refcount == 0, got %u.\n", ref1);
4734 memset(&desc, 0, sizeof(desc));
4735 desc.dwSize = sizeof(desc);
4736 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4737 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
4738 desc.dwWidth = rc.right;
4739 desc.dwHeight = rc.bottom;
4741 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4742 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
4744 memset(&desc, 0, sizeof(desc));
4745 desc.dwSize = sizeof(desc);
4746 desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT;
4747 desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | (use_sysmem_zbuffer ? DDSCAPS_SYSTEMMEMORY : 0);
4748 desc.dwZBufferBitDepth = 16;
4749 desc.dwWidth = rc.right;
4750 desc.dwHeight = rc.bottom;
4751 hr = IDirectDraw_CreateSurface(ddraw, &desc, &ds, NULL);
4752 ok(hr == DD_OK, "Cannot create depth surface (hr = %x).\n", hr);
4753 hr = IDirectDrawSurface_AddAttachedSurface(surface, ds);
4754 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#x.\n", hr);
4756 hr = IDirect3DRM2_CreateDeviceFromSurface(d3drm2, &driver, ddraw, surface, &device2);
4757 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice2 interface (hr = %x).\n", hr);
4759 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3ddevice2);
4760 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface (hr = %x).\n", hr);
4762 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &d3drm_surface);
4763 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
4764 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
4766 /* Check if depth surface matches the one we created */
4767 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &d3drm_ds);
4768 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4769 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
4771 IDirectDrawSurface_Release(d3drm_ds);
4772 IDirectDrawSurface_Release(d3drm_surface);
4773 IDirectDrawSurface_Release(ds);
4775 IDirect3DDevice2_Release(d3ddevice2);
4776 IDirect3DRMDevice2_Release(device2);
4777 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4778 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4779 /*The render target still holds a reference to ds as the depth surface remains attached to it, so refcount will be 1*/
4780 ref1 = IDirectDrawSurface_Release(ds);
4781 ok(ref1 == 1, "Expected ref1 == 1, got %u.\n", ref1);
4782 ref1 = IDirectDrawSurface_Release(surface);
4783 ok(ref1 == 0, "Expected Render target refcount == 0, got %u.\n", ref1);
4784 IDirect3DRM2_Release(d3drm2);
4785 IDirect3DRM_Release(d3drm1);
4786 IDirectDraw_Release(ddraw);
4787 DestroyWindow(window);
4790 static void test_create_device_from_surface3(void)
4792 DDSCAPS caps = { DDSCAPS_ZBUFFER };
4793 DDSURFACEDESC desc;
4794 IDirectDraw *ddraw = NULL;
4795 IDirect3DRM *d3drm1 = NULL;
4796 IDirect3DRM3 *d3drm3 = NULL;
4797 IDirect3DRMDevice3 *device3 = (IDirect3DRMDevice3 *)0xdeadbeef;
4798 IDirect3DDevice2 *d3ddevice2 = NULL;
4799 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_surface = NULL, *d3drm_ds = NULL;
4800 DWORD expected_flags, ret_val;
4801 HWND window;
4802 GUID driver = IID_IDirect3DRGBDevice;
4803 ULONG ref1, ref2, ref3, surface_ref1, surface_ref2;
4804 RECT rc;
4805 BOOL use_sysmem_zbuffer = FALSE;
4806 HRESULT hr;
4808 hr = DirectDrawCreate(NULL, &ddraw, NULL);
4809 ok(hr == DD_OK, "Cannot get IDirectDraw interface (hr = %x).\n", hr);
4811 window = create_window();
4812 GetClientRect(window, &rc);
4814 hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
4815 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
4817 hr = Direct3DRMCreate(&d3drm1);
4818 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr);
4819 ref1 = get_refcount((IUnknown *)d3drm1);
4821 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
4822 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface (hr = %x).\n", hr);
4823 ref2 = get_refcount((IUnknown *)d3drm3);
4825 /* Create a surface and use it to create the retained mode device. */
4826 memset(&desc, 0, sizeof(desc));
4827 desc.dwSize = sizeof(desc);
4828 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4829 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
4830 desc.dwWidth = rc.right;
4831 desc.dwHeight = rc.bottom;
4833 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4834 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
4836 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, ddraw, surface, 0, &device3);
4837 ok(hr == DDERR_INVALIDCAPS, "Expected hr == DDERR_INVALIDCAPS, got %x.\n", hr);
4838 ok(device3 == NULL, "Expected device returned == NULL, got %p.\n", device3);
4839 IDirectDrawSurface_Release(surface);
4841 desc.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE;
4842 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4843 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
4844 surface_ref1 = get_refcount((IUnknown *)surface);
4846 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, ddraw, surface, 0, NULL);
4847 ok(hr == D3DRMERR_BADVALUE, "Expected hr == DDERR_BADVALUE, got %x.\n", hr);
4848 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, ddraw, NULL, 0, &device3);
4849 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == DDERR_BADDEVICE, got %x.\n", hr);
4850 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, NULL, surface, 0, &device3);
4851 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == DDERR_BADDEVICE, got %x.\n", hr);
4853 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, ddraw, surface, 0, &device3);
4854 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice3 interface (hr = %x).\n", hr);
4855 ref3 = get_refcount((IUnknown *)d3drm1);
4856 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
4857 ref3 = get_refcount((IUnknown *)d3drm3);
4858 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
4859 surface_ref2 = get_refcount((IUnknown *)surface);
4860 ok(surface_ref2 > surface_ref1, "Expected surface_ref2 > surface_ref1, got surface_ref1 = %u, surface_ref2 = %u.\n", surface_ref1, surface_ref2);
4861 ret_val = IDirect3DRMDevice3_GetWidth(device3);
4862 ok(ret_val == rc.right, "Expected device width = 300, got %u.\n", ret_val);
4863 ret_val = IDirect3DRMDevice3_GetHeight(device3);
4864 ok(ret_val == rc.bottom, "Expected device height == 200, got %u.\n", ret_val);
4866 /* Check if CreateDeviceFromSurface creates a primary surface */
4867 hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
4868 NULL, &d3drm_surface, surface_callback);
4869 ok(hr == DD_OK, "Failed to enumerate surfaces (hr = %x).\n", hr);
4870 ok(d3drm_surface == NULL, "No primary surface should have enumerated (%p).\n", d3drm_surface);
4872 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
4873 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface (hr = %x).\n", hr);
4875 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &d3drm_surface);
4876 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
4877 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
4879 /* Check properties of attached depth surface */
4880 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &ds);
4881 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4883 memset(&desc, 0, sizeof(desc));
4884 desc.dwSize = sizeof(desc);
4885 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
4886 ok(hr == DD_OK, "Cannot get z surface desc structure (hr = %x).\n", hr);
4888 use_sysmem_zbuffer = desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY;
4889 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %u, %u, got %u, %u.\n",
4890 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
4891 ok(desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER, "Expected caps containing %x, got %x.\n", DDSCAPS_ZBUFFER, desc.ddsCaps.dwCaps);
4892 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4893 ok(desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, desc.dwFlags);
4895 IDirectDrawSurface_Release(ds);
4896 IDirect3DDevice2_Release(d3ddevice2);
4897 IDirectDrawSurface_Release(d3drm_surface);
4898 IDirect3DRMDevice3_Release(device3);
4900 ref3 = get_refcount((IUnknown *)d3drm1);
4901 ok(ref1 == ref3, "expected ref1 == ref3, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
4902 ref3 = get_refcount((IUnknown *)d3drm3);
4903 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
4904 surface_ref2 = get_refcount((IUnknown *)surface);
4905 ok(surface_ref2 == surface_ref1, "Expected surface_ref2 == surface_ref1, got surface_ref1 = %u, surface_ref2 = %u.\n",
4906 surface_ref1, surface_ref2);
4907 /* In version 3, d3drm will destroy all references of the depth surface it created internally. */
4908 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4909 todo_wine ok(hr == DDERR_NOTFOUND, "Expected hr == DDERR_NOTFOUND, got %x.\n", hr);
4910 if (SUCCEEDED(hr))
4911 IDirectDrawSurface_Release(ds);
4912 ref1 = IDirectDrawSurface_Release(surface);
4913 ok(ref1 == 0, "Expected Render target refcount == 0, got %u.\n", ref1);
4915 memset(&desc, 0, sizeof(desc));
4916 desc.dwSize = sizeof(desc);
4917 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4918 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
4919 desc.dwWidth = rc.right;
4920 desc.dwHeight = rc.bottom;
4922 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4923 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
4925 memset(&desc, 0, sizeof(desc));
4926 desc.dwSize = sizeof(desc);
4927 desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT;
4928 desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | (use_sysmem_zbuffer ? DDSCAPS_SYSTEMMEMORY : 0);
4929 desc.dwZBufferBitDepth = 16;
4930 desc.dwWidth = rc.right;
4931 desc.dwHeight = rc.bottom;
4932 hr = IDirectDraw_CreateSurface(ddraw, &desc, &ds, NULL);
4933 ok(hr == DD_OK, "Cannot create depth surface (hr = %x).\n", hr);
4934 hr = IDirectDrawSurface_AddAttachedSurface(surface, ds);
4935 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#x.\n", hr);
4937 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, ddraw, surface, D3DRMDEVICE_NOZBUFFER, &device3);
4938 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice3 interface (hr = %x).\n", hr);
4940 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
4941 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface (hr = %x).\n", hr);
4943 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &d3drm_surface);
4944 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
4945 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
4947 /* Check if depth surface matches the one we created */
4948 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &d3drm_ds);
4949 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4950 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
4952 IDirectDrawSurface_Release(d3drm_ds);
4953 IDirectDrawSurface_Release(d3drm_surface);
4954 IDirectDrawSurface_Release(ds);
4955 IDirect3DDevice2_Release(d3ddevice2);
4956 IDirect3DRMDevice3_Release(device3);
4957 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4958 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4959 /* The render target still holds a reference to ds as the depth surface remains attached to it, so refcount will be 1*/
4960 ref1 = IDirectDrawSurface_Release(ds);
4961 ok(ref1 == 1, "Expected ref1 == 1, got %u.\n", ref1);
4963 /* What happens if we pass no flags and still attach our own depth surface? */
4964 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, ddraw, surface, 0, &device3);
4965 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice3 interface (hr = %x).\n", hr);
4967 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
4968 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface (hr = %x).\n", hr);
4970 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &d3drm_surface);
4971 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
4972 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
4974 /* Check if depth surface matches the one we created */
4975 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &d3drm_ds);
4976 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4977 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
4979 IDirectDrawSurface_Release(d3drm_ds);
4980 IDirectDrawSurface_Release(d3drm_surface);
4981 IDirect3DDevice2_Release(d3ddevice2);
4982 IDirect3DRMDevice3_Release(device3);
4983 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4984 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
4985 /*The render target still holds a reference to ds as the depth surface remains attached to it, so refcount will be 1*/
4986 ref1 = IDirectDrawSurface_Release(ds);
4987 ok(ref1 == 1, "Expected ref1 == 1, got %u.\n", ref1);
4988 ref1 = IDirectDrawSurface_Release(surface);
4989 ok(ref1 == 0, "Expected Render target refcount == 0, got %u.\n", ref1);
4991 memset(&desc, 0, sizeof(desc));
4992 desc.dwSize = sizeof(desc);
4993 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4994 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
4995 desc.dwWidth = rc.right;
4996 desc.dwHeight = rc.bottom;
4998 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4999 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5001 /* What happens if we don't pass D3DRMDEVICE_NOZBUFFER and still not attach our own depth surface? */
5002 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, ddraw, surface, D3DRMDEVICE_NOZBUFFER, &device3);
5003 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice3 interface (hr = %x).\n", hr);
5005 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
5006 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface (hr = %x).\n", hr);
5008 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &d3drm_surface);
5009 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
5010 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
5012 /* Check if depth surface matches the one we created */
5013 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &d3drm_ds);
5014 ok(hr == DDERR_NOTFOUND, "Expected hr == DDERR_NOTFOUND, got %x).\n", hr);
5015 IDirectDrawSurface_Release(d3drm_surface);
5017 IDirect3DDevice2_Release(d3ddevice2);
5018 IDirect3DRMDevice3_Release(device3);
5019 ref1 = IDirectDrawSurface_Release(surface);
5020 ok(ref1 == 0, "Expected Render target refcount == 0, got %u.\n", ref1);
5021 IDirect3DRM3_Release(d3drm3);
5022 IDirect3DRM_Release(d3drm1);
5023 IDirectDraw_Release(ddraw);
5024 DestroyWindow(window);
5027 static IDirect3DDevice *create_device1(IDirectDraw *ddraw, HWND window, IDirectDrawSurface **ds)
5029 static const DWORD z_depths[] = { 32, 24, 16 };
5030 IDirectDrawSurface *surface;
5031 IDirect3DDevice *device = NULL;
5032 DDSURFACEDESC surface_desc;
5033 unsigned int i;
5034 HRESULT hr;
5035 RECT rc;
5037 GetClientRect(window, &rc);
5038 hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
5039 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
5041 memset(&surface_desc, 0, sizeof(surface_desc));
5042 surface_desc.dwSize = sizeof(surface_desc);
5043 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
5044 surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
5045 surface_desc.dwWidth = rc.right;
5046 surface_desc.dwHeight = rc.bottom;
5048 hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL);
5049 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5051 /* We used to use EnumDevices() for this, but it seems
5052 * D3DDEVICEDESC.dwDeviceZBufferBitDepth only has a very casual
5053 * relationship with reality. */
5054 for (i = 0; i < ARRAY_SIZE(z_depths); ++i)
5056 memset(&surface_desc, 0, sizeof(surface_desc));
5057 surface_desc.dwSize = sizeof(surface_desc);
5058 surface_desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT;
5059 surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
5060 U2(surface_desc).dwZBufferBitDepth = z_depths[i];
5061 surface_desc.dwWidth = rc.right;
5062 surface_desc.dwHeight = rc.bottom;
5063 if (FAILED(IDirectDraw_CreateSurface(ddraw, &surface_desc, ds, NULL)))
5064 continue;
5066 hr = IDirectDrawSurface_AddAttachedSurface(surface, *ds);
5067 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#x.\n", hr);
5068 if (FAILED(hr))
5070 IDirectDrawSurface_Release(*ds);
5071 continue;
5074 if (SUCCEEDED(IDirectDrawSurface_QueryInterface(surface, &IID_IDirect3DHALDevice, (void **)&device)))
5075 break;
5077 IDirectDrawSurface_DeleteAttachedSurface(surface, 0, *ds);
5078 IDirectDrawSurface_Release(*ds);
5079 *ds = NULL;
5082 IDirectDrawSurface_Release(surface);
5083 return device;
5086 static void test_create_device_from_d3d1(void)
5088 IDirectDraw *ddraw1 = NULL, *temp_ddraw1;
5089 IDirect3D *d3d1 = NULL, *temp_d3d1;
5090 IDirect3DRM *d3drm1 = NULL;
5091 IDirect3DRMDevice *device1 = (IDirect3DRMDevice *)0xdeadbeef;
5092 IDirect3DRMDevice2 *device2;
5093 IDirect3DRMDevice3 *device3;
5094 IDirect3DDevice *d3ddevice1 = NULL, *d3drm_d3ddevice1 = NULL, *temp_d3ddevice1;
5095 IDirect3DDevice2 *d3ddevice2 = (IDirect3DDevice2 *)0xdeadbeef;
5096 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_ds = NULL;
5097 DWORD expected_flags, ret_val;
5098 DDSCAPS caps = { DDSCAPS_ZBUFFER };
5099 DDSURFACEDESC desc;
5100 RECT rc;
5101 HWND window;
5102 ULONG ref1, ref2, ref3, ref4, device_ref1, device_ref2, d3d_ref1, d3d_ref2;
5103 HRESULT hr;
5105 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
5106 ok(hr == DD_OK, "Cannot get IDirectDraw interface (hr = %x).\n", hr);
5108 window = create_window();
5109 GetClientRect(window, &rc);
5111 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1);
5112 ok(hr == DD_OK, "Cannot get IDirect3D2 interface (hr = %x).\n", hr);
5113 d3d_ref1 = get_refcount((IUnknown *)d3d1);
5115 /* Create the immediate mode device */
5116 d3ddevice1 = create_device1(ddraw1, window, &ds);
5117 if (d3ddevice1 == NULL)
5119 win_skip("Cannot create IM device, skipping tests.\n");
5120 IDirect3D_Release(d3d1);
5121 IDirectDraw_Release(ddraw1);
5122 return;
5124 device_ref1 = get_refcount((IUnknown *)d3ddevice1);
5126 hr = Direct3DRMCreate(&d3drm1);
5127 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr);
5128 ref1 = get_refcount((IUnknown *)d3drm1);
5130 hr = IDirect3DRM_CreateDeviceFromD3D(d3drm1, NULL, d3ddevice1, &device1);
5131 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
5132 ok(device1 == NULL, "Expected device returned == NULL, got %p.\n", device1);
5133 hr = IDirect3DRM_CreateDeviceFromD3D(d3drm1, d3d1, NULL, &device1);
5134 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
5135 hr = IDirect3DRM_CreateDeviceFromD3D(d3drm1, d3d1, d3ddevice1, NULL);
5136 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
5138 hr = IDirect3DRM_CreateDeviceFromD3D(d3drm1, d3d1, d3ddevice1, &device1);
5139 ok(hr == DD_OK, "Failed to create IDirect3DRMDevice interface (hr = %x)\n", hr);
5140 ref2 = get_refcount((IUnknown *)d3drm1);
5141 ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %u , ref2 = %u.\n", ref1, ref2);
5142 device_ref2 = get_refcount((IUnknown *)d3ddevice1);
5143 ok(device_ref2 > device_ref1, "Expected device_ref2 > device_ref1, got device_ref1 = %u, device_ref2 = %u.\n", device_ref1, device_ref2);
5144 d3d_ref2 = get_refcount((IUnknown *)d3d1);
5145 ok(d3d_ref2 > d3d_ref1, "Expected d3d_ref2 > d3d_ref1, got d3d_ref1 = %u, d3d_ref2 = %u.\n", d3d_ref1, d3d_ref2);
5146 ret_val = IDirect3DRMDevice_GetWidth(device1);
5147 ok(ret_val == rc.right, "Expected device width = 300, got %u.\n", ret_val);
5148 ret_val = IDirect3DRMDevice_GetHeight(device1);
5149 ok(ret_val == rc.bottom, "Expected device height == 200, got %u.\n", ret_val);
5151 hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IDirect3DRMDevice2, (void **)&device2);
5152 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice2 Interface (hr = %x).\n", hr);
5153 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3ddevice2);
5154 ok(SUCCEEDED(hr), "Expected hr == D3DRM_OK, got %#x.\n", hr);
5155 ok(d3ddevice2 == NULL, "Expected d3ddevice2 == NULL, got %p.\n", d3ddevice2);
5156 IDirect3DRMDevice2_Release(device2);
5158 d3ddevice2 = (IDirect3DDevice2 *)0xdeadbeef;
5159 hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IDirect3DRMDevice3, (void **)&device3);
5160 ok(hr == DD_OK, "Cannot get IDirect3DRMDevice3 Interface (hr = %x).\n", hr);
5161 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
5162 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
5163 ok(d3ddevice2 == NULL, "Expected d3ddevice2 == NULL, got %p.\n", d3ddevice2);
5164 IDirect3DRMDevice3_Release(device3);
5166 hr = IDirectDraw_EnumSurfaces(ddraw1, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
5167 NULL, &surface, surface_callback);
5168 ok(hr == DD_OK, "Failed to enumerate surfaces (hr = %x).\n", hr);
5169 ok(surface == NULL, "No primary surface should have enumerated (%p).\n", surface);
5171 hr = IDirect3DRMDevice_GetDirect3DDevice(device1, &d3drm_d3ddevice1);
5172 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice interface (hr = %x).\n", hr);
5173 ok(d3ddevice1 == d3drm_d3ddevice1, "Expected Immediate Mode device created == %p, got %p.\n", d3ddevice1, d3drm_d3ddevice1);
5175 /* Check properties of render target and depth surfaces */
5176 hr = IDirect3DDevice_QueryInterface(d3drm_d3ddevice1, &IID_IDirectDrawSurface, (void **)&surface);
5177 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
5179 memset(&desc, 0, sizeof(desc));
5180 desc.dwSize = sizeof(desc);
5181 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
5182 ok(hr == DD_OK, "Cannot get surface desc structure (hr = %x).\n", hr);
5184 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %u, %u, got %u, %u.\n",
5185 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5186 ok((desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE),
5187 "Expected caps containing %x, got %x.\n", DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE, desc.ddsCaps.dwCaps);
5188 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5189 ok(desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, desc.dwFlags);
5191 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
5192 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
5193 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
5195 desc.dwSize = sizeof(desc);
5196 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
5197 ok(hr == DD_OK, "Cannot get z surface desc structure (hr = %x).\n", hr);
5199 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %u, %u, got %u, %u.\n",
5200 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5201 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Expected caps containing %x, got %x.\n", DDSCAPS_ZBUFFER, desc.ddsCaps.dwCaps);
5202 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5203 ok(desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, desc.dwFlags);
5205 IDirectDrawSurface_Release(d3drm_ds);
5206 IDirectDrawSurface_Release(ds);
5207 IDirectDrawSurface_Release(surface);
5208 IDirect3DDevice_Release(d3drm_d3ddevice1);
5209 IDirect3DRMDevice_Release(device1);
5210 ref2 = get_refcount((IUnknown *)d3drm1);
5211 ok(ref1 == ref2, "expected ref1 == ref2, got ref1 = %u, ref2 = %u.\n", ref1, ref2);
5212 device_ref2 = get_refcount((IUnknown *)d3ddevice1);
5213 ok(device_ref2 == device_ref1, "Expected device_ref2 == device_ref1, got device_ref1 = %u, device_ref2 = %u.\n", device_ref1, device_ref2);
5215 /* InitFromD3D tests */
5216 hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_CDirect3DRMDevice, NULL, &IID_IDirect3DRMDevice, (void **)&device1);
5217 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface (hr = %#x).\n", hr);
5219 hr = IDirect3DRMDevice_InitFromD3D(device1, NULL, d3ddevice1);
5220 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
5221 hr = IDirect3DRMDevice_InitFromD3D(device1, d3d1, NULL);
5222 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
5224 hr = IDirect3DRMDevice_InitFromD3D(device1, d3d1, d3ddevice1);
5225 ok(SUCCEEDED(hr), "Failed to initialise IDirect3DRMDevice interface (hr = %#x)\n", hr);
5226 ref2 = get_refcount((IUnknown *)d3drm1);
5227 ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %u , ref2 = %u.\n", ref1, ref2);
5228 device_ref2 = get_refcount((IUnknown *)d3ddevice1);
5229 ok(device_ref2 > device_ref1, "Expected device_ref2 > device_ref1, got device_ref1 = %u, device_ref2 = %u.\n",
5230 device_ref1, device_ref2);
5231 d3d_ref2 = get_refcount((IUnknown *)d3d1);
5232 ok(d3d_ref2 > d3d_ref1, "Expected d3d_ref2 > d3d_ref1, got d3d_ref1 = %u, d3d_ref2 = %u.\n", d3d_ref1, d3d_ref2);
5233 ret_val = IDirect3DRMDevice_GetWidth(device1);
5234 ok(ret_val == rc.right, "Expected device width = 300, got %u.\n", ret_val);
5235 ret_val = IDirect3DRMDevice_GetHeight(device1);
5236 ok(ret_val == rc.bottom, "Expected device height == 200, got %u.\n", ret_val);
5238 hr = IDirect3DRMDevice_InitFromD3D(device1, d3d1, d3ddevice1);
5239 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
5240 ref3 = get_refcount((IUnknown *)d3drm1);
5241 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
5242 ref3 = get_refcount((IUnknown *)d3ddevice1);
5243 ok(ref3 > device_ref2, "Expected ref3 > device_ref2, got ref3 = %u, device_ref2 = %u.\n", ref3, device_ref2);
5244 ref3 = get_refcount((IUnknown *)d3d1);
5245 ok(ref3 > d3d_ref2, "Expected ref3 > d3d_ref2, got ref3 = %u, d3d_ref2 = %u.\n", ref3, d3d_ref2);
5246 /* Release leaked references */
5247 while (IDirect3DRM_Release(d3drm1) > ref2);
5248 while (IDirect3DDevice_Release(d3ddevice1) > device_ref2);
5249 while (IDirect3D_Release(d3d1) > d3d_ref2);
5251 hr = DirectDrawCreate(NULL, &temp_ddraw1, NULL);
5252 ok(SUCCEEDED(hr), "Cannot get IDirectDraw interface (hr = %#x).\n", hr);
5253 ref4 = get_refcount((IUnknown *)temp_ddraw1);
5255 hr = IDirectDraw_QueryInterface(temp_ddraw1, &IID_IDirect3D, (void **)&temp_d3d1);
5256 ok(SUCCEEDED(hr), "Cannot get IDirect3D2 interface (hr = %#x).\n", hr);
5257 temp_d3ddevice1 = create_device1(temp_ddraw1, window, &surface);
5258 hr = IDirect3DRMDevice_InitFromD3D(device1, temp_d3d1, temp_d3ddevice1);
5259 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
5260 ref3 = get_refcount((IUnknown *)d3drm1);
5261 ok(ref3 > ref2, "expected ref3 > ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
5262 ref3 = get_refcount((IUnknown *)temp_d3ddevice1);
5263 ok(ref3 == device_ref2, "Expected ref3 == device_ref2, got ref3 = %u, device_ref2 = %u.\n", ref3, device_ref2);
5264 ref3 = get_refcount((IUnknown *)temp_d3d1);
5265 todo_wine ok(ref3 < d3d_ref2, "Expected ref3 < d3d_ref2, got ref3 = %u, d3d_ref2 = %u.\n", ref3, d3d_ref2);
5266 /* Release leaked references */
5267 while (IDirect3DRM_Release(d3drm1) > ref2);
5268 while (IDirect3DDevice_Release(temp_d3ddevice1) > 0);
5269 while (IDirect3D_Release(temp_d3d1) > ref4);
5270 IDirectDrawSurface_Release(surface);
5271 IDirectDraw_Release(temp_ddraw1);
5273 d3ddevice2 = (IDirect3DDevice2 *)0xdeadbeef;
5274 hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IDirect3DRMDevice2, (void **)&device2);
5275 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice2 Interface (hr = %x).\n", hr);
5276 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3ddevice2);
5277 ok(SUCCEEDED(hr), "Expected hr == D3DRM_OK, got %#x.\n", hr);
5278 ok(d3ddevice2 == NULL, "Expected d3ddevice2 == NULL, got %p.\n", d3ddevice2);
5279 IDirect3DRMDevice2_Release(device2);
5281 d3ddevice2 = (IDirect3DDevice2 *)0xdeadbeef;
5282 hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IDirect3DRMDevice3, (void **)&device3);
5283 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 Interface (hr = %#x).\n", hr);
5284 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
5285 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
5286 ok(d3ddevice2 == NULL, "Expected d3ddevice2 == NULL, got %p.\n", d3ddevice2);
5287 IDirect3DRMDevice3_Release(device3);
5289 surface = NULL;
5290 hr = IDirectDraw_EnumSurfaces(ddraw1, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
5291 NULL, &surface, surface_callback);
5292 ok(SUCCEEDED(hr), "Failed to enumerate surfaces (hr = %#x).\n", hr);
5293 ok(surface == NULL, "No primary surface should have enumerated (%p).\n", surface);
5295 hr = IDirect3DRMDevice_GetDirect3DDevice(device1, &d3drm_d3ddevice1);
5296 ok(SUCCEEDED(hr), "Cannot get IDirect3DDevice interface (hr = %#x).\n", hr);
5297 ok(d3ddevice1 == d3drm_d3ddevice1, "Expected Immediate Mode device created == %p, got %p.\n",
5298 d3ddevice1, d3drm_d3ddevice1);
5300 /* Check properties of render target and depth surfaces */
5301 hr = IDirect3DDevice_QueryInterface(d3drm_d3ddevice1, &IID_IDirectDrawSurface, (void **)&surface);
5302 ok(SUCCEEDED(hr), "Cannot get surface to the render target (hr = %#x).\n", hr);
5304 memset(&desc, 0, sizeof(desc));
5305 desc.dwSize = sizeof(desc);
5306 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
5307 ok(SUCCEEDED(hr), "Cannot get surface desc structure (hr = %#x).\n", hr);
5309 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %u, %u, got %u, %u.\n",
5310 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5311 ok((desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE),
5312 "Expected caps containing %x, got %x.\n", DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE, desc.ddsCaps.dwCaps);
5313 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5314 ok(desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, desc.dwFlags);
5316 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
5317 ok(SUCCEEDED(hr), "Cannot get attached depth surface (hr = %x).\n", hr);
5318 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
5320 desc.dwSize = sizeof(desc);
5321 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
5322 ok(SUCCEEDED(hr), "Cannot get z surface desc structure (hr = %#x).\n", hr);
5324 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %u, %u, got %u, %u.\n",
5325 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5326 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Expected caps containing %#x, got %#x.\n",
5327 DDSCAPS_ZBUFFER, desc.ddsCaps.dwCaps);
5328 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5329 ok(desc.dwFlags == expected_flags, "Expected %#x for flags, got %#x.\n", expected_flags, desc.dwFlags);
5331 IDirectDrawSurface_Release(d3drm_ds);
5332 IDirectDrawSurface_Release(ds);
5333 IDirectDrawSurface_Release(surface);
5334 IDirect3DDevice_Release(d3drm_d3ddevice1);
5335 IDirect3DRMDevice_Release(device1);
5336 ref2 = get_refcount((IUnknown *)d3drm1);
5337 ok(ref1 == ref2, "expected ref1 == ref2, got ref1 = %u, ref2 = %u.\n", ref1, ref2);
5338 device_ref2 = get_refcount((IUnknown *)d3ddevice1);
5339 ok(device_ref2 == device_ref1, "Expected device_ref2 == device_ref1, got device_ref1 = %u, device_ref2 = %u.\n",
5340 device_ref1, device_ref2);
5341 d3d_ref2 = get_refcount((IUnknown *)d3d1);
5342 todo_wine ok(d3d_ref2 > d3d_ref1, "Expected d3d_ref2 > d3d_ref1, got d3d_ref1 = %u, d3d_ref2 = %u.\n", d3d_ref1,
5343 d3d_ref2);
5345 IDirect3DRM_Release(d3drm1);
5346 IDirect3DDevice_Release(d3ddevice1);
5347 IDirect3D_Release(d3d1);
5348 IDirectDraw_Release(ddraw1);
5349 DestroyWindow(window);
5352 static IDirect3DDevice2 *create_device2(IDirectDraw2 *ddraw, HWND window, IDirectDrawSurface **ds)
5354 static const DWORD z_depths[] = { 32, 24, 16 };
5355 IDirectDrawSurface *surface;
5356 IDirect3DDevice2 *device = NULL;
5357 DDSURFACEDESC surface_desc;
5358 IDirect3D2 *d3d;
5359 unsigned int i;
5360 HRESULT hr;
5361 RECT rc;
5363 GetClientRect(window, &rc);
5364 hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
5365 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
5367 memset(&surface_desc, 0, sizeof(surface_desc));
5368 surface_desc.dwSize = sizeof(surface_desc);
5369 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
5370 surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
5371 surface_desc.dwWidth = rc.right;
5372 surface_desc.dwHeight = rc.bottom;
5374 hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface, NULL);
5375 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
5377 hr = IDirectDraw2_QueryInterface(ddraw, &IID_IDirect3D2, (void **)&d3d);
5378 if (FAILED(hr))
5380 IDirectDrawSurface_Release(surface);
5381 *ds = NULL;
5382 return NULL;
5385 /* We used to use EnumDevices() for this, but it seems
5386 * D3DDEVICEDESC.dwDeviceZBufferBitDepth only has a very casual
5387 * relationship with reality. */
5388 for (i = 0; i < ARRAY_SIZE(z_depths); ++i)
5390 memset(&surface_desc, 0, sizeof(surface_desc));
5391 surface_desc.dwSize = sizeof(surface_desc);
5392 surface_desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT;
5393 surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
5394 U2(surface_desc).dwZBufferBitDepth = z_depths[i];
5395 surface_desc.dwWidth = rc.right;
5396 surface_desc.dwHeight = rc.bottom;
5397 if (FAILED(IDirectDraw2_CreateSurface(ddraw, &surface_desc, ds, NULL)))
5398 continue;
5400 hr = IDirectDrawSurface_AddAttachedSurface(surface, *ds);
5401 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#x.\n", hr);
5402 if (FAILED(hr))
5404 IDirectDrawSurface_Release(*ds);
5405 continue;
5408 if (SUCCEEDED(IDirect3D2_CreateDevice(d3d, &IID_IDirect3DHALDevice, surface, &device)))
5409 break;
5411 IDirectDrawSurface_DeleteAttachedSurface(surface, 0, *ds);
5412 IDirectDrawSurface_Release(*ds);
5413 *ds = NULL;
5416 IDirect3D2_Release(d3d);
5417 IDirectDrawSurface_Release(surface);
5418 return device;
5421 static void test_create_device_from_d3d2(void)
5423 IDirectDraw *ddraw1 = NULL, *temp_ddraw1;
5424 IDirectDraw2 *ddraw2 = NULL, *temp_ddraw2;
5425 IDirect3D* d3d1;
5426 IDirect3D2 *d3d2 = NULL, *temp_d3d2;
5427 IDirect3DRM *d3drm1 = NULL;
5428 IDirect3DRM2 *d3drm2 = NULL;
5429 IDirect3DRMDevice *device1;
5430 IDirect3DRMDevice2 *device2 = (IDirect3DRMDevice2 *)0xdeadbeef;
5431 IDirect3DDevice *d3ddevice1;
5432 IDirect3DDevice2 *d3ddevice2 = NULL, *d3drm_d3ddevice2 = NULL, *temp_d3ddevice2;
5433 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_ds = NULL;
5434 DWORD expected_flags, ret_val;
5435 DDSCAPS caps = { DDSCAPS_ZBUFFER };
5436 DDSURFACEDESC desc;
5437 RECT rc;
5438 HWND window;
5439 ULONG ref1, ref2, ref3, ref4, ref5, device_ref1, device_ref2, d3d_ref1, d3d_ref2;
5440 HRESULT hr;
5442 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
5443 ok(hr == DD_OK, "Cannot get IDirectDraw interface (hr = %x).\n", hr);
5445 window = create_window();
5446 GetClientRect(window, &rc);
5448 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D2, (void **)&d3d2);
5449 ok(hr == DD_OK, "Cannot get IDirect3D2 interface (hr = %x).\n", hr);
5450 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2);
5451 ok(hr == DD_OK, "Cannot get IDirectDraw2 interface (hr = %x).\n", hr);
5452 d3d_ref1 = get_refcount((IUnknown *)d3d2);
5454 /* Create the immediate mode device */
5455 d3ddevice2 = create_device2(ddraw2, window, &ds);
5456 if (d3ddevice2 == NULL)
5458 win_skip("Cannot create IM device, skipping tests.\n");
5459 IDirect3D2_Release(d3d2);
5460 IDirectDraw2_Release(ddraw2);
5461 IDirectDraw_Release(ddraw1);
5462 return;
5464 device_ref1 = get_refcount((IUnknown *)d3ddevice2);
5466 hr = Direct3DRMCreate(&d3drm1);
5467 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr);
5468 ref1 = get_refcount((IUnknown *)d3drm1);
5470 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
5471 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM2 interface (hr = %x).\n", hr);
5472 ref2 = get_refcount((IUnknown *)d3drm2);
5474 hr = IDirect3DRM2_CreateDeviceFromD3D(d3drm2, NULL, d3ddevice2, &device2);
5475 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
5476 ok(device2 == NULL, "Expected device returned == NULL, got %p.\n", device2);
5477 hr = IDirect3DRM2_CreateDeviceFromD3D(d3drm2, d3d2, NULL, &device2);
5478 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
5479 hr = IDirect3DRM2_CreateDeviceFromD3D(d3drm2, d3d2, d3ddevice2, NULL);
5480 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
5482 hr = IDirect3DRM2_CreateDeviceFromD3D(d3drm2, d3d2, d3ddevice2, &device2);
5483 ok(hr == DD_OK, "Failed to create IDirect3DRMDevice2 interface (hr = %x)\n", hr);
5484 ref3 = get_refcount((IUnknown *)d3drm1);
5485 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
5486 ref3 = get_refcount((IUnknown *)d3drm2);
5487 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
5488 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
5489 ok(device_ref2 > device_ref1, "Expected device_ref2 > device_ref1, got device_ref1 = %u, device_ref2 = %u.\n", device_ref1, device_ref2);
5490 d3d_ref2 = get_refcount((IUnknown *)d3d2);
5491 ok(d3d_ref2 > d3d_ref1, "Expected d3d_ref2 > d3d_ref1, got d3d_ref1 = %u, d3d_ref2 = %u.\n", d3d_ref1, d3d_ref2);
5492 ret_val = IDirect3DRMDevice2_GetWidth(device2);
5493 ok(ret_val == rc.right, "Expected device width = 300, got %u.\n", ret_val);
5494 ret_val = IDirect3DRMDevice2_GetHeight(device2);
5495 ok(ret_val == rc.bottom, "Expected device height == 200, got %u.\n", ret_val);
5497 hr = IDirectDraw_EnumSurfaces(ddraw1, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
5498 NULL, &surface, surface_callback);
5499 ok(hr == DD_OK, "Failed to enumerate surfaces (hr = %x).\n", hr);
5500 ok(surface == NULL, "No primary surface should have enumerated (%p).\n", surface);
5502 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3drm_d3ddevice2);
5503 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface (hr = %x).\n", hr);
5504 ok(d3ddevice2 == d3drm_d3ddevice2, "Expected Immediate Mode device created == %p, got %p.\n", d3ddevice2, d3drm_d3ddevice2);
5506 /* Check properties of render target and depth surfaces */
5507 hr = IDirect3DDevice2_GetRenderTarget(d3drm_d3ddevice2, &surface);
5508 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
5510 memset(&desc, 0, sizeof(desc));
5511 desc.dwSize = sizeof(desc);
5512 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
5513 ok(hr == DD_OK, "Cannot get surface desc structure (hr = %x).\n", hr);
5515 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %u, %u, got %u, %u.\n",
5516 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5517 ok((desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE),
5518 "Expected caps containing %x, got %x.\n", DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE, desc.ddsCaps.dwCaps);
5519 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5520 ok(desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, desc.dwFlags);
5522 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
5523 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
5524 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
5526 desc.dwSize = sizeof(desc);
5527 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
5528 ok(hr == DD_OK, "Cannot get z surface desc structure (hr = %x).\n", hr);
5530 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %u, %u, got %u, %u.\n",
5531 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5532 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Expected caps containing %x, got %x.\n", DDSCAPS_ZBUFFER, desc.ddsCaps.dwCaps);
5533 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5534 ok(desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, desc.dwFlags);
5536 IDirectDrawSurface_Release(d3drm_ds);
5537 IDirectDrawSurface_Release(ds);
5538 IDirectDrawSurface_Release(surface);
5539 IDirect3DDevice2_Release(d3drm_d3ddevice2);
5540 IDirect3DRMDevice2_Release(device2);
5541 ref3 = get_refcount((IUnknown *)d3drm1);
5542 ok(ref1 == ref3, "expected ref1 == ref3, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
5543 ref3 = get_refcount((IUnknown *)d3drm2);
5544 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
5545 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
5546 ok(device_ref2 == device_ref1, "Expected device_ref2 == device_ref1, got device_ref1 = %u, device_ref2 = %u.\n", device_ref1, device_ref2);
5547 d3d_ref2 = get_refcount((IUnknown *)d3d2);
5548 ok(d3d_ref2 == d3d_ref1, "Expected d3d_ref2 == d3d_ref1, got d3d_ref1 = %u, d3d_ref2 = %u.\n", d3d_ref1, d3d_ref2);
5550 /* InitFromD3D tests */
5551 hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMDevice, NULL, &IID_IDirect3DRMDevice2, (void **)&device2);
5552 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice2 interface (hr = %#x).\n", hr);
5554 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1);
5555 ok(SUCCEEDED(hr), "Cannot get IDirect3D interface (hr = %x).\n", hr);
5556 if (SUCCEEDED(hr = IDirect3DDevice2_QueryInterface(d3ddevice2, &IID_IDirect3DDevice, (void **)&d3ddevice1)))
5558 hr = IDirect3DRMDevice2_InitFromD3D(device2, d3d1, d3ddevice1);
5559 ok(hr == E_NOINTERFACE, "Expected hr == E_NOINTERFACE, got %#x.\n", hr);
5560 hr = IDirect3DRMDevice2_InitFromD3D(device2, NULL, d3ddevice1);
5561 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
5562 hr = IDirect3DRMDevice2_InitFromD3D(device2, d3d1, NULL);
5563 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
5564 hr = IDirect3DRMDevice2_QueryInterface(device2, &IID_IDirect3DRMDevice, (void **)&device1);
5565 ok(SUCCEEDED(hr), "Cannot obtain IDirect3DRMDevice interface (hr = %#x).\n", hr);
5566 hr = IDirect3DRMDevice_InitFromD3D(device1, d3d1, d3ddevice1);
5567 todo_wine ok(hr == E_NOINTERFACE, "Expected hr == E_NOINTERFACE, got %#x.\n", hr);
5568 IDirect3DRMDevice_Release(device1);
5569 if (SUCCEEDED(hr))
5571 IDirect3DRMDevice_Release(device1);
5572 hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMDevice, NULL, &IID_IDirect3DRMDevice2,
5573 (void **)&device2);
5574 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice2 interface (hr = %#x).\n", hr);
5577 IDirect3D_Release(d3d1);
5578 IDirect3DDevice_Release(d3ddevice1);
5580 hr = IDirect3DRMDevice2_InitFromD3D2(device2, NULL, d3ddevice2);
5581 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
5582 hr = IDirect3DRMDevice2_InitFromD3D2(device2, d3d2, NULL);
5583 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
5585 hr = IDirect3DRMDevice2_InitFromD3D2(device2, d3d2, d3ddevice2);
5586 ok(SUCCEEDED(hr), "Failed to initialise IDirect3DRMDevice2 interface (hr = %#x)\n", hr);
5587 ref4 = get_refcount((IUnknown *)d3drm1);
5588 ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u , ref4 = %u.\n", ref1, ref4);
5589 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
5590 ok(device_ref2 > device_ref1, "Expected device_ref2 > device_ref1, got device_ref1 = %u, device_ref2 = %u.\n",
5591 device_ref1, device_ref2);
5592 d3d_ref2 = get_refcount((IUnknown *)d3d2);
5593 ok(d3d_ref2 > d3d_ref1, "Expected d3d_ref2 > d3d_ref1, got d3d_ref1 = %u, d3d_ref2 = %u.\n", d3d_ref1, d3d_ref2);
5594 ret_val = IDirect3DRMDevice2_GetWidth(device2);
5595 ok(ret_val == rc.right, "Expected device width = 300, got %u.\n", ret_val);
5596 ret_val = IDirect3DRMDevice2_GetHeight(device2);
5597 ok(ret_val == rc.bottom, "Expected device height == 200, got %u.\n", ret_val);
5599 hr = IDirect3DRMDevice2_InitFromD3D2(device2, d3d2, d3ddevice2);
5600 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
5601 ref3 = get_refcount((IUnknown *)d3drm1);
5602 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
5603 ref3 = get_refcount((IUnknown *)d3ddevice2);
5604 ok(ref3 > device_ref2, "Expected ref3 > device_ref2, got ref3 = %u, device_ref2 = %u.\n", ref3, device_ref2);
5605 ref3 = get_refcount((IUnknown *)d3d2);
5606 ok(ref3 > d3d_ref2, "Expected ref3 > d3d_ref2, got ref3 = %u, d3d_ref2 = %u.\n", ref3, d3d_ref2);
5607 /* Release leaked references */
5608 while (IDirect3DRM_Release(d3drm1) > ref4);
5609 while (IDirect3DDevice2_Release(d3ddevice2) > device_ref2);
5610 while (IDirect3D2_Release(d3d2) > d3d_ref2);
5612 hr = DirectDrawCreate(NULL, &temp_ddraw1, NULL);
5613 ok(SUCCEEDED(hr), "Cannot get IDirectDraw interface (hr = %#x).\n", hr);
5614 hr = IDirectDraw_QueryInterface(temp_ddraw1, &IID_IDirect3D2, (void **)&temp_d3d2);
5615 ok(SUCCEEDED(hr), "Cannot get IDirect3D2 interface (hr = %#x).\n", hr);
5616 ref5 = get_refcount((IUnknown *)temp_d3d2);
5618 hr = IDirectDraw_QueryInterface(temp_ddraw1, &IID_IDirectDraw2, (void **)&temp_ddraw2);
5619 ok(SUCCEEDED(hr), "Cannot get IDirectDraw2 interface (hr = %#x).\n", hr);
5621 temp_d3ddevice2 = create_device2(temp_ddraw2, window, &surface);
5622 hr = IDirect3DRMDevice2_InitFromD3D2(device2, temp_d3d2, temp_d3ddevice2);
5623 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
5624 ref3 = get_refcount((IUnknown *)d3drm1);
5625 ok(ref3 > ref4, "expected ref3 > ref4, got ref3 = %u , ref4 = %u.\n", ref3, ref4);
5626 ref3 = get_refcount((IUnknown *)temp_d3ddevice2);
5627 ok(ref3 == device_ref2, "Expected ref3 == device_ref2, got ref3 = %u, device_ref2 = %u.\n", ref3, device_ref2);
5628 ref3 = get_refcount((IUnknown *)temp_d3d2);
5629 ok(ref3 == d3d_ref2, "Expected ref3 == d3d_ref2, got ref3 = %u, d3d_ref2 = %u.\n", ref3, d3d_ref2);
5630 /* Release leaked references */
5631 while (IDirect3DRM_Release(d3drm1) > ref4);
5632 while (IDirect3DDevice2_Release(temp_d3ddevice2) > 0);
5633 while (IDirect3D2_Release(temp_d3d2) >= ref5);
5634 IDirectDrawSurface_Release(surface);
5635 IDirectDraw2_Release(temp_ddraw2);
5636 IDirectDraw_Release(temp_ddraw1);
5638 surface = NULL;
5639 hr = IDirectDraw_EnumSurfaces(ddraw1, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
5640 NULL, &surface, surface_callback);
5641 ok(SUCCEEDED(hr), "Failed to enumerate surfaces (hr = %#x).\n", hr);
5642 ok(surface == NULL, "No primary surface should have enumerated (%p).\n", surface);
5644 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3drm_d3ddevice2);
5645 ok(SUCCEEDED(hr), "Cannot get IDirect3DDevice2 interface (hr = %#x).\n", hr);
5646 ok(d3ddevice2 == d3drm_d3ddevice2, "Expected Immediate Mode device created == %p, got %p.\n", d3ddevice2,
5647 d3drm_d3ddevice2);
5649 /* Check properties of render target and depth surfaces */
5650 hr = IDirect3DDevice2_GetRenderTarget(d3drm_d3ddevice2, &surface);
5651 ok(SUCCEEDED(hr), "Cannot get surface to the render target (hr = %#x).\n", hr);
5653 memset(&desc, 0, sizeof(desc));
5654 desc.dwSize = sizeof(desc);
5655 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
5656 ok(SUCCEEDED(hr), "Cannot get surface desc structure (hr = %#x).\n", hr);
5658 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %u, %u, got %u, %u.\n",
5659 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5660 ok((desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE),
5661 "Expected caps containing %#x, got %#x.\n", DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE, desc.ddsCaps.dwCaps);
5662 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5663 ok(desc.dwFlags == expected_flags, "Expected %#x for flags, got %#x.\n", expected_flags, desc.dwFlags);
5665 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
5666 ok(SUCCEEDED(hr), "Cannot get attached depth surface (hr = %x).\n", hr);
5667 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
5669 desc.dwSize = sizeof(desc);
5670 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
5671 ok(SUCCEEDED(hr), "Cannot get z surface desc structure (hr = %x).\n", hr);
5673 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %u, %u, got %u, %u.\n",
5674 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5675 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Expected caps containing %#x, got %#x.\n",
5676 DDSCAPS_ZBUFFER, desc.ddsCaps.dwCaps);
5677 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5678 ok(desc.dwFlags == expected_flags, "Expected %#x for flags, got %#x.\n", expected_flags, desc.dwFlags);
5680 IDirectDrawSurface_Release(d3drm_ds);
5681 IDirectDrawSurface_Release(ds);
5682 IDirectDrawSurface_Release(surface);
5683 IDirect3DDevice2_Release(d3drm_d3ddevice2);
5684 IDirect3DRMDevice2_Release(device2);
5685 ref3 = get_refcount((IUnknown *)d3drm1);
5686 ok(ref1 == ref3, "Expected ref1 == ref3, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
5687 ref3 = get_refcount((IUnknown *)d3drm2);
5688 ok(ref3 == ref2, "Expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
5689 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
5690 ok(device_ref2 == device_ref1, "Expected device_ref2 == device_ref1, got device_ref1 = %u, device_ref2 = %u.\n",
5691 device_ref1, device_ref2);
5692 d3d_ref2 = get_refcount((IUnknown *)d3d2);
5693 ok(d3d_ref2 == d3d_ref1, "Expected d3d_ref2 == d3d_ref1, got d3d_ref1 = %u, d3d_ref2 = %u.\n", d3d_ref1, d3d_ref2);
5695 IDirect3DRM2_Release(d3drm2);
5696 IDirect3DRM_Release(d3drm1);
5697 IDirect3DDevice2_Release(d3ddevice2);
5698 IDirect3D2_Release(d3d2);
5699 IDirectDraw2_Release(ddraw2);
5700 IDirectDraw_Release(ddraw1);
5701 DestroyWindow(window);
5704 static void test_create_device_from_d3d3(void)
5706 IDirectDraw *ddraw1 = NULL, *temp_ddraw1;
5707 IDirectDraw2 *ddraw2 = NULL, *temp_ddraw2;
5708 IDirect3D *d3d1;
5709 IDirect3D2 *d3d2 = NULL, *temp_d3d2;
5710 IDirect3DRM *d3drm1 = NULL;
5711 IDirect3DRM3 *d3drm3 = NULL;
5712 IDirect3DRMDevice *device1;
5713 IDirect3DRMDevice3 *device3 = (IDirect3DRMDevice3 *)0xdeadbeef;
5714 IDirect3DDevice *d3ddevice1;
5715 IDirect3DDevice2 *d3ddevice2 = NULL, *d3drm_d3ddevice2 = NULL, *temp_d3ddevice2;
5716 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_ds = NULL;
5717 DWORD expected_flags, ret_val;
5718 DDSCAPS caps = { DDSCAPS_ZBUFFER };
5719 DDSURFACEDESC desc;
5720 RECT rc;
5721 HWND window;
5722 ULONG ref1, ref2, ref3, ref4, ref5, device_ref1, device_ref2, d3d_ref1, d3d_ref2;
5723 HRESULT hr;
5725 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
5726 ok(hr == DD_OK, "Cannot get IDirectDraw interface (hr = %x).\n", hr);
5728 window = create_window();
5729 GetClientRect(window, &rc);
5731 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D2, (void **)&d3d2);
5732 ok(hr == DD_OK, "Cannot get IDirect3D2 interface (hr = %x).\n", hr);
5733 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2);
5734 ok(hr == DD_OK, "Cannot get IDirectDraw2 interface (hr = %x).\n", hr);
5735 d3d_ref1 = get_refcount((IUnknown *)d3d2);
5737 /* Create the immediate mode device */
5738 d3ddevice2 = create_device2(ddraw2, window, &ds);
5739 if (d3ddevice2 == NULL)
5741 win_skip("Cannot create IM device, skipping tests.\n");
5742 IDirect3D2_Release(d3d2);
5743 IDirectDraw2_Release(ddraw2);
5744 IDirectDraw_Release(ddraw1);
5745 return;
5747 device_ref1 = get_refcount((IUnknown *)d3ddevice2);
5749 hr = Direct3DRMCreate(&d3drm1);
5750 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr);
5751 ref1 = get_refcount((IUnknown *)d3drm1);
5753 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
5754 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface (hr = %x).\n", hr);
5755 ref2 = get_refcount((IUnknown *)d3drm3);
5757 hr = IDirect3DRM3_CreateDeviceFromD3D(d3drm3, NULL, d3ddevice2, &device3);
5758 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
5759 ok(device3 == NULL, "Expected device returned == NULL, got %p.\n", device3);
5760 hr = IDirect3DRM3_CreateDeviceFromD3D(d3drm3, d3d2, NULL, &device3);
5761 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
5762 hr = IDirect3DRM3_CreateDeviceFromD3D(d3drm3, d3d2, d3ddevice2, NULL);
5763 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
5765 hr = IDirect3DRM3_CreateDeviceFromD3D(d3drm3, d3d2, d3ddevice2, &device3);
5766 ok(hr == DD_OK, "Failed to create IDirect3DRMDevice3 interface (hr = %x)\n", hr);
5767 ref3 = get_refcount((IUnknown *)d3drm1);
5768 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
5769 ref3 = get_refcount((IUnknown *)d3drm3);
5770 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
5771 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
5772 ok(device_ref2 > device_ref1, "Expected device_ref2 > device_ref1, got device_ref1 = %u, device_ref2 = %u.\n", device_ref1, device_ref2);
5773 ret_val = IDirect3DRMDevice3_GetWidth(device3);
5774 ok(ret_val == rc.right, "Expected device width = 300, got %u.\n", ret_val);
5775 ret_val = IDirect3DRMDevice3_GetHeight(device3);
5776 ok(ret_val == rc.bottom, "Expected device height == 200, got %u.\n", ret_val);
5778 hr = IDirectDraw_EnumSurfaces(ddraw1, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
5779 NULL, &surface, surface_callback);
5780 ok(hr == DD_OK, "Failed to enumerate surfaces (hr = %x).\n", hr);
5781 ok(surface == NULL, "No primary surface should have enumerated (%p).\n", surface);
5783 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3drm_d3ddevice2);
5784 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface (hr = %x).\n", hr);
5785 ok(d3ddevice2 == d3drm_d3ddevice2, "Expected Immediate Mode device created == %p, got %p.\n", d3ddevice2, d3drm_d3ddevice2);
5787 /* Check properties of render target and depth surfaces */
5788 hr = IDirect3DDevice2_GetRenderTarget(d3drm_d3ddevice2, &surface);
5789 ok(hr == DD_OK, "Cannot get surface to the render target (hr = %x).\n", hr);
5791 memset(&desc, 0, sizeof(desc));
5792 desc.dwSize = sizeof(desc);
5793 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
5794 ok(hr == DD_OK, "Cannot get surface desc structure (hr = %x).\n", hr);
5796 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %u, %u, got %u, %u.\n",
5797 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5798 ok((desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE),
5799 "Expected caps containing %x, got %x.\n", DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE, desc.ddsCaps.dwCaps);
5800 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5801 ok(desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, desc.dwFlags);
5803 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
5804 ok(hr == DD_OK, "Cannot get attached depth surface (hr = %x).\n", hr);
5805 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
5807 desc.dwSize = sizeof(desc);
5808 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
5809 ok(hr == DD_OK, "Cannot get z surface desc structure (hr = %x).\n", hr);
5811 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %u, %u, got %u, %u.\n",
5812 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5813 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Expected caps containing %x, got %x.\n", DDSCAPS_ZBUFFER, desc.ddsCaps.dwCaps);
5814 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5815 ok(desc.dwFlags == expected_flags, "Expected %x for flags, got %x.\n", expected_flags, desc.dwFlags);
5817 IDirectDrawSurface_Release(d3drm_ds);
5818 IDirectDrawSurface_Release(ds);
5819 IDirectDrawSurface_Release(surface);
5820 IDirect3DDevice2_Release(d3drm_d3ddevice2);
5821 IDirect3DRMDevice3_Release(device3);
5822 ref3 = get_refcount((IUnknown *)d3drm1);
5823 ok(ref1 == ref3, "expected ref1 == ref3, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
5824 ref3 = get_refcount((IUnknown *)d3drm3);
5825 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
5826 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
5827 ok(device_ref2 == device_ref1, "Expected device_ref2 == device_ref1, got device_ref1 = %u, device_ref2 = %u.\n", device_ref1, device_ref2);
5828 d3d_ref2 = get_refcount((IUnknown *)d3d2);
5829 ok(d3d_ref2 == d3d_ref1, "Expected d3d_ref2 == d3d_ref1, got d3d_ref1 = %u, d3d_ref2 = %u.\n", d3d_ref1, d3d_ref2);
5831 /* InitFromD3D tests */
5832 hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMDevice, NULL, &IID_IDirect3DRMDevice3, (void **)&device3);
5833 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface (hr = %#x).\n", hr);
5835 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1);
5836 ok(SUCCEEDED(hr), "Cannot get IDirect3D interface (hr = %#x).\n", hr);
5837 if (SUCCEEDED(hr = IDirect3DDevice2_QueryInterface(d3ddevice2, &IID_IDirect3DDevice, (void **)&d3ddevice1)))
5839 hr = IDirect3DRMDevice3_InitFromD3D(device3, d3d1, d3ddevice1);
5840 ok(hr == E_NOINTERFACE, "Expected hr == E_NOINTERFACE, got %#x.\n", hr);
5841 hr = IDirect3DRMDevice3_InitFromD3D(device3, NULL, d3ddevice1);
5842 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
5843 hr = IDirect3DRMDevice3_InitFromD3D(device3, d3d1, NULL);
5844 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
5845 hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice, (void **)&device1);
5846 ok(SUCCEEDED(hr), "Cannot obtain IDirect3DRMDevice interface (hr = %#x).\n", hr);
5847 hr = IDirect3DRMDevice_InitFromD3D(device1, d3d1, d3ddevice1);
5848 todo_wine ok(hr == E_NOINTERFACE, "Expected hr == E_NOINTERFACE, got %#x.\n", hr);
5849 IDirect3DRMDevice_Release(device1);
5850 if (SUCCEEDED(hr))
5852 IDirect3DRMDevice_Release(device1);
5853 hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMDevice, NULL, &IID_IDirect3DRMDevice3,
5854 (void **)&device3);
5855 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface (hr = %#x).\n", hr);
5858 IDirect3D_Release(d3d1);
5859 IDirect3DDevice_Release(d3ddevice1);
5861 hr = IDirect3DRMDevice3_InitFromD3D2(device3, NULL, d3ddevice2);
5862 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
5863 hr = IDirect3DRMDevice3_InitFromD3D2(device3, d3d2, NULL);
5864 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
5866 hr = IDirect3DRMDevice3_InitFromD3D2(device3, d3d2, d3ddevice2);
5867 ok(SUCCEEDED(hr), "Failed to initialise IDirect3DRMDevice2 interface (hr = %#x)\n", hr);
5868 ref4 = get_refcount((IUnknown *)d3drm1);
5869 ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u , ref4 = %u.\n", ref1, ref4);
5870 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
5871 ok(device_ref2 > device_ref1, "Expected device_ref2 > device_ref1, got device_ref1 = %u, device_ref2 = %u.\n",
5872 device_ref1, device_ref2);
5873 d3d_ref2 = get_refcount((IUnknown *)d3d2);
5874 ok(d3d_ref2 > d3d_ref1, "Expected d3d_ref2 > d3d_ref1, got d3d_ref1 = %u, d3d_ref2 = %u.\n", d3d_ref1, d3d_ref2);
5875 ret_val = IDirect3DRMDevice3_GetWidth(device3);
5876 ok(ret_val == rc.right, "Expected device width = 300, got %u.\n", ret_val);
5877 ret_val = IDirect3DRMDevice3_GetHeight(device3);
5878 ok(ret_val == rc.bottom, "Expected device height == 200, got %u.\n", ret_val);
5880 hr = IDirect3DRMDevice3_InitFromD3D2(device3, d3d2, d3ddevice2);
5881 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
5882 ref3 = get_refcount((IUnknown *)d3drm1);
5883 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3);
5884 ref3 = get_refcount((IUnknown *)d3ddevice2);
5885 ok(ref3 > device_ref2, "Expected ref3 > device_ref2, got ref3 = %u, device_ref2 = %u.\n", ref3, device_ref2);
5886 ref3 = get_refcount((IUnknown *)d3d2);
5887 ok(ref3 > d3d_ref2, "Expected ref3 > d3d_ref2, got ref3 = %u, d3d_ref2 = %u.\n", ref3, d3d_ref2);
5888 /* Release leaked references */
5889 while (IDirect3DRM_Release(d3drm1) > ref4);
5890 while (IDirect3DDevice2_Release(d3ddevice2) > device_ref2);
5891 while (IDirect3D2_Release(d3d2) > d3d_ref2);
5893 hr = DirectDrawCreate(NULL, &temp_ddraw1, NULL);
5894 ok(SUCCEEDED(hr), "Cannot get IDirectDraw interface (hr = %#x).\n", hr);
5895 hr = IDirectDraw_QueryInterface(temp_ddraw1, &IID_IDirect3D2, (void **)&temp_d3d2);
5896 ok(SUCCEEDED(hr), "Cannot get IDirect3D2 interface (hr = %#x).\n", hr);
5897 ref5 = get_refcount((IUnknown *)temp_d3d2);
5899 hr = IDirectDraw_QueryInterface(temp_ddraw1, &IID_IDirectDraw2, (void **)&temp_ddraw2);
5900 ok(SUCCEEDED(hr), "Cannot get IDirectDraw2 interface (hr = %#x).\n", hr);
5902 temp_d3ddevice2 = create_device2(temp_ddraw2, window, &surface);
5903 hr = IDirect3DRMDevice3_InitFromD3D2(device3, temp_d3d2, temp_d3ddevice2);
5904 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
5905 ref3 = get_refcount((IUnknown *)d3drm1);
5906 ok(ref3 > ref4, "expected ref3 > ref4, got ref3 = %u , ref4 = %u.\n", ref3, ref4);
5907 ref3 = get_refcount((IUnknown *)temp_d3ddevice2);
5908 ok(ref3 == device_ref2, "Expected ref3 == device_ref2, got ref3 = %u, device_ref2 = %u.\n", ref3, device_ref2);
5909 ref3 = get_refcount((IUnknown *)temp_d3d2);
5910 ok(ref3 == d3d_ref2, "Expected ref3 == d3d_ref2, got ref3 = %u, d3d_ref2 = %u.\n", ref3, d3d_ref2);
5911 /* Release leaked references */
5912 while (IDirect3DRM_Release(d3drm1) > ref4);
5913 while (IDirect3DDevice2_Release(temp_d3ddevice2) > 0);
5914 while (IDirect3D2_Release(temp_d3d2) >= ref5);
5915 IDirectDrawSurface_Release(surface);
5916 IDirectDraw2_Release(temp_ddraw2);
5917 IDirectDraw_Release(temp_ddraw1);
5919 surface = NULL;
5920 hr = IDirectDraw_EnumSurfaces(ddraw1, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
5921 NULL, &surface, surface_callback);
5922 ok(SUCCEEDED(hr), "Failed to enumerate surfaces (hr = %#x).\n", hr);
5923 ok(surface == NULL, "No primary surface should have enumerated (%p).\n", surface);
5925 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3drm_d3ddevice2);
5926 ok(SUCCEEDED(hr), "Cannot get IDirect3DDevice2 interface (hr = %#x).\n", hr);
5927 ok(d3ddevice2 == d3drm_d3ddevice2, "Expected Immediate Mode device created == %p, got %p.\n", d3ddevice2,
5928 d3drm_d3ddevice2);
5930 /* Check properties of render target and depth surfaces */
5931 hr = IDirect3DDevice2_GetRenderTarget(d3drm_d3ddevice2, &surface);
5932 ok(SUCCEEDED(hr), "Cannot get surface to the render target (hr = %#x).\n", hr);
5934 memset(&desc, 0, sizeof(desc));
5935 desc.dwSize = sizeof(desc);
5936 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
5937 ok(SUCCEEDED(hr), "Cannot get surface desc structure (hr = %x).\n", hr);
5939 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %u, %u, got %u, %u.\n",
5940 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5941 ok((desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE),
5942 "Expected caps containing %#x, got %#x.\n", DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE, desc.ddsCaps.dwCaps);
5943 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5944 ok(desc.dwFlags == expected_flags, "Expected %#x for flags, got %#x.\n", expected_flags, desc.dwFlags);
5946 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
5947 ok(SUCCEEDED(hr), "Cannot get attached depth surface (hr = %x).\n", hr);
5948 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
5950 desc.dwSize = sizeof(desc);
5951 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
5952 ok(SUCCEEDED(hr), "Cannot get z surface desc structure (hr = %x).\n", hr);
5954 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %u, %u, got %u, %u.\n",
5955 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5956 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Expected caps containing %x, got %#x.\n",
5957 DDSCAPS_ZBUFFER, desc.ddsCaps.dwCaps);
5958 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5959 ok(desc.dwFlags == expected_flags, "Expected %#x for flags, got %#x.\n", expected_flags, desc.dwFlags);
5961 IDirectDrawSurface_Release(d3drm_ds);
5962 IDirectDrawSurface_Release(ds);
5963 IDirectDrawSurface_Release(surface);
5964 IDirect3DDevice2_Release(d3drm_d3ddevice2);
5965 IDirect3DRMDevice3_Release(device3);
5966 ref3 = get_refcount((IUnknown *)d3drm1);
5967 ok(ref1 == ref3, "expected ref1 == ref3, got ref1 = %u, ref3 = %u.\n", ref1, ref3);
5968 ref3 = get_refcount((IUnknown *)d3drm3);
5969 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3);
5970 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
5971 ok(device_ref2 == device_ref1, "Expected device_ref2 == device_ref1, got device_ref1 = %u, device_ref2 = %u.\n",
5972 device_ref1, device_ref2);
5973 d3d_ref2 = get_refcount((IUnknown *)d3d2);
5974 ok(d3d_ref2 == d3d_ref1, "Expected d3d_ref2 == d3d_ref1, got d3d_ref1 = %u, d3d_ref2 = %u.\n", d3d_ref1, d3d_ref2);
5976 IDirect3DRM3_Release(d3drm3);
5977 IDirect3DRM_Release(d3drm1);
5978 IDirect3DDevice2_Release(d3ddevice2);
5979 IDirect3D2_Release(d3d2);
5980 IDirectDraw2_Release(ddraw2);
5981 IDirectDraw_Release(ddraw1);
5982 DestroyWindow(window);
5985 static void test_create_device_1(void)
5987 IDirect3DRM *d3drm = NULL;
5988 IDirect3DRMDevice *device = (IDirect3DRMDevice *)0xdeadbeef;
5989 HRESULT hr;
5991 hr = Direct3DRMCreate(&d3drm);
5992 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr);
5994 hr = IDirect3DRM_CreateDevice(d3drm, 640, 480, &device);
5995 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == D3DRMERR_BADDEVICE, got %x.\n", hr);
5996 ok(device == NULL, "Expected device returned == NULL, got %p.\n", device);
5997 hr = IDirect3DRM_CreateDevice(d3drm, 640, 480, NULL);
5998 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
6000 IDirect3DRM_Release(d3drm);
6003 static void test_create_device_2(void)
6005 IDirect3DRM *d3drm = NULL;
6006 IDirect3DRM2 *d3drm2 = NULL;
6007 IDirect3DRMDevice2 *device2 = (IDirect3DRMDevice2 *)0xdeadbeef;
6008 HRESULT hr;
6010 hr = Direct3DRMCreate(&d3drm);
6011 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr);
6012 hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM2, (void **)&d3drm2);
6013 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface (hr = %x).\n", hr);
6015 hr = IDirect3DRM2_CreateDevice(d3drm2, 640, 480, &device2);
6016 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == D3DRMERR_BADDEVICE, got %x.\n", hr);
6017 ok(device2 == NULL, "Expected device returned == NULL, got %p.\n", device2);
6018 hr = IDirect3DRM2_CreateDevice(d3drm2, 640, 480, NULL);
6019 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
6021 IDirect3DRM2_Release(d3drm2);
6022 IDirect3DRM_Release(d3drm);
6025 static void test_create_device_3(void)
6027 IDirect3DRM *d3drm = NULL;
6028 IDirect3DRM3 *d3drm3 = NULL;
6029 IDirect3DRMDevice3 *device3 = (IDirect3DRMDevice3 *)0xdeadbeef;
6030 HRESULT hr;
6032 hr = Direct3DRMCreate(&d3drm);
6033 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr);
6034 hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM3, (void **)&d3drm3);
6035 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface (hr = %x).\n", hr);
6037 hr = IDirect3DRM3_CreateDevice(d3drm3, 640, 480, &device3);
6038 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == D3DRMERR_BADDEVICE, got %x.\n", hr);
6039 ok(device3 == NULL, "Expected device returned == NULL, got %p.\n", device3);
6040 hr = IDirect3DRM3_CreateDevice(d3drm3, 640, 480, NULL);
6041 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
6043 IDirect3DRM3_Release(d3drm3);
6044 IDirect3DRM_Release(d3drm);
6047 static char *create_bitmap(unsigned int w, unsigned int h, BOOL palettized)
6049 unsigned int bpp = palettized ? 8 : 24;
6050 BITMAPFILEHEADER file_header;
6051 DWORD written, size, ret;
6052 unsigned char *buffer;
6053 char path[MAX_PATH];
6054 unsigned int i, j;
6055 BITMAPINFO *info;
6056 char *filename;
6057 HANDLE file;
6059 ret = GetTempPathA(MAX_PATH, path);
6060 ok(ret, "Failed to get temporary file path.\n");
6061 filename = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
6062 ret = GetTempFileNameA(path, "d3d", 0, filename);
6063 ok(ret, "Failed to get filename.\n");
6064 file = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
6065 ok(file != INVALID_HANDLE_VALUE, "Failed to open temporary file \"%s\".\n", filename);
6067 size = FIELD_OFFSET(BITMAPINFO, bmiColors[palettized ? 256 : 0]);
6069 memset(&file_header, 0, sizeof(file_header));
6070 file_header.bfType = 0x4d42; /* BM */
6071 file_header.bfOffBits = sizeof(file_header) + size;
6072 file_header.bfSize = file_header.bfOffBits + w * h * (bpp / 8);
6073 ret = WriteFile(file, &file_header, sizeof(file_header), &written, NULL);
6074 ok(ret && written == sizeof(file_header), "Failed to write file header.\n");
6076 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
6077 info->bmiHeader.biSize = sizeof(info->bmiHeader);
6078 info->bmiHeader.biBitCount = bpp;
6079 info->bmiHeader.biPlanes = 1;
6080 info->bmiHeader.biWidth = w;
6081 info->bmiHeader.biHeight = h;
6082 info->bmiHeader.biCompression = BI_RGB;
6083 if (palettized)
6085 for (i = 0; i < 256; ++i)
6087 info->bmiColors[i].rgbBlue = i;
6088 info->bmiColors[i].rgbGreen = i;
6089 info->bmiColors[i].rgbRed = i;
6092 ret = WriteFile(file, info, size, &written, NULL);
6093 ok(ret && written == size, "Failed to write bitmap info.\n");
6094 HeapFree(GetProcessHeap(), 0, info);
6096 size = w * h * (bpp / 8);
6097 buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
6098 for (i = 0, j = 0; i < size;)
6100 if (palettized)
6102 buffer[i++] = j++;
6103 j %= 256;
6105 else
6107 buffer[i++] = j % 251;
6108 buffer[i++] = j % 239;
6109 buffer[i++] = j++ % 247;
6112 ret = WriteFile(file, buffer, size, &written, NULL);
6113 ok(ret && written == size, "Failed to write bitmap data.\n");
6114 HeapFree(GetProcessHeap(), 0, buffer);
6116 CloseHandle(file);
6118 return filename;
6121 static void test_bitmap_data(unsigned int test_idx, const D3DRMIMAGE *img,
6122 BOOL upside_down, unsigned int w, unsigned int h, BOOL palettized)
6124 const unsigned char *data = img->buffer1;
6125 unsigned int i, j;
6127 ok(img->width == w, "Test %u: Got unexpected image width %u, expected %u.\n", test_idx, img->width, w);
6128 ok(img->height == h, "Test %u: Got unexpected image height %u, expected %u.\n", test_idx, img->height, h);
6129 ok(img->aspectx == 1, "Test %u: Got unexpected image aspectx %u.\n", test_idx, img->aspectx);
6130 ok(img->aspecty == 1, "Test %u: Got unexpected image aspecty %u.\n", test_idx, img->aspecty);
6131 ok(!img->buffer2, "Test %u: Got unexpected image buffer2 %p.\n", test_idx, img->buffer2);
6133 /* The image is palettized if the total number of colors used is <= 256. */
6134 if (w * h > 256 && !palettized)
6136 /* D3drm aligns the 24bpp texture to 4 bytes in the buffer, with one
6137 * byte padding from 24bpp texture. */
6138 ok(img->depth == 32, "Test %u: Got unexpected image depth %u.\n", test_idx, img->depth);
6139 ok(img->rgb == TRUE, "Test %u: Got unexpected image rgb %#x.\n", test_idx, img->rgb);
6140 ok(img->bytes_per_line == w * 4, "Test %u: Got unexpected image bytes per line %u, expected %u.\n",
6141 test_idx, img->bytes_per_line, w * 4);
6142 ok(img->red_mask == 0xff0000, "Test %u: Got unexpected image red mask %#x.\n", test_idx, img->red_mask);
6143 ok(img->green_mask == 0x00ff00, "Test %u: Got unexpected image green mask %#x.\n", test_idx, img->green_mask);
6144 ok(img->blue_mask == 0x0000ff, "Test %u: Got unexpected image blue mask %#x.\n", test_idx, img->blue_mask);
6145 ok(!img->alpha_mask, "Test %u: Got unexpected image alpha mask %#x.\n", test_idx, img->alpha_mask);
6146 ok(!img->palette_size, "Test %u: Got unexpected palette size %u.\n", test_idx, img->palette_size);
6147 ok(!img->palette, "Test %u: Got unexpected image palette %p.\n", test_idx, img->palette);
6148 for (i = 0; i < h; ++i)
6150 for (j = 0; j < w; ++j)
6152 const unsigned char *ptr = &data[i * img->bytes_per_line + j * 4];
6153 unsigned int idx = upside_down ? (h - 1 - i) * w + j : i * w + j;
6155 if (ptr[0] != idx % 251 || ptr[1] != idx % 239 || ptr[2] != idx % 247 || ptr[3] != 0xff)
6157 ok(0, "Test %u: Got unexpected color 0x%02x%02x%02x%02x at position %u, %u, "
6158 "expected 0x%02x%02x%02x%02x.\n", test_idx, ptr[0], ptr[1], ptr[2], ptr[3],
6159 j, i, idx % 251, idx % 239, idx % 247, 0xff);
6160 return;
6164 return;
6167 ok(img->depth == 8, "Test %u: Got unexpected image depth %u.\n", test_idx, img->depth);
6168 ok(!img->rgb, "Test %u: Got unexpected image rgb %#x.\n", test_idx, img->rgb);
6169 ok(img->red_mask == 0xff, "Test %u: Got unexpected image red mask %#x.\n", test_idx, img->red_mask);
6170 ok(img->green_mask == 0xff, "Test %u: Got unexpected image green mask %#x.\n", test_idx, img->green_mask);
6171 ok(img->blue_mask == 0xff, "Test %u: Got unexpected image blue mask %#x.\n", test_idx, img->blue_mask);
6172 ok(!img->alpha_mask, "Test %u: Got unexpected image alpha mask %#x.\n", test_idx, img->alpha_mask);
6173 ok(!!img->palette, "Test %u: Got unexpected image palette %p.\n", test_idx, img->palette);
6174 if (!palettized)
6176 /* In this case, bytes_per_line is aligned to the next multiple of
6177 * 4 from width. */
6178 ok(img->bytes_per_line == ((w + 3) & ~3), "Test %u: Got unexpected image bytes per line %u, expected %u.\n",
6179 test_idx, img->bytes_per_line, (w + 3) & ~3);
6180 ok(img->palette_size == w * h, "Test %u: Got unexpected palette size %u, expected %u.\n",
6181 test_idx, img->palette_size, w * h);
6182 for (i = 0; i < img->palette_size; ++i)
6184 unsigned int idx = upside_down ? (h - 1) * w - i + (i % w) * 2 : i;
6185 ok(img->palette[i].red == idx % 251
6186 && img->palette[i].green == idx % 239 && img->palette[i].blue == idx % 247,
6187 "Test %u: Got unexpected palette entry (%u) color 0x%02x%02x%02x.\n",
6188 test_idx, i, img->palette[i].red, img->palette[i].green, img->palette[i].blue);
6189 ok(img->palette[i].flags == D3DRMPALETTE_READONLY,
6190 "Test %u: Got unexpected palette entry (%u) flags %#x.\n",
6191 test_idx, i, img->palette[i].flags);
6193 for (i = 0; i < h; ++i)
6195 for (j = 0; j < w; ++j)
6197 if (data[i * img->bytes_per_line + j] != i * w + j)
6199 ok(0, "Test %u: Got unexpected color 0x%02x at position %u, %u, expected 0x%02x.\n",
6200 test_idx, data[i * img->bytes_per_line + j], j, i, i * w + j);
6201 return;
6205 return;
6208 /* bytes_per_line is not always aligned by d3drm depending on the
6209 * format. */
6210 ok(img->bytes_per_line == w, "Test %u: Got unexpected image bytes per line %u, expected %u.\n",
6211 test_idx, img->bytes_per_line, w);
6212 ok(img->palette_size == 256, "Test %u: Got unexpected palette size %u.\n", test_idx, img->palette_size);
6213 for (i = 0; i < 256; ++i)
6215 ok(img->palette[i].red == i && img->palette[i].green == i && img->palette[i].blue == i,
6216 "Test %u: Got unexpected palette entry (%u) color 0x%02x%02x%02x.\n",
6217 test_idx, i, img->palette[i].red, img->palette[i].green, img->palette[i].blue);
6218 ok(img->palette[i].flags == D3DRMPALETTE_READONLY,
6219 "Test %u: Got unexpected palette entry (%u) flags %#x.\n",
6220 test_idx, i, img->palette[i].flags);
6222 for (i = 0; i < h; ++i)
6224 for (j = 0; j < w; ++j)
6226 unsigned int idx = upside_down ? (h - 1 - i) * w + j : i * w + j;
6227 if (data[i * img->bytes_per_line + j] != idx % 256)
6229 ok(0, "Test %u: Got unexpected color 0x%02x at position %u, %u, expected 0x%02x.\n",
6230 test_idx, data[i * img->bytes_per_line + j], j, i, idx % 256);
6231 return;
6237 static void test_load_texture(void)
6239 IDirect3DRMTexture3 *texture3;
6240 IDirect3DRMTexture2 *texture2;
6241 IDirect3DRMTexture *texture1;
6242 D3DRMIMAGE *d3drm_img;
6243 IDirect3DRM3 *d3drm3;
6244 IDirect3DRM2 *d3drm2;
6245 IDirect3DRM *d3drm1;
6246 ULONG ref1, ref2;
6247 unsigned int i;
6248 char *filename;
6249 HRESULT hr;
6250 BOOL ret;
6252 static const struct
6254 unsigned int w;
6255 unsigned int h;
6256 BOOL palettized;
6258 tests[] =
6260 {100, 100, TRUE },
6261 {99, 100, TRUE },
6262 {100, 100, FALSE},
6263 {99, 100, FALSE},
6264 {3, 39, FALSE},
6267 hr = Direct3DRMCreate(&d3drm1);
6268 ok(hr == D3DRM_OK, "Failed to create IDirect3DRM object, hr %#x.\n", hr);
6269 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
6270 ok(SUCCEEDED(hr), "Failed to get IDirect3DRM2 interface, hr %#x.\n", hr);
6271 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
6272 ok(SUCCEEDED(hr), "Failed to get IDirect3DRM3 interface, hr %#x.\n", hr);
6273 ref1 = get_refcount((IUnknown *)d3drm1);
6275 /* Test all failures together. */
6276 texture1 = (IDirect3DRMTexture *)0xdeadbeef;
6277 hr = IDirect3DRM_LoadTexture(d3drm1, NULL, &texture1);
6278 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr);
6279 ok(!texture1, "Got unexpected texture %p.\n", texture1);
6280 texture1 = (IDirect3DRMTexture *)0xdeadbeef;
6281 hr = IDirect3DRM_LoadTexture(d3drm1, "", &texture1);
6282 ok(hr == D3DRMERR_FILENOTFOUND, "Got unexpected hr %#x.\n", hr);
6283 ok(!texture1, "Got unexpected texture %p.\n", texture1);
6284 hr = IDirect3DRM_LoadTexture(d3drm1, NULL, NULL);
6285 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr);
6287 texture2 = (IDirect3DRMTexture2 *)0xdeadbeef;
6288 hr = IDirect3DRM2_LoadTexture(d3drm2, NULL, &texture2);
6289 ok(hr == D3DRMERR_FILENOTFOUND, "Got unexpected hr %#x.\n", hr);
6290 ok(!texture2, "Got unexpected texture %p.\n", texture2);
6291 texture2 = (IDirect3DRMTexture2 *)0xdeadbeef;
6292 hr = IDirect3DRM2_LoadTexture(d3drm2, "", &texture2);
6293 ok(hr == D3DRMERR_FILENOTFOUND, "Got unexpected hr %#x.\n", hr);
6294 ok(!texture2, "Got unexpected texture %p.\n", texture2);
6295 hr = IDirect3DRM2_LoadTexture(d3drm2, NULL, NULL);
6296 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr);
6298 texture3 = (IDirect3DRMTexture3 *)0xdeadbeef;
6299 hr = IDirect3DRM3_LoadTexture(d3drm3, NULL, &texture3);
6300 ok(hr == D3DRMERR_FILENOTFOUND, "Got unexpected hr %#x.\n", hr);
6301 ok(!texture3, "Got unexpected texture %p.\n", texture3);
6302 texture3 = (IDirect3DRMTexture3 *)0xdeadbeef;
6303 hr = IDirect3DRM_LoadTexture(d3drm3, "", &texture3);
6304 ok(hr == D3DRMERR_FILENOTFOUND, "Got unexpected hr %#x.\n", hr);
6305 ok(!texture3, "Got unexpected texture %p.\n", texture3);
6306 hr = IDirect3DRM3_LoadTexture(d3drm3, NULL, NULL);
6307 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr);
6309 for (i = 0; i < ARRAY_SIZE(tests); ++i)
6311 filename = create_bitmap(tests[i].w, tests[i].h, tests[i].palettized);
6313 hr = IDirect3DRM_LoadTexture(d3drm1, filename, &texture1);
6314 ok(SUCCEEDED(hr), "Test %u: Failed to load texture, hr %#x.\n", i, hr);
6315 ref2 = get_refcount((IUnknown *)d3drm1);
6316 ok(ref2 > ref1, "Test %u: expected ref2 > ref1, got ref1 %u, ref2 %u.\n", i, ref1, ref2);
6318 hr = IDirect3DRMTexture_InitFromFile(texture1, filename);
6319 ok(hr == D3DRMERR_BADOBJECT, "Test %u: Got unexpected hr %#x.\n", i, hr);
6320 /* InitFromFile() seems to AddRef() IDirect3DRM even if it fails. */
6321 IDirect3DRM_Release(d3drm1);
6322 d3drm_img = IDirect3DRMTexture_GetImage(texture1);
6323 ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
6324 test_bitmap_data(i * 7, d3drm_img, FALSE, tests[i].w, tests[i].h, tests[i].palettized);
6325 IDirect3DRMTexture_Release(texture1);
6326 ref2 = get_refcount((IUnknown *)d3drm1);
6327 ok(ref1 == ref2, "Test %u: expected ref1 == ref2, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
6328 hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_CDirect3DRMTexture,
6329 NULL, &IID_IDirect3DRMTexture, (void **)&texture1);
6330 ok(SUCCEEDED(hr), "Test %u: Failed to create texture, hr %#x.\n", i, hr);
6331 hr = IDirect3DRMTexture_InitFromFile(texture1, NULL);
6332 ok(hr == D3DRMERR_BADOBJECT, "Test %u: Got unexpected hr %#x.\n", i, hr);
6333 hr = IDirect3DRMTexture_InitFromFile(texture1, "");
6334 ok(hr == D3DRMERR_BADOBJECT, "Test %u: Got unexpected hr %#x.\n", i, hr);
6335 hr = IDirect3DRMTexture_InitFromFile(texture1, filename);
6336 ok(SUCCEEDED(hr), "Test %u: Failed to initialise texture from file, hr %#x.\n", i, hr);
6337 d3drm_img = IDirect3DRMTexture_GetImage(texture1);
6338 ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
6339 test_bitmap_data(i * 7 + 1, d3drm_img, FALSE, tests[i].w, tests[i].h, tests[i].palettized);
6340 IDirect3DRMTexture_Release(texture1);
6342 hr = IDirect3DRM2_LoadTexture(d3drm2, filename, &texture2);
6343 ok(SUCCEEDED(hr), "Test %u: Failed to load texture, hr %#x.\n", i, hr);
6344 ref2 = get_refcount((IUnknown *)d3drm1);
6345 ok(ref2 > ref1, "Test %u: expected ref2 > ref1, got ref1 %u, ref2 %u.\n", i, ref1, ref2);
6347 hr = IDirect3DRMTexture2_InitFromFile(texture2, filename);
6348 ok(hr == D3DRMERR_BADOBJECT, "Test %u: Got unexpected hr %#x.\n", i, hr);
6349 IDirect3DRM_Release(d3drm1);
6350 d3drm_img = IDirect3DRMTexture2_GetImage(texture2);
6351 ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
6352 test_bitmap_data(i * 7 + 2, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
6353 IDirect3DRMTexture2_Release(texture2);
6354 ref2 = get_refcount((IUnknown *)d3drm1);
6355 ok(ref1 == ref2, "Test %u: expected ref1 == ref2, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
6356 hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMTexture,
6357 NULL, &IID_IDirect3DRMTexture2, (void **)&texture2);
6358 ok(SUCCEEDED(hr), "Test %u: Failed to create texture, hr %#x.\n", i, hr);
6359 hr = IDirect3DRMTexture2_InitFromFile(texture2, NULL);
6360 ok(hr == D3DRMERR_BADOBJECT, "Test %u: Got unexpected hr %#x.\n", i, hr);
6361 hr = IDirect3DRMTexture2_InitFromFile(texture2, "");
6362 ok(hr == D3DRMERR_BADOBJECT, "Test %u: Got unexpected hr %#x.\n", i, hr);
6363 hr = IDirect3DRMTexture2_InitFromFile(texture2, filename);
6364 ok(SUCCEEDED(hr), "Test %u: Failed to initialise texture from file, hr %#x.\n", i, hr);
6365 d3drm_img = IDirect3DRMTexture2_GetImage(texture2);
6366 ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
6367 test_bitmap_data(i * 7 + 3, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
6368 IDirect3DRMTexture2_Release(texture2);
6370 hr = IDirect3DRM3_LoadTexture(d3drm3, filename, &texture3);
6371 ok(SUCCEEDED(hr), "Test %u: Failed to load texture, hr %#x.\n", i, hr);
6372 ref2 = get_refcount((IUnknown *)d3drm1);
6373 ok(ref2 > ref1, "Test %u: expected ref2 > ref1, got ref1 %u, ref2 %u.\n", i, ref1, ref2);
6375 hr = IDirect3DRMTexture3_InitFromFile(texture3, filename);
6376 ok(hr == D3DRMERR_BADOBJECT, "Test %u: Got unexpected hr %#x.\n", i, hr);
6377 IDirect3DRM_Release(d3drm1);
6378 d3drm_img = IDirect3DRMTexture3_GetImage(texture3);
6379 ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
6380 test_bitmap_data(i * 7 + 4, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
6381 /* Test whether querying a version 1 texture from version 3 causes a
6382 * change in the loading behavior. */
6383 hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)&texture1);
6384 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMTexture interface, hr %#x.\n", hr);
6385 d3drm_img = IDirect3DRMTexture_GetImage(texture1);
6386 ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
6387 test_bitmap_data(i * 7 + 5, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
6388 IDirect3DRMTexture_Release(texture1);
6389 IDirect3DRMTexture3_Release(texture3);
6390 ref2 = get_refcount((IUnknown *)d3drm1);
6391 ok(ref1 == ref2, "Test %u: expected ref1 == ref2, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
6393 hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMTexture,
6394 NULL, &IID_IDirect3DRMTexture3, (void **)&texture3);
6395 ok(SUCCEEDED(hr), "Test %u: Failed to create texture, hr %#x.\n", i, hr);
6396 hr = IDirect3DRMTexture3_InitFromFile(texture3, NULL);
6397 ok(hr == D3DRMERR_BADOBJECT, "Test %u: Got unexpected hr %#x.\n", i, hr);
6398 hr = IDirect3DRMTexture3_InitFromFile(texture3, "");
6399 ok(hr == D3DRMERR_BADOBJECT, "Test %u: Got unexpected hr %#x.\n", i, hr);
6400 hr = IDirect3DRMTexture3_InitFromFile(texture3, filename);
6401 ok(SUCCEEDED(hr), "Test %u: Failed to initialize texture from file, hr %#x.\n", i, hr);
6402 d3drm_img = IDirect3DRMTexture3_GetImage(texture3);
6403 ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
6404 test_bitmap_data(i * 7 + 6, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
6405 IDirect3DRMTexture3_Release(texture3);
6407 ret = DeleteFileA(filename);
6408 ok(ret, "Test %u: Failed to delete bitmap \"%s\".\n", i, filename);
6409 HeapFree(GetProcessHeap(), 0, filename);
6412 IDirect3DRM3_Release(d3drm3);
6413 IDirect3DRM2_Release(d3drm2);
6414 IDirect3DRM_Release(d3drm1);
6417 static void test_texture_qi(void)
6419 static const struct qi_test tests[] =
6421 { &IID_IDirect3DRM3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6422 { &IID_IDirect3DRM2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6423 { &IID_IDirect3DRM, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6424 { &IID_IDirect3DRMDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6425 { &IID_IDirect3DRMDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6426 { &IID_IDirect3DRMDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6427 { &IID_IDirect3DRMWinDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6428 { &IID_IDirect3DRMObject, &IID_IUnknown, &IID_IDirect3DRMTexture, S_OK },
6429 { &IID_IDirect3DRMViewport, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6430 { &IID_IDirect3DRMViewport2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6431 { &IID_IDirect3DRMFrame, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6432 { &IID_IDirect3DRMFrame2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6433 { &IID_IDirect3DRMFrame3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6434 { &IID_IDirect3DRMVisual, &IID_IUnknown, &IID_IDirect3DRMTexture, S_OK },
6435 { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6436 { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6437 { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6438 { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6439 { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6440 { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6441 { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6442 { &IID_IDirect3DRMTexture, &IID_IUnknown, &IID_IDirect3DRMTexture, S_OK },
6443 { &IID_IDirect3DRMTexture2, &IID_IUnknown, &IID_IDirect3DRMTexture2, S_OK },
6444 { &IID_IDirect3DRMTexture3, &IID_IUnknown, &IID_IDirect3DRMTexture3, S_OK },
6445 { &IID_IDirect3DRMWrap, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6446 { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6447 { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6448 { &IID_IDirect3DRMAnimation, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6449 { &IID_IDirect3DRMAnimation2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6450 { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6451 { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6452 { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6453 { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6454 { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6455 { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6456 { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6457 { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6458 { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6459 { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6460 { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6461 { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6462 { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6463 { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6464 { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6465 { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6466 { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6467 { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6468 { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6469 { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6470 { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6471 { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6472 { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6473 { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6474 { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6475 { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6476 { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6477 { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6478 { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6479 { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6480 { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6481 { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6482 { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6483 { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6484 { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6485 { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6486 { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6487 { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6488 { &IID_IUnknown, &IID_IUnknown, NULL, S_OK, },
6490 HRESULT hr;
6491 IDirect3DRM *d3drm1;
6492 IDirect3DRM2 *d3drm2;
6493 IDirect3DRM3 *d3drm3;
6494 IDirect3DRMTexture *texture1;
6495 IDirect3DRMTexture2 *texture2;
6496 IDirect3DRMTexture3 *texture3;
6497 IUnknown *unknown;
6498 char *filename;
6499 BOOL check;
6501 hr = Direct3DRMCreate(&d3drm1);
6502 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface (hr = %#x)\n", hr);
6503 filename = create_bitmap(1, 1, TRUE);
6504 hr = IDirect3DRM_LoadTexture(d3drm1, filename, &texture1);
6505 ok(SUCCEEDED(hr), "Failed to load texture (hr = %#x).\n", hr);
6506 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture interface (hr = %#x)\n", hr);
6507 hr = IDirect3DRMTexture_QueryInterface(texture1, &IID_IUnknown, (void **)&unknown);
6508 ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMTexture (hr = %#x)\n", hr);
6509 IDirect3DRMTexture_Release(texture1);
6510 test_qi("texture1_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
6511 IUnknown_Release(unknown);
6513 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
6514 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface (hr = %#x).\n", hr);
6515 hr = IDirect3DRM2_LoadTexture(d3drm2, filename, &texture2);
6516 ok(SUCCEEDED(hr), "Failed to load texture (hr = %#x).\n", hr);
6517 hr = IDirect3DRMTexture2_QueryInterface(texture2, &IID_IUnknown, (void **)&unknown);
6518 ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMTexture2 (hr = %#x)\n", hr);
6519 IDirect3DRMTexture2_Release(texture2);
6520 test_qi("texture2_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
6521 IUnknown_Release(unknown);
6523 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
6524 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface (hr = %#x).\n", hr);
6525 hr = IDirect3DRM3_LoadTexture(d3drm3, filename, &texture3);
6526 ok(SUCCEEDED(hr), "Failed to load texture (hr = %#x).\n", hr);
6527 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface (hr = %#x)\n", hr);
6528 hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IUnknown, (void **)&unknown);
6529 ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMTexture3 (hr = %#x)\n", hr);
6530 IDirect3DRMTexture3_Release(texture3);
6531 test_qi("texture3_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
6532 IUnknown_Release(unknown);
6534 IDirect3DRM3_Release(d3drm3);
6535 IDirect3DRM2_Release(d3drm2);
6536 IDirect3DRM_Release(d3drm1);
6537 check = DeleteFileA(filename);
6538 ok(check, "Cannot delete image stored in %s (error = %d).\n", filename, GetLastError());
6539 HeapFree(GetProcessHeap(), 0, filename);
6542 static void test_viewport_qi(void)
6544 IDirect3DRM *d3drm1;
6545 IDirect3DRM2 *d3drm2;
6546 IDirect3DRM3 *d3drm3;
6547 IDirect3DRMFrame *frame1, *camera1;
6548 IDirect3DRMFrame3 *frame3, *camera3;
6549 IDirect3DRMDevice *device1;
6550 IDirect3DRMDevice3 *device3;
6551 IDirectDrawClipper *clipper;
6552 IDirect3DRMViewport *viewport1;
6553 IDirect3DRMViewport2 *viewport2;
6554 IUnknown *unknown;
6555 GUID driver = IID_IDirect3DRGBDevice;
6556 HRESULT hr;
6558 static const struct qi_test tests[] =
6560 { &IID_IDirect3DRM3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6561 { &IID_IDirect3DRM2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6562 { &IID_IDirect3DRM, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6563 { &IID_IDirect3DRMDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6564 { &IID_IDirect3DRMDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6565 { &IID_IDirect3DRMDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6566 { &IID_IDirect3DRMWinDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6567 { &IID_IDirect3DRMObject, &IID_IUnknown, &IID_IDirect3DRMViewport, S_OK },
6568 { &IID_IDirect3DRMViewport, &IID_IUnknown, &IID_IDirect3DRMViewport, S_OK },
6569 { &IID_IDirect3DRMViewport2, &IID_IUnknown, &IID_IDirect3DRMViewport2, S_OK },
6570 { &IID_IDirect3DRMFrame, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6571 { &IID_IDirect3DRMFrame2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6572 { &IID_IDirect3DRMFrame3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6573 { &IID_IDirect3DRMVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6574 { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6575 { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6576 { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6577 { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6578 { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6579 { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6580 { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6581 { &IID_IDirect3DRMTexture, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6582 { &IID_IDirect3DRMTexture2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6583 { &IID_IDirect3DRMTexture3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6584 { &IID_IDirect3DRMWrap, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6585 { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6586 { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6587 { &IID_IDirect3DRMAnimation, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6588 { &IID_IDirect3DRMAnimation2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6589 { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6590 { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6591 { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6592 { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6593 { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6594 { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6595 { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6596 { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6597 { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6598 { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6599 { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6600 { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6601 { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6602 { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6603 { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6604 { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6605 { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6606 { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6607 { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6608 { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6609 { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6610 { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6611 { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6612 { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6613 { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6614 { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6615 { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6616 { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6617 { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6618 { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6619 { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6620 { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6621 { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6622 { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6623 { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6624 { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6625 { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6626 { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6627 { &IID_IUnknown, &IID_IUnknown, NULL, S_OK, },
6630 hr = DirectDrawCreateClipper(0, &clipper, NULL);
6631 ok(SUCCEEDED(hr), "Cannot get IDirectDrawClipper interface (hr = %#x).\n", hr);
6633 hr = Direct3DRMCreate(&d3drm1);
6634 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface (hr = %#x).\n", hr);
6636 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, 640, 480, &device1);
6637 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface (hr = %#x).\n", hr);
6638 hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &frame1);
6639 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame interface (hr = %#x)\n", hr);
6640 hr = IDirect3DRM_CreateFrame(d3drm1, frame1, &camera1);
6641 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame interface (hr = %#x)\n", hr);
6642 hr = IDirect3DRM_CreateViewport(d3drm1, device1, camera1, 0, 0, 640, 480, &viewport1);
6643 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport interface (hr = %#x)\n", hr);
6644 hr = IDirect3DRMViewport_QueryInterface(viewport1, &IID_IUnknown, (void **)&unknown);
6645 ok(SUCCEEDED(hr), "Cannot get IUnknown interface (hr = %#x).\n", hr);
6646 IDirect3DRMViewport_Release(viewport1);
6647 test_qi("viewport1_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
6648 IUnknown_Release(unknown);
6650 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
6651 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface (hr = %#x).\n", hr);
6652 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, camera1, 0, 0, 640, 480, &viewport1);
6653 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport interface (hr = %#x)\n", hr);
6654 hr = IDirect3DRMViewport_QueryInterface(viewport1, &IID_IUnknown, (void **)&unknown);
6655 ok(SUCCEEDED(hr), "Cannot get IUnknown interface (hr = %#x).\n", hr);
6656 IDirect3DRMViewport_Release(viewport1);
6657 test_qi("viewport1_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
6658 IUnknown_Release(unknown);
6659 IDirect3DRMDevice_Release(device1);
6660 IDirect3DRMFrame_Release(camera1);
6661 IDirect3DRMFrame_Release(frame1);
6663 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
6664 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface (hr = %#x).\n", hr);
6665 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, 640, 480, &device3);
6666 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface (hr = %#x).\n", hr);
6667 hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &frame3);
6668 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame3 interface (hr = %#x)\n", hr);
6669 hr = IDirect3DRM3_CreateFrame(d3drm3, frame3, &camera3);
6670 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame3 interface (hr = %#x)\n", hr);
6671 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, camera3, 0, 0, 640, 480, &viewport2);
6672 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport2 interface (hr = %#x)\n", hr);
6673 hr = IDirect3DRMViewport2_QueryInterface(viewport2, &IID_IUnknown, (void **)&unknown);
6674 ok(SUCCEEDED(hr), "Cannot get IUnknown interface (hr = %#x).\n", hr);
6675 IDirect3DRMViewport_Release(viewport2);
6676 test_qi("viewport2_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
6677 IUnknown_Release(unknown);
6678 IDirect3DRMDevice3_Release(device3);
6679 IDirect3DRMFrame3_Release(camera3);
6680 IDirect3DRMFrame3_Release(frame3);
6682 IDirectDrawClipper_Release(clipper);
6683 IDirect3DRM3_Release(d3drm3);
6684 IDirect3DRM2_Release(d3drm2);
6685 IDirect3DRM_Release(d3drm1);
6688 static D3DCOLOR get_surface_color(IDirectDrawSurface *surface, UINT x, UINT y)
6690 RECT rect = { x, y, x + 1, y + 1 };
6691 DDSURFACEDESC surface_desc;
6692 D3DCOLOR color;
6693 HRESULT hr;
6695 memset(&surface_desc, 0, sizeof(surface_desc));
6696 surface_desc.dwSize = sizeof(surface_desc);
6698 hr = IDirectDrawSurface_Lock(surface, &rect, &surface_desc, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
6699 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
6700 if (FAILED(hr))
6701 return 0xdeadbeef;
6703 color = *((DWORD *)surface_desc.lpSurface) & 0x00ffffff;
6705 hr = IDirectDrawSurface_Unlock(surface, NULL);
6706 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
6708 return color;
6711 static IDirect3DDevice2 *create_device2_without_ds(IDirectDraw2 *ddraw, HWND window)
6713 IDirectDrawSurface *surface;
6714 IDirect3DDevice2 *device = NULL;
6715 DDSURFACEDESC surface_desc;
6716 IDirect3D2 *d3d;
6717 HRESULT hr;
6718 RECT rc;
6720 GetClientRect(window, &rc);
6721 hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
6722 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
6724 memset(&surface_desc, 0, sizeof(surface_desc));
6725 surface_desc.dwSize = sizeof(surface_desc);
6726 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
6727 surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
6728 surface_desc.dwWidth = rc.right;
6729 surface_desc.dwHeight = rc.bottom;
6731 hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface, NULL);
6732 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
6734 hr = IDirectDraw2_QueryInterface(ddraw, &IID_IDirect3D2, (void **)&d3d);
6735 if (FAILED(hr))
6737 IDirectDrawSurface_Release(surface);
6738 return NULL;
6741 IDirect3D2_CreateDevice(d3d, &IID_IDirect3DHALDevice, surface, &device);
6743 IDirect3D2_Release(d3d);
6744 IDirectDrawSurface_Release(surface);
6745 return device;
6748 static void clear_depth_surface(IDirectDrawSurface *surface, DWORD value)
6750 HRESULT hr;
6751 DDBLTFX fx;
6753 memset(&fx, 0, sizeof(fx));
6754 fx.dwSize = sizeof(fx);
6755 U5(fx).dwFillDepth = value;
6757 hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_DEPTHFILL | DDBLT_WAIT, &fx);
6758 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
6761 static void set_execute_data(IDirect3DExecuteBuffer *execute_buffer, UINT vertex_count, UINT offset, UINT len)
6763 D3DEXECUTEDATA exec_data;
6764 HRESULT hr;
6766 memset(&exec_data, 0, sizeof(exec_data));
6767 exec_data.dwSize = sizeof(exec_data);
6768 exec_data.dwVertexCount = vertex_count;
6769 exec_data.dwInstructionOffset = offset;
6770 exec_data.dwInstructionLength = len;
6771 hr = IDirect3DExecuteBuffer_SetExecuteData(execute_buffer, &exec_data);
6772 ok(SUCCEEDED(hr), "Failed to set execute data, hr %#x.\n", hr);
6775 static void emit_set_ts(void **ptr, D3DTRANSFORMSTATETYPE state, DWORD value)
6777 D3DINSTRUCTION *inst = *ptr;
6778 D3DSTATE *ts = (D3DSTATE *)(inst + 1);
6780 inst->bOpcode = D3DOP_STATETRANSFORM;
6781 inst->bSize = sizeof(*ts);
6782 inst->wCount = 1;
6784 U1(*ts).dtstTransformStateType = state;
6785 U2(*ts).dwArg[0] = value;
6787 *ptr = ts + 1;
6790 static void emit_set_rs(void **ptr, D3DRENDERSTATETYPE state, DWORD value)
6792 D3DINSTRUCTION *inst = *ptr;
6793 D3DSTATE *rs = (D3DSTATE *)(inst + 1);
6795 inst->bOpcode = D3DOP_STATERENDER;
6796 inst->bSize = sizeof(*rs);
6797 inst->wCount = 1;
6799 U1(*rs).drstRenderStateType = state;
6800 U2(*rs).dwArg[0] = value;
6802 *ptr = rs + 1;
6805 static void emit_process_vertices(void **ptr, DWORD flags, WORD base_idx, DWORD vertex_count)
6807 D3DINSTRUCTION *inst = *ptr;
6808 D3DPROCESSVERTICES *pv = (D3DPROCESSVERTICES *)(inst + 1);
6810 inst->bOpcode = D3DOP_PROCESSVERTICES;
6811 inst->bSize = sizeof(*pv);
6812 inst->wCount = 1;
6814 pv->dwFlags = flags;
6815 pv->wStart = base_idx;
6816 pv->wDest = 0;
6817 pv->dwCount = vertex_count;
6818 pv->dwReserved = 0;
6820 *ptr = pv + 1;
6823 static void emit_tquad(void **ptr, WORD base_idx)
6825 D3DINSTRUCTION *inst = *ptr;
6826 D3DTRIANGLE *tri = (D3DTRIANGLE *)(inst + 1);
6828 inst->bOpcode = D3DOP_TRIANGLE;
6829 inst->bSize = sizeof(*tri);
6830 inst->wCount = 2;
6832 U1(*tri).v1 = base_idx;
6833 U2(*tri).v2 = base_idx + 1;
6834 U3(*tri).v3 = base_idx + 2;
6835 tri->wFlags = D3DTRIFLAG_START;
6836 ++tri;
6838 U1(*tri).v1 = base_idx + 2;
6839 U2(*tri).v2 = base_idx + 1;
6840 U3(*tri).v3 = base_idx + 3;
6841 tri->wFlags = D3DTRIFLAG_ODD;
6842 ++tri;
6844 *ptr = tri;
6847 static void emit_end(void **ptr)
6849 D3DINSTRUCTION *inst = *ptr;
6851 inst->bOpcode = D3DOP_EXIT;
6852 inst->bSize = 0;
6853 inst->wCount = 0;
6855 *ptr = inst + 1;
6858 static void d3d_draw_quad1(IDirect3DDevice *device, IDirect3DViewport *viewport)
6860 IDirect3DExecuteBuffer *execute_buffer;
6861 D3DEXECUTEBUFFERDESC exec_desc;
6862 HRESULT hr;
6863 void *ptr;
6864 UINT inst_length;
6865 D3DMATRIXHANDLE world_handle, view_handle, proj_handle;
6866 static D3DMATRIX mat =
6868 1.0f, 0.0f, 0.0f, 0.0f,
6869 0.0f, 1.0f, 0.0f, 0.0f,
6870 0.0f, 0.0f, 1.0f, 0.0f,
6871 0.0f, 0.0f, 0.0f, 1.0f,
6873 static const D3DLVERTEX quad_strip[] =
6875 {{-1.0f}, {-1.0f}, {0.00f}, 0, {0xffbada55}, {0}, {0.0f}, {0.0f}},
6876 {{-1.0f}, { 1.0f}, {0.00f}, 0, {0xffbada55}, {0}, {0.0f}, {0.0f}},
6877 {{ 1.0f}, {-1.0f}, {1.00f}, 0, {0xffbada55}, {0}, {0.0f}, {0.0f}},
6878 {{ 1.0f}, { 1.0f}, {1.00f}, 0, {0xffbada55}, {0}, {0.0f}, {0.0f}},
6881 hr = IDirect3DDevice_CreateMatrix(device, &world_handle);
6882 ok(hr == D3D_OK, "Creating a matrix object failed, hr %#x.\n", hr);
6883 hr = IDirect3DDevice_SetMatrix(device, world_handle, &mat);
6884 ok(hr == D3D_OK, "Setting a matrix object failed, hr %#x.\n", hr);
6885 hr = IDirect3DDevice_CreateMatrix(device, &view_handle);
6886 ok(hr == D3D_OK, "Creating a matrix object failed, hr %#x.\n", hr);
6887 hr = IDirect3DDevice_SetMatrix(device, view_handle, &mat);
6888 ok(hr == D3D_OK, "Setting a matrix object failed, hr %#x.\n", hr);
6889 hr = IDirect3DDevice_CreateMatrix(device, &proj_handle);
6890 ok(hr == D3D_OK, "Creating a matrix object failed, hr %#x.\n", hr);
6891 hr = IDirect3DDevice_SetMatrix(device, proj_handle, &mat);
6892 ok(hr == D3D_OK, "Setting a matrix object failed, hr %#x.\n", hr);
6894 memset(&exec_desc, 0, sizeof(exec_desc));
6895 exec_desc.dwSize = sizeof(exec_desc);
6896 exec_desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
6897 exec_desc.dwBufferSize = 1024;
6898 exec_desc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY;
6900 hr = IDirect3DDevice_CreateExecuteBuffer(device, &exec_desc, &execute_buffer, NULL);
6901 ok(SUCCEEDED(hr), "Failed to create execute buffer, hr %#x.\n", hr);
6903 hr = IDirect3DExecuteBuffer_Lock(execute_buffer, &exec_desc);
6904 ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#x.\n", hr);
6906 memcpy(exec_desc.lpData, quad_strip, sizeof(quad_strip));
6907 ptr = ((BYTE *)exec_desc.lpData) + sizeof(quad_strip);
6908 emit_set_ts(&ptr, D3DTRANSFORMSTATE_WORLD, world_handle);
6909 emit_set_ts(&ptr, D3DTRANSFORMSTATE_VIEW, view_handle);
6910 emit_set_ts(&ptr, D3DTRANSFORMSTATE_PROJECTION, proj_handle);
6911 emit_set_rs(&ptr, D3DRENDERSTATE_CLIPPING, FALSE);
6912 emit_set_rs(&ptr, D3DRENDERSTATE_ZENABLE, TRUE);
6913 emit_set_rs(&ptr, D3DRENDERSTATE_FOGENABLE, FALSE);
6914 emit_set_rs(&ptr, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
6915 emit_set_rs(&ptr, D3DRENDERSTATE_SHADEMODE, D3DSHADE_FLAT);
6917 emit_process_vertices(&ptr, D3DPROCESSVERTICES_TRANSFORM, 0, 4);
6918 emit_tquad(&ptr, 0);
6920 emit_end(&ptr);
6921 inst_length = (BYTE *)ptr - (BYTE *)exec_desc.lpData;
6922 inst_length -= sizeof(quad_strip);
6924 hr = IDirect3DExecuteBuffer_Unlock(execute_buffer);
6925 ok(SUCCEEDED(hr), "Failed to unlock execute buffer, hr %#x.\n", hr);
6927 hr = IDirect3DDevice_BeginScene(device);
6928 set_execute_data(execute_buffer, 4, sizeof(quad_strip), inst_length);
6929 hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED);
6930 ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#x.\n", hr);
6931 hr = IDirect3DDevice_EndScene(device);
6932 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6934 IDirect3DExecuteBuffer_Release(execute_buffer);
6937 static void test_viewport_clear1(void)
6939 DDSCAPS caps = { DDSCAPS_ZBUFFER };
6940 IDirectDraw *ddraw;
6941 IDirectDrawClipper *clipper;
6942 IDirect3DRM *d3drm1;
6943 IDirect3DRMFrame *frame1, *camera1;
6944 IDirect3DRMDevice *device1;
6945 IDirect3DViewport *d3d_viewport;
6946 IDirect3DRMViewport *viewport1;
6947 IDirect3DDevice *d3d_device1;
6948 IDirectDrawSurface *surface, *ds, *d3drm_ds;
6949 HWND window;
6950 GUID driver = IID_IDirect3DRGBDevice;
6951 HRESULT hr;
6952 D3DCOLOR ret_color;
6953 RECT rc;
6955 window = create_window();
6956 GetClientRect(window, &rc);
6958 hr = DirectDrawCreate(NULL, &ddraw, NULL);
6959 ok(SUCCEEDED(hr), "Cannot create IDirectDraw interface (hr = %#x).\n", hr);
6961 hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
6962 ok(SUCCEEDED(hr), "Failed to set cooperative level (hr = %#x).\n", hr);
6964 hr = IDirectDraw_CreateClipper(ddraw, 0, &clipper, NULL);
6965 ok(SUCCEEDED(hr), "Cannot create clipper (hr = %#x).\n", hr);
6967 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
6968 ok(SUCCEEDED(hr), "Cannot set HWnd to Clipper (hr = %#x)\n", hr);
6970 hr = Direct3DRMCreate(&d3drm1);
6971 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface (hr = %#x).\n", hr);
6973 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, rc.right, rc.bottom, &device1);
6974 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMDevice interface (hr = %#x)\n", hr);
6976 hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &frame1);
6977 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame interface (hr = %#x)\n", hr);
6978 hr = IDirect3DRM_CreateFrame(d3drm1, frame1, &camera1);
6979 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame interface (hr = %#x)\n", hr);
6981 hr = IDirect3DRM_CreateViewport(d3drm1, device1, camera1, 0, 0, rc.right,
6982 rc.bottom, &viewport1);
6983 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport2 interface (hr = %#x)\n", hr);
6985 /* Fetch immediate mode device and viewport */
6986 hr = IDirect3DRMDevice_GetDirect3DDevice(device1, &d3d_device1);
6987 ok(SUCCEEDED(hr), "Cannot get IDirect3DDevice interface (hr = %#x).\n", hr);
6988 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport1, &d3d_viewport);
6989 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
6991 hr = IDirect3DDevice_QueryInterface(d3d_device1, &IID_IDirectDrawSurface, (void **)&surface);
6992 ok(SUCCEEDED(hr), "Cannot get surface to the render target (hr = %#x).\n", hr);
6994 ret_color = get_surface_color(surface, 320, 240);
6995 ok(compare_color(ret_color, 0, 1), "Got unexpected color 0x%08x.\n", ret_color);
6997 /* Clear uses the scene frame's background color. */
6998 hr = IDirect3DRMFrame_SetSceneBackgroundRGB(frame1, 1.0f, 1.0f, 1.0f);
6999 ok(SUCCEEDED(hr), "Cannot set scene background RGB (hr = %#x)\n", hr);
7000 ret_color = IDirect3DRMFrame_GetSceneBackground(frame1);
7001 ok(ret_color == 0xffffffff, "Expected scene color returned == 0xffffffff, got %#x.\n", ret_color);
7002 hr = IDirect3DRMFrame_SetSceneBackgroundRGB(camera1, 0.0f, 1.0f, 0.0f);
7003 ok(SUCCEEDED(hr), "Cannot set scene background RGB (hr = %#x)\n", hr);
7004 ret_color = IDirect3DRMFrame_GetSceneBackground(camera1);
7005 ok(ret_color == 0xff00ff00, "Expected scene color returned == 0xff00ff00, got %#x.\n", ret_color);
7007 CHECK_REFCOUNT(frame1, 1);
7008 hr = IDirect3DRMViewport_Clear(viewport1);
7009 ok(SUCCEEDED(hr), "Cannot clear viewport (hr = %#x).\n", hr);
7010 ret_color = get_surface_color(surface, 320, 240);
7011 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", ret_color);
7012 CHECK_REFCOUNT(frame1, 1);
7014 hr = IDirect3DRMFrame_SetSceneBackgroundRGB(frame1, 0.0f, 0.0f, 1.0f);
7015 ok(SUCCEEDED(hr), "Cannot set scene background RGB (hr = %#x)\n", hr);
7016 ret_color = IDirect3DRMFrame_GetSceneBackground(frame1);
7017 ok(ret_color == 0xff0000ff, "Expected scene color returned == 0xff00ff00, got %#x.\n", ret_color);
7019 hr = IDirect3DRMViewport_Configure(viewport1, 0, 0, rc.right, rc.bottom);
7020 todo_wine ok(SUCCEEDED(hr), "Cannot configure viewport (hr = %#x).\n", hr);
7021 hr = IDirect3DRMViewport_Clear(viewport1);
7022 ok(SUCCEEDED(hr), "Cannot clear viewport (hr = %#x).\n", hr);
7023 ret_color = get_surface_color(surface, 100, 200);
7024 ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", ret_color);
7026 d3d_draw_quad1(d3d_device1, d3d_viewport);
7028 ret_color = get_surface_color(surface, 100, 200);
7029 ok(compare_color(ret_color, 0x00bada55, 1), "Got unexpected color 0x%08x.\n", ret_color);
7031 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
7032 ok(SUCCEEDED(hr), "Cannot get attached depth surface (hr = %x).\n", hr);
7034 hr = IDirect3DRMViewport_Configure(viewport1, 0, 0, rc.right, rc.bottom);
7035 todo_wine ok(SUCCEEDED(hr), "Cannot configure viewport (hr = %#x).\n", hr);
7036 hr = IDirect3DRMViewport_Clear(viewport1);
7037 ok(SUCCEEDED(hr), "Cannot clear viewport (hr = %#x).\n", hr);
7038 ret_color = get_surface_color(surface, 100, 200);
7039 ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", ret_color);
7041 /* Fill the depth surface with a value lower than the quad's depth value. */
7042 clear_depth_surface(ds, 0x7fff);
7044 /* Depth test passes here */
7045 d3d_draw_quad1(d3d_device1, d3d_viewport);
7046 ret_color = get_surface_color(surface, 100, 200);
7047 ok(compare_color(ret_color, 0x00bada55, 1), "Got unexpected color 0x%08x.\n", ret_color);
7048 /* Depth test fails here */
7049 ret_color = get_surface_color(surface, 500, 400);
7050 ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", ret_color);
7052 /* Check what happens if we release the depth surface that d3drm created, and clear the viewport */
7053 hr = IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds);
7054 ok(SUCCEEDED(hr), "Cannot delete attached surface (hr = %#x).\n", hr);
7055 d3drm_ds = (IDirectDrawSurface *)0xdeadbeef;
7056 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
7057 ok(hr == DDERR_NOTFOUND, "Expected hr == DDERR_NOTFOUND, got %#x.\n", hr);
7058 ok(d3drm_ds == NULL, "Expected NULL z-surface, got %p.\n", d3drm_ds);
7060 clear_depth_surface(ds, 0x7fff);
7061 hr = IDirect3DRMViewport_Configure(viewport1, 0, 0, rc.right, rc.bottom);
7062 todo_wine ok(SUCCEEDED(hr), "Cannot configure viewport (hr = %#x).\n", hr);
7063 hr = IDirect3DRMViewport_Clear(viewport1);
7064 ok(SUCCEEDED(hr), "Cannot clear viewport (hr = %#x).\n", hr);
7066 ret_color = get_surface_color(surface, 100, 200);
7067 ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", ret_color);
7069 hr = IDirectDrawSurface_AddAttachedSurface(surface, ds);
7070 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#x.\n", hr);
7071 IDirectDrawSurface_Release(ds);
7073 d3d_draw_quad1(d3d_device1, d3d_viewport);
7075 ret_color = get_surface_color(surface, 100, 200);
7076 ok(compare_color(ret_color, 0x00bada55, 1), "Got unexpected color 0x%08x.\n", ret_color);
7077 ret_color = get_surface_color(surface, 500, 400);
7078 ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", ret_color);
7080 IDirect3DViewport_Release(d3d_viewport);
7081 IDirectDrawSurface_Release(surface);
7082 IDirect3DDevice_Release(d3d_device1);
7083 IDirect3DRMViewport_Release(viewport1);
7084 IDirect3DRMFrame_Release(frame1);
7085 IDirect3DRMFrame_Release(camera1);
7086 IDirect3DRMDevice_Release(device1);
7087 IDirect3DRM_Release(d3drm1);
7088 IDirectDrawClipper_Release(clipper);
7089 IDirectDraw_Release(ddraw);
7090 DestroyWindow(window);
7093 static void draw_quad2(IDirect3DDevice2 *device, IDirect3DViewport *viewport)
7095 static D3DLVERTEX tquad[] =
7097 {{-1.0f}, {-1.0f}, {0.0f}, 0, {0xffbada55}, {0}, {0.0f}, {0.0f}},
7098 {{-1.0f}, { 1.0f}, {0.0f}, 0, {0xffbada55}, {0}, {0.0f}, {1.0f}},
7099 {{ 1.0f}, {-1.0f}, {1.0f}, 0, {0xffbada55}, {0}, {1.0f}, {0.0f}},
7100 {{ 1.0f}, { 1.0f}, {1.0f}, 0, {0xffbada55}, {0}, {1.0f}, {1.0f}},
7102 static D3DMATRIX mat =
7104 1.0f, 0.0f, 0.0f, 0.0f,
7105 0.0f, 1.0f, 0.0f, 0.0f,
7106 0.0f, 0.0f, 1.0f, 0.0f,
7107 0.0f, 0.0f, 0.0f, 1.0f,
7109 IDirect3DViewport2 *viewport2;
7110 HRESULT hr;
7112 hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &mat);
7113 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
7114 hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_VIEW, &mat);
7115 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
7116 hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, &mat);
7117 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
7119 hr = IDirect3DViewport_QueryInterface(viewport, &IID_IDirect3DViewport2, (void **)&viewport2);
7120 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport2 interface (hr = %#x).\n", hr);
7121 hr = IDirect3DDevice2_SetCurrentViewport(device, viewport2);
7122 ok(SUCCEEDED(hr), "Failed to activate the viewport, hr %#x.\n", hr);
7123 IDirect3DViewport2_Release(viewport2);
7125 hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_ZENABLE, D3DZB_TRUE);
7126 ok(SUCCEEDED(hr), "Failed to enable z testing, hr %#x.\n", hr);
7127 hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
7128 ok(SUCCEEDED(hr), "Failed to set the z function, hr %#x.\n", hr);
7130 hr = IDirect3DDevice2_BeginScene(device);
7131 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7132 hr = IDirect3DDevice2_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DVT_LVERTEX, tquad, 4, 0);
7133 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7134 hr = IDirect3DDevice2_EndScene(device);
7135 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7138 static void test_viewport_clear2(void)
7140 DDSCAPS caps = { DDSCAPS_ZBUFFER };
7141 IDirect3D2 *d3d2;
7142 IDirectDraw *ddraw1;
7143 IDirectDraw2 *ddraw2;
7144 IDirectDrawClipper *clipper;
7145 IDirect3DRM *d3drm1;
7146 IDirect3DRM3 *d3drm3;
7147 IDirect3DRMFrame3 *frame3, *camera3;
7148 IDirect3DRMDevice3 *device3;
7149 IDirect3DViewport *d3d_viewport;
7150 IDirect3DRMViewport2 *viewport2;
7151 IDirect3DDevice2 *d3d_device2;
7152 IDirectDrawSurface *surface, *ds, *d3drm_ds;
7153 HWND window;
7154 GUID driver = IID_IDirect3DRGBDevice;
7155 HRESULT hr;
7156 D3DCOLOR ret_color;
7157 RECT rc;
7159 window = create_window();
7160 GetClientRect(window, &rc);
7162 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
7163 ok(SUCCEEDED(hr), "Cannot create IDirectDraw interface (hr = %#x).\n", hr);
7165 hr = IDirectDraw_SetCooperativeLevel(ddraw1, window, DDSCL_NORMAL);
7166 ok(SUCCEEDED(hr), "Failed to set cooperative level (hr = %#x).\n", hr);
7168 hr = IDirectDraw_CreateClipper(ddraw1, 0, &clipper, NULL);
7169 ok(SUCCEEDED(hr), "Cannot create clipper (hr = %#x).\n", hr);
7171 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
7172 ok(SUCCEEDED(hr), "Cannot set HWnd to Clipper (hr = %#x)\n", hr);
7174 hr = Direct3DRMCreate(&d3drm1);
7175 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface (hr = %#x).\n", hr);
7177 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
7178 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface (hr = %#x).\n", hr);
7180 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, rc.right, rc.bottom, &device3);
7181 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMDevice3 interface (hr = %#x)\n", hr);
7183 hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &frame3);
7184 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame3 interface (hr = %#x)\n", hr);
7185 hr = IDirect3DRM3_CreateFrame(d3drm3, frame3, &camera3);
7186 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame3 interface (hr = %#x)\n", hr);
7188 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, camera3, 0, 0, rc.right,
7189 rc.bottom, &viewport2);
7190 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport2 interface (hr = %#x)\n", hr);
7192 /* Fetch immediate mode device in order to access render target and test its color. */
7193 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3d_device2);
7194 ok(SUCCEEDED(hr), "Cannot get IDirect3DDevice2 interface (hr = %#x).\n", hr);
7196 hr = IDirect3DDevice2_GetRenderTarget(d3d_device2, &surface);
7197 ok(SUCCEEDED(hr), "Cannot get surface to the render target (hr = %#x).\n", hr);
7199 ret_color = get_surface_color(surface, 320, 240);
7200 ok(compare_color(ret_color, 0, 1), "Got unexpected color 0x%08x.\n", ret_color);
7202 /* Clear uses the scene frame's background color. */
7203 hr = IDirect3DRMFrame3_SetSceneBackgroundRGB(frame3, 1.0f, 1.0f, 1.0f);
7204 ok(SUCCEEDED(hr), "Cannot set scene background RGB (hr = %#x)\n", hr);
7205 ret_color = IDirect3DRMFrame3_GetSceneBackground(frame3);
7206 ok(ret_color == 0xffffffff, "Expected scene color returned == 0xffffffff, got %#x.\n", ret_color);
7207 hr = IDirect3DRMFrame3_SetSceneBackgroundRGB(camera3, 0.0f, 1.0f, 0.0f);
7208 ok(SUCCEEDED(hr), "Cannot set scene background RGB (hr = %#x)\n", hr);
7209 ret_color = IDirect3DRMFrame3_GetSceneBackground(camera3);
7210 ok(ret_color == 0xff00ff00, "Expected scene color returned == 0xff00ff00, got %#x.\n", ret_color);
7212 CHECK_REFCOUNT(frame3, 1);
7213 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL);
7214 ok(SUCCEEDED(hr), "Cannot clear viewport (hr = %#x).\n", hr);
7215 ret_color = get_surface_color(surface, 320, 240);
7216 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", ret_color);
7217 CHECK_REFCOUNT(frame3, 1);
7219 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
7220 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr);
7222 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL);
7223 ok(SUCCEEDED(hr), "Cannot clear viewport (hr = %#x).\n", hr);
7225 /* d3drm seems to be calling BeginScene when Clear is called. */
7226 hr = IDirect3DDevice2_BeginScene(d3d_device2);
7227 todo_wine ok(hr == D3DERR_SCENE_IN_SCENE, "Expected hr == D3DERR_SCENE_IN_SCENE, got %#x.\n", hr);
7228 hr = IDirect3DDevice2_EndScene(d3d_device2);
7229 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7231 ret_color = get_surface_color(surface, 320, 240);
7232 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", ret_color);
7234 /* We're using d3d to draw using IDirect3DDevice2 created from d3drm. */
7235 draw_quad2(d3d_device2, d3d_viewport);
7236 ret_color = get_surface_color(surface, 320, 240);
7237 ok(compare_color(ret_color, 0x00bada55, 1), "Got unexpected color 0x%08x.\n", ret_color);
7239 /* Without calling Configure, Clear doesn't work. */
7240 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL);
7241 ok(SUCCEEDED(hr), "Cannot clear viewport (hr = %#x).\n", hr);
7242 ret_color = get_surface_color(surface, 320, 240);
7243 todo_wine ok(compare_color(ret_color, 0x00bada55, 1), "Got unexpected color 0x%08x.\n", ret_color);
7245 hr = IDirect3DRMViewport2_Configure(viewport2, 0, 0, rc.right, rc.bottom);
7246 todo_wine ok(SUCCEEDED(hr), "Cannot configure viewport (hr = %#x).\n", hr);
7247 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL);
7248 ok(SUCCEEDED(hr), "Cannot clear viewport (hr = %#x).\n", hr);
7250 ret_color = get_surface_color(surface, 320, 240);
7251 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", ret_color);
7253 /* Fetch attached depth surface and see if viewport clears it if it's detached from the render target. */
7254 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
7255 ok(SUCCEEDED(hr), "Cannot get attached depth surface (hr = %x).\n", hr);
7257 clear_depth_surface(ds, 0x39);
7258 draw_quad2(d3d_device2, d3d_viewport);
7260 ret_color = get_surface_color(surface, 320, 240);
7261 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", ret_color);
7263 hr = IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds);
7264 ok(SUCCEEDED(hr), "Cannot delete attached surface (hr = %#x).\n", hr);
7265 d3drm_ds = (IDirectDrawSurface *)0xdeadbeef;
7266 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
7267 ok(hr == DDERR_NOTFOUND, "Expected hr == DDERR_NOTFOUND, got %#x.\n", hr);
7268 ok(d3drm_ds == NULL, "Expected NULL z-surface, got %p.\n", d3drm_ds);
7270 clear_depth_surface(ds, 0x7fff);
7272 /* This version of Clear still clears the depth surface even if it's deleted from the render target. */
7273 hr = IDirect3DRMViewport2_Configure(viewport2, 0, 0, rc.right, rc.bottom);
7274 todo_wine ok(SUCCEEDED(hr), "Cannot configure viewport (hr = %#x).\n", hr);
7275 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL);
7276 ok(SUCCEEDED(hr), "Cannot clear viewport (hr = %#x).\n", hr);
7278 hr = IDirectDrawSurface_AddAttachedSurface(surface, ds);
7279 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#x.\n", hr);
7280 ret_color = get_surface_color(surface, 320, 240);
7281 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", ret_color);
7283 draw_quad2(d3d_device2, d3d_viewport);
7284 ret_color = get_surface_color(surface, 100, 200);
7285 ok(compare_color(ret_color, 0x00bada55, 1), "Got unexpected color 0x%08x.\n", ret_color);
7286 ret_color = get_surface_color(surface, 500, 400);
7287 todo_wine ok(compare_color(ret_color, 0x00bada55, 1), "Got unexpected color 0x%08x.\n", ret_color);
7289 /* Clear with no flags */
7290 hr = IDirect3DRMViewport2_Configure(viewport2, 0, 0, rc.right, rc.bottom);
7291 todo_wine ok(SUCCEEDED(hr), "Cannot configure viewport (hr = %#x).\n", hr);
7292 hr = IDirect3DRMViewport2_Clear(viewport2, 0);
7293 ok(SUCCEEDED(hr), "Cannot clear viewport (hr = %#x).\n", hr);
7294 ret_color = get_surface_color(surface, 320, 240);
7295 todo_wine ok(compare_color(ret_color, 0x00bada55, 1), "Got unexpected color 0x%08x.\n", ret_color);
7297 hr = IDirect3DRMViewport2_Configure(viewport2, 0, 0, rc.right, rc.bottom);
7298 todo_wine ok(SUCCEEDED(hr), "Cannot configure viewport (hr = %#x).\n", hr);
7299 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL);
7300 ok(SUCCEEDED(hr), "Cannot clear viewport (hr = %#x).\n", hr);
7301 ret_color = get_surface_color(surface, 320, 240);
7302 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", ret_color);
7304 IDirect3DViewport_Release(d3d_viewport);
7305 IDirectDrawSurface_Release(surface);
7306 IDirectDrawSurface_Release(ds);
7307 IDirect3DDevice2_Release(d3d_device2);
7308 IDirect3DRMViewport2_Release(viewport2);
7309 IDirect3DRMDevice3_Release(device3);
7311 /* Create device without depth surface attached */
7312 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2);
7313 ok(SUCCEEDED(hr), "Cannot get IDirectDraw2 interface (hr = %#x).\n", hr);
7314 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D2, (void **)&d3d2);
7315 ok(SUCCEEDED(hr), "Cannot get IDirect3D2 interface (hr = %x).\n", hr);
7316 d3d_device2 = create_device2_without_ds(ddraw2, window);
7317 if (!d3d_device2)
7318 goto cleanup;
7320 hr = IDirect3DRM3_CreateDeviceFromD3D(d3drm3, d3d2, d3d_device2, &device3);
7321 ok(SUCCEEDED(hr), "Failed to create IDirect3DRMDevice interface (hr = %#x)\n", hr);
7322 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, camera3, 0, 0, rc.right,
7323 rc.bottom, &viewport2);
7324 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport2 interface (hr = %#x)\n", hr);
7325 hr = IDirect3DDevice2_GetRenderTarget(d3d_device2, &surface);
7326 ok(SUCCEEDED(hr), "Cannot get surface to the render target (hr = %#x).\n", hr);
7328 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL);
7329 ok(SUCCEEDED(hr), "Cannot clear viewport (hr = %#x).\n", hr);
7330 ret_color = get_surface_color(surface, 320, 240);
7331 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", ret_color);
7333 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ZBUFFER);
7334 ok(SUCCEEDED(hr), "Cannot clear viewport (hr = %#x).\n", hr);
7336 IDirectDrawSurface_Release(surface);
7337 IDirect3DRMViewport2_Release(viewport2);
7338 IDirect3DRMDevice3_Release(device3);
7339 IDirect3DDevice2_Release(d3d_device2);
7341 cleanup:
7342 IDirect3DRMFrame3_Release(camera3);
7343 IDirect3DRMFrame3_Release(frame3);
7344 IDirect3DRM3_Release(d3drm3);
7345 IDirect3DRM_Release(d3drm1);
7346 IDirectDrawClipper_Release(clipper);
7347 IDirect3D2_Release(d3d2);
7348 IDirectDraw2_Release(ddraw2);
7349 IDirectDraw_Release(ddraw1);
7350 DestroyWindow(window);
7353 static void test_create_texture_from_surface(void)
7355 D3DRMIMAGE testimg =
7357 0, 0, 0, 0, 0,
7358 TRUE, 0, (void *)0xcafebabe, NULL,
7359 0x000000ff, 0x0000ff00, 0x00ff0000, 0, 0, NULL
7361 IDirectDrawSurface *surface = NULL, *surface2 = NULL, *ds = NULL;
7362 IDirect3DRMTexture *texture1;
7363 IDirect3DRMTexture2 *texture2;
7364 IDirect3DRMTexture3 *texture3;
7365 IDirectDraw *ddraw = NULL;
7366 IDirect3DRM *d3drm1 = NULL;
7367 IDirect3DRM2 *d3drm2 = NULL;
7368 IDirect3DRM3 *d3drm3 = NULL;
7369 ULONG ref1, ref2, ref3;
7370 D3DRMIMAGE *image;
7371 DDSURFACEDESC desc;
7372 HWND window;
7373 HRESULT hr;
7374 RECT rc;
7376 hr = DirectDrawCreate(NULL, &ddraw, NULL);
7377 ok(hr == DD_OK, "Cannot get IDirectDraw interface (hr = %x).\n", hr);
7379 window = create_window();
7380 GetClientRect(window, &rc);
7382 hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
7383 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
7385 hr = Direct3DRMCreate(&d3drm1);
7386 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr);
7388 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
7389 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface (hr = %x).\n", hr);
7391 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
7392 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface (hr = %x).\n", hr);
7394 /* Create a surface and use it to create a texture. */
7395 memset(&desc, 0, sizeof(desc));
7396 desc.dwSize = sizeof(desc);
7397 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
7398 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
7399 desc.dwWidth = rc.right;
7400 desc.dwHeight = rc.bottom;
7402 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
7403 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
7405 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface2, NULL);
7406 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
7408 /* Test NULL params */
7409 texture1 = (IDirect3DRMTexture *)0xdeadbeef;
7410 hr = IDirect3DRM_CreateTextureFromSurface(d3drm1, NULL, &texture1);
7411 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
7412 ok(!texture1, "Expected texture returned == NULL, got %p.\n", texture1);
7414 hr = IDirect3DRM_CreateTextureFromSurface(d3drm1, NULL, NULL);
7415 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
7417 texture2 = (IDirect3DRMTexture2 *)0xdeadbeef;
7418 hr = IDirect3DRM2_CreateTextureFromSurface(d3drm2, NULL, &texture2);
7419 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
7420 ok(!texture2, "Expected texture returned == NULL, got %p.\n", texture2);
7422 hr = IDirect3DRM2_CreateTextureFromSurface(d3drm2, NULL, NULL);
7423 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
7425 texture3 = (IDirect3DRMTexture3 *)0xdeadbeef;
7426 hr = IDirect3DRM3_CreateTextureFromSurface(d3drm3, NULL, &texture3);
7427 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
7428 ok(!texture3, "Expected texture returned == NULL, got %p.\n", texture3);
7430 hr = IDirect3DRM3_CreateTextureFromSurface(d3drm3, NULL, NULL);
7431 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
7433 ok(get_refcount((IUnknown *)surface) == 1, "Unexpected surface refcount.\n");
7434 hr = IDirect3DRM_CreateTextureFromSurface(d3drm1, surface, &texture1);
7435 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7437 ok(get_refcount((IUnknown *)surface) == 2, "Unexpected surface refcount.\n");
7438 image = IDirect3DRMTexture_GetImage(texture1);
7439 ok(image == NULL, "Unexpected image, %p.\n", image);
7440 hr = IDirect3DRMTexture_InitFromSurface(texture1, NULL);
7441 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
7442 IDirect3DRMTexture_Release(texture1);
7444 ok(get_refcount((IUnknown *)surface) == 1, "Unexpected surface refcount.\n");
7445 hr = IDirect3DRM2_CreateTextureFromSurface(d3drm2, surface, &texture2);
7446 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7447 ok(get_refcount((IUnknown *)surface) == 2, "Unexpected surface refcount.\n");
7448 image = IDirect3DRMTexture2_GetImage(texture2);
7449 ok(image == NULL, "Unexpected image, %p.\n", image);
7450 hr = IDirect3DRMTexture2_InitFromSurface(texture2, NULL);
7451 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
7452 IDirect3DRMTexture_Release(texture2);
7454 ok(get_refcount((IUnknown *)surface) == 1, "Unexpected surface refcount.\n");
7455 hr = IDirect3DRM3_CreateTextureFromSurface(d3drm3, surface, &texture3);
7456 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7457 ok(get_refcount((IUnknown *)surface) == 2, "Unexpected surface refcount.\n");
7458 image = IDirect3DRMTexture3_GetImage(texture3);
7459 ok(image == NULL, "Unexpected image, %p.\n", image);
7460 hr = IDirect3DRMTexture3_InitFromSurface(texture3, NULL);
7461 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
7462 hr = IDirect3DRMTexture3_GetSurface(texture3, 0, NULL);
7463 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
7464 hr = IDirect3DRMTexture3_GetSurface(texture3, 0, &ds);
7465 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
7466 ok(ds == surface, "Expected same surface back.\n");
7467 IDirectDrawSurface_Release(ds);
7469 /* Init already initialized texture with same surface. */
7470 hr = IDirect3DRMTexture3_InitFromSurface(texture3, surface);
7471 ok(hr == D3DRMERR_BADOBJECT, "Expected a failure, hr %#x.\n", hr);
7473 /* Init already initialized texture with different surface. */
7474 hr = IDirect3DRMTexture3_InitFromSurface(texture3, surface2);
7475 ok(hr == D3DRMERR_BADOBJECT, "Expected a failure, hr %#x.\n", hr);
7477 hr = IDirect3DRMTexture3_GetSurface(texture3, 0, &ds);
7478 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
7479 ok(ds == surface, "Expected same surface back.\n");
7480 IDirectDrawSurface_Release(ds);
7482 ref1 = get_refcount((IUnknown *)d3drm1);
7483 ref2 = get_refcount((IUnknown *)d3drm2);
7484 ref3 = get_refcount((IUnknown *)d3drm3);
7485 hr = IDirect3DRMTexture3_InitFromImage(texture3, &testimg);
7486 ok(hr == D3DRMERR_BADOBJECT, "Expected a failure, hr %#x.\n", hr);
7487 ok(ref1 < get_refcount((IUnknown *)d3drm1), "Expected d3drm1 reference taken.\n");
7488 ok(ref2 == get_refcount((IUnknown *)d3drm2), "Expected d3drm2 reference unchanged.\n");
7489 ok(ref3 == get_refcount((IUnknown *)d3drm3), "Expected d3drm3 reference unchanged.\n");
7490 /* Release leaked reference to d3drm1 */
7491 IDirect3DRM_Release(d3drm1);
7493 IDirect3DRMTexture_Release(texture3);
7495 /* Create from image, initialize from surface. */
7496 hr = IDirect3DRM3_CreateTexture(d3drm3, &testimg, &texture3);
7497 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface (hr = %#x)\n", hr);
7499 ref1 = get_refcount((IUnknown *)d3drm1);
7500 ref2 = get_refcount((IUnknown *)d3drm2);
7501 ref3 = get_refcount((IUnknown *)d3drm3);
7502 hr = IDirect3DRMTexture3_InitFromSurface(texture3, surface);
7503 ok(hr == D3DRMERR_BADOBJECT, "Expected a failure, hr %#x.\n", hr);
7504 ok(ref1 < get_refcount((IUnknown *)d3drm1), "Expected d3drm1 reference taken.\n");
7505 ok(ref2 == get_refcount((IUnknown *)d3drm2), "Expected d3drm2 reference unchanged.\n");
7506 ok(ref3 == get_refcount((IUnknown *)d3drm3), "Expected d3drm3 reference unchanged.\n");
7507 /* Release leaked reference to d3drm1 */
7508 IDirect3DRM_Release(d3drm1);
7509 IDirect3DRMTexture3_Release(texture3);
7511 IDirectDrawSurface_Release(surface2);
7512 IDirectDrawSurface_Release(surface);
7513 IDirect3DRM3_Release(d3drm3);
7514 IDirect3DRM2_Release(d3drm2);
7515 IDirect3DRM_Release(d3drm1);
7516 IDirectDraw_Release(ddraw);
7519 static void test_animation(void)
7521 IDirect3DRMAnimation2 *animation2;
7522 IDirect3DRMAnimation *animation;
7523 D3DRMANIMATIONOPTIONS options;
7524 IDirect3DRMObject *obj, *obj2;
7525 D3DRMANIMATIONKEY keys[10];
7526 IDirect3DRMFrame3 *frame3;
7527 IDirect3DRMFrame *frame;
7528 D3DRMANIMATIONKEY key;
7529 IDirect3DRM *d3drm1;
7530 D3DRMQUATERNION q;
7531 DWORD count, i;
7532 HRESULT hr;
7533 D3DVECTOR v;
7535 hr = Direct3DRMCreate(&d3drm1);
7536 ok(SUCCEEDED(hr), "Failed to create IDirect3DRM instance, hr 0x%08x.\n", hr);
7538 hr = IDirect3DRM_CreateAnimation(d3drm1, NULL);
7539 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr 0x%08x.\n", hr);
7541 CHECK_REFCOUNT(d3drm1, 1);
7542 hr = IDirect3DRM_CreateAnimation(d3drm1, &animation);
7543 ok(SUCCEEDED(hr), "Failed to create animation hr 0x%08x.\n", hr);
7544 CHECK_REFCOUNT(d3drm1, 2);
7546 test_class_name((IDirect3DRMObject *)animation, "Animation");
7548 hr = IDirect3DRMAnimation_QueryInterface(animation, &IID_IDirect3DRMAnimation2, (void **)&animation2);
7549 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMAnimation2, hr 0x%08x.\n", hr);
7550 ok(animation != (void *)animation2, "Expected different interface pointer.\n");
7552 hr = IDirect3DRMAnimation_QueryInterface(animation, &IID_IDirect3DRMObject, (void **)&obj);
7553 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, hr 0x%08x.\n", hr);
7555 hr = IDirect3DRMAnimation2_QueryInterface(animation2, &IID_IDirect3DRMObject, (void **)&obj2);
7556 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, hr 0x%08x.\n", hr);
7558 ok(obj == obj2 && obj == (IDirect3DRMObject *)animation, "Unexpected object pointer.\n");
7560 IDirect3DRMObject_Release(obj);
7561 IDirect3DRMObject_Release(obj2);
7563 /* Set animated frame, get it back. */
7564 hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &frame);
7565 ok(SUCCEEDED(hr), "Failed to create a frame, hr %#x.\n", hr);
7567 hr = IDirect3DRMAnimation_SetFrame(animation, NULL);
7568 ok(SUCCEEDED(hr), "Failed to reset frame, hr %#x.\n", hr);
7570 CHECK_REFCOUNT(frame, 1);
7571 hr = IDirect3DRMAnimation_SetFrame(animation, frame);
7572 ok(SUCCEEDED(hr), "Failed to set a frame, hr %#x.\n", hr);
7573 CHECK_REFCOUNT(frame, 1);
7575 hr = IDirect3DRMAnimation2_GetFrame(animation2, NULL);
7576 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#x.\n", hr);
7578 hr = IDirect3DRMAnimation2_GetFrame(animation2, &frame3);
7579 ok(SUCCEEDED(hr), "Failed to get the frame, %#x.\n", hr);
7580 ok(frame3 != (void *)frame, "Unexpected interface pointer.\n");
7581 CHECK_REFCOUNT(frame, 2);
7583 IDirect3DRMFrame3_Release(frame3);
7585 hr = IDirect3DRMAnimation_SetFrame(animation, NULL);
7586 ok(SUCCEEDED(hr), "Failed to reset frame, hr %#x.\n", hr);
7588 hr = IDirect3DRMFrame_QueryInterface(frame, &IID_IDirect3DRMFrame3, (void **)&frame3);
7589 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMFrame3, hr %#x.\n", hr);
7591 CHECK_REFCOUNT(frame3, 2);
7592 hr = IDirect3DRMAnimation2_SetFrame(animation2, frame3);
7593 ok(SUCCEEDED(hr), "Failed to set a frame, hr %#x.\n", hr);
7594 CHECK_REFCOUNT(frame3, 2);
7596 IDirect3DRMFrame3_Release(frame3);
7597 IDirect3DRMFrame_Release(frame);
7599 /* Animation options. */
7600 options = IDirect3DRMAnimation_GetOptions(animation);
7601 ok(options == (D3DRMANIMATION_CLOSED | D3DRMANIMATION_LINEARPOSITION),
7602 "Unexpected default options %#x.\n", options);
7604 /* Undefined mask value */
7605 hr = IDirect3DRMAnimation_SetOptions(animation, 0xf0000000);
7606 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#x.\n", hr);
7608 options = IDirect3DRMAnimation_GetOptions(animation);
7609 ok(options == (D3DRMANIMATION_CLOSED | D3DRMANIMATION_LINEARPOSITION),
7610 "Unexpected default options %#x.\n", options);
7612 /* Ambiguous mask */
7613 hr = IDirect3DRMAnimation_SetOptions(animation, D3DRMANIMATION_OPEN | D3DRMANIMATION_CLOSED);
7614 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#x.\n", hr);
7616 hr = IDirect3DRMAnimation_SetOptions(animation, D3DRMANIMATION_LINEARPOSITION | D3DRMANIMATION_SPLINEPOSITION);
7617 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#x.\n", hr);
7619 hr = IDirect3DRMAnimation_SetOptions(animation, D3DRMANIMATION_SCALEANDROTATION | D3DRMANIMATION_POSITION);
7620 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#x.\n", hr);
7622 options = IDirect3DRMAnimation_GetOptions(animation);
7623 ok(options == (D3DRMANIMATION_CLOSED | D3DRMANIMATION_LINEARPOSITION),
7624 "Unexpected default options %#x.\n", options);
7626 /* Mask contains undefined bits together with valid one. */
7627 hr = IDirect3DRMAnimation_SetOptions(animation, 0xf0000000 | D3DRMANIMATION_OPEN);
7628 ok(SUCCEEDED(hr), "Failed to set animation options, hr %#x.\n", hr);
7630 options = IDirect3DRMAnimation_GetOptions(animation);
7631 ok(options == (0xf0000000 | D3DRMANIMATION_OPEN), "Unexpected animation options %#x.\n", options);
7633 hr = IDirect3DRMAnimation_SetOptions(animation, D3DRMANIMATION_SCALEANDROTATION);
7634 ok(SUCCEEDED(hr), "Failed to set animation options, hr %#x.\n", hr);
7636 options = IDirect3DRMAnimation_GetOptions(animation);
7637 ok(options == D3DRMANIMATION_SCALEANDROTATION, "Unexpected options %#x.\n", options);
7639 hr = IDirect3DRMAnimation_SetOptions(animation, D3DRMANIMATION_OPEN);
7640 ok(SUCCEEDED(hr), "Failed to set animation options, hr %#x.\n", hr);
7642 options = IDirect3DRMAnimation_GetOptions(animation);
7643 ok(options == D3DRMANIMATION_OPEN, "Unexpected options %#x.\n", options);
7645 hr = IDirect3DRMAnimation_SetOptions(animation, 0);
7646 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#x.\n", hr);
7648 options = IDirect3DRMAnimation_GetOptions(animation);
7649 ok(options == D3DRMANIMATION_OPEN, "Unexpected options %#x.\n", options);
7651 /* Key management. */
7652 hr = IDirect3DRMAnimation_AddPositionKey(animation, 0.0f, 1.0f, 0.0f, 0.0f);
7653 ok(SUCCEEDED(hr), "Failed to add position key, hr %#x.\n", hr);
7655 hr = IDirect3DRMAnimation_AddScaleKey(animation, 0.0f, 1.0f, 2.0f, 1.0f);
7656 ok(SUCCEEDED(hr), "Failed to add scale key, hr %#x.\n", hr);
7658 hr = IDirect3DRMAnimation_AddPositionKey(animation, 0.0f, 2.0f, 0.0f, 0.0f);
7659 ok(SUCCEEDED(hr), "Failed to add position key, hr %#x.\n", hr);
7661 hr = IDirect3DRMAnimation_AddPositionKey(animation, 99.0f, 3.0f, 1.0f, 0.0f);
7662 ok(SUCCEEDED(hr), "Failed to add position key, hr %#x.\n", hr);
7664 hr = IDirect3DRMAnimation_AddPositionKey(animation, 80.0f, 4.0f, 1.0f, 0.0f);
7665 ok(SUCCEEDED(hr), "Failed to add position key, hr %#x.\n", hr);
7667 v.x = 1.0f;
7668 v.y = 0.0f;
7669 v.z = 0.0f;
7670 D3DRMQuaternionFromRotation(&q, &v, 1.0f);
7672 /* NULL quaternion pointer leads to a crash on Windows. */
7673 hr = IDirect3DRMAnimation_AddRotateKey(animation, 0.0f, &q);
7674 ok(SUCCEEDED(hr), "Failed to add rotation key, hr %#.x\n", hr);
7676 count = 0;
7677 memset(keys, 0, sizeof(keys));
7678 hr = IDirect3DRMAnimation2_GetKeys(animation2, 0.0f, 99.0f, &count, keys);
7679 ok(SUCCEEDED(hr), "Failed to get animation keys, hr %#x.\n", hr);
7680 ok(count == 6, "Unexpected key count %u.\n", count);
7682 ok(keys[0].dwKeyType == D3DRMANIMATION_ROTATEKEY, "Unexpected key type %u.\n", keys[0].dwKeyType);
7683 ok(keys[1].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[1].dwKeyType);
7684 ok(keys[2].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[2].dwKeyType);
7685 ok(keys[3].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[3].dwKeyType);
7686 ok(keys[4].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[4].dwKeyType);
7687 ok(keys[5].dwKeyType == D3DRMANIMATION_SCALEKEY, "Unexpected key type %u.\n", keys[5].dwKeyType);
7689 /* Relative order, keys are returned sorted by time. */
7690 ok(keys[1].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[1].dvTime);
7691 ok(keys[2].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[2].dvTime);
7692 ok(keys[3].dvTime == 80.0f, "Unexpected key time %.8e.\n", keys[3].dvTime);
7693 ok(keys[4].dvTime == 99.0f, "Unexpected key time %.8e.\n", keys[4].dvTime);
7695 /* For keys with same time, order they were added in is kept. */
7696 ok(keys[1].dvPositionKey.x == 1.0f, "Unexpected key position x %.8e.\n", keys[1].dvPositionKey.x);
7697 ok(keys[2].dvPositionKey.x == 2.0f, "Unexpected key position x %.8e.\n", keys[2].dvPositionKey.x);
7698 ok(keys[3].dvPositionKey.x == 4.0f, "Unexpected key position x %.8e.\n", keys[3].dvPositionKey.x);
7699 ok(keys[4].dvPositionKey.x == 3.0f, "Unexpected key position x %.8e.\n", keys[4].dvPositionKey.x);
7701 for (i = 0; i < count; i++)
7703 ok(keys[i].dwSize == sizeof(*keys), "%u: unexpected dwSize value %u.\n", i, keys[i].dwSize);
7705 todo_wine
7707 switch (keys[i].dwKeyType)
7709 case D3DRMANIMATION_ROTATEKEY:
7710 ok((keys[i].dwID & 0xf0000000) == 0x40000000, "%u: unexpected id mask %#x.\n", i, keys[i].dwID);
7711 break;
7712 case D3DRMANIMATION_POSITIONKEY:
7713 ok((keys[i].dwID & 0xf0000000) == 0x80000000, "%u: unexpected id mask %#x.\n", i, keys[i].dwID);
7714 break;
7715 case D3DRMANIMATION_SCALEKEY:
7716 ok((keys[i].dwID & 0xf0000000) == 0xc0000000, "%u: unexpected id mask %#x.\n", i, keys[i].dwID);
7717 break;
7718 default:
7719 ok(0, "%u: unknown key type %d.\n", i, keys[i].dwKeyType);
7724 /* No keys in this range. */
7725 count = 10;
7726 hr = IDirect3DRMAnimation2_GetKeys(animation2, 100.0f, 200.0f, &count, NULL);
7727 ok(hr == D3DRMERR_NOSUCHKEY, "Unexpected hr %#x.\n", hr);
7728 ok(count == 0, "Unexpected key count %u.\n", count);
7730 count = 10;
7731 hr = IDirect3DRMAnimation2_GetKeys(animation2, 100.0f, 200.0f, &count, keys);
7732 ok(hr == D3DRMERR_NOSUCHKEY, "Unexpected hr %#x.\n", hr);
7733 ok(count == 0, "Unexpected key count %u.\n", count);
7735 count = 10;
7736 hr = IDirect3DRMAnimation2_GetKeys(animation2, 0.0f, 0.0f, &count, NULL);
7737 ok(SUCCEEDED(hr), "Failed to get animation keys, hr %#x.\n", hr);
7738 ok(count == 4, "Unexpected key count %u.\n", count);
7740 hr = IDirect3DRMAnimation2_GetKeys(animation2, 0.0f, 100.0f, NULL, NULL);
7741 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#x.\n", hr);
7743 /* Time is 0-based. */
7744 hr = IDirect3DRMAnimation2_GetKeys(animation2, -100.0f, -50.0f, NULL, NULL);
7745 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#x.\n", hr);
7747 count = 10;
7748 hr = IDirect3DRMAnimation2_GetKeys(animation2, -100.0f, -50.0f, &count, NULL);
7749 ok(hr == D3DRMERR_NOSUCHKEY, "Unexpected hr %#x.\n", hr);
7750 ok(count == 0, "Unexpected key count %u.\n", count);
7752 count = 10;
7753 hr = IDirect3DRMAnimation2_GetKeys(animation2, -100.0f, 100.0f, &count, NULL);
7754 ok(SUCCEEDED(hr), "Failed to get animation keys, hr %#x.\n", hr);
7755 ok(count == 6, "Unexpected key count %u.\n", count);
7757 /* AddKey() tests. */
7758 hr = IDirect3DRMAnimation2_AddKey(animation2, NULL);
7759 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
7761 memset(&key, 0, sizeof(key));
7762 key.dwKeyType = D3DRMANIMATION_POSITIONKEY;
7763 hr = IDirect3DRMAnimation2_AddKey(animation2, &key);
7764 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
7766 memset(&key, 0, sizeof(key));
7767 key.dwSize = sizeof(key) - 1;
7768 key.dwKeyType = D3DRMANIMATION_POSITIONKEY;
7769 hr = IDirect3DRMAnimation2_AddKey(animation2, &key);
7770 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
7772 memset(&key, 0, sizeof(key));
7773 key.dwSize = sizeof(key) + 1;
7774 key.dwKeyType = D3DRMANIMATION_POSITIONKEY;
7775 hr = IDirect3DRMAnimation2_AddKey(animation2, &key);
7776 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
7778 memset(&key, 0, sizeof(key));
7779 key.dwSize = sizeof(key);
7780 key.dwKeyType = D3DRMANIMATION_POSITIONKEY;
7781 key.dvPositionKey.x = 8.0f;
7782 hr = IDirect3DRMAnimation2_AddKey(animation2, &key);
7783 ok(SUCCEEDED(hr), "Failed to add key, hr %#x.\n", hr);
7785 /* Delete tests. */
7786 hr = IDirect3DRMAnimation_AddRotateKey(animation, 0.0f, &q);
7787 ok(SUCCEEDED(hr), "Failed to add rotation key, hr %#.x\n", hr);
7789 hr = IDirect3DRMAnimation_AddScaleKey(animation, 0.0f, 1.0f, 2.0f, 1.0f);
7790 ok(SUCCEEDED(hr), "Failed to add scale key, hr %#x.\n", hr);
7792 count = 0;
7793 memset(keys, 0, sizeof(keys));
7794 hr = IDirect3DRMAnimation2_GetKeys(animation2, -1000.0f, 1000.0f, &count, keys);
7795 ok(SUCCEEDED(hr), "Failed to get key count, hr %#x.\n", hr);
7796 ok(count == 9, "Unexpected key count %u.\n", count);
7798 ok(keys[0].dwKeyType == D3DRMANIMATION_ROTATEKEY, "Unexpected key type %u.\n", keys[0].dwKeyType);
7799 ok(keys[1].dwKeyType == D3DRMANIMATION_ROTATEKEY, "Unexpected key type %u.\n", keys[1].dwKeyType);
7800 ok(keys[2].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[2].dwKeyType);
7801 ok(keys[3].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[3].dwKeyType);
7802 ok(keys[4].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[4].dwKeyType);
7803 ok(keys[5].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[5].dwKeyType);
7804 ok(keys[6].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[6].dwKeyType);
7805 ok(keys[7].dwKeyType == D3DRMANIMATION_SCALEKEY, "Unexpected key type %u.\n", keys[7].dwKeyType);
7806 ok(keys[8].dwKeyType == D3DRMANIMATION_SCALEKEY, "Unexpected key type %u.\n", keys[8].dwKeyType);
7808 ok(keys[0].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[0].dvTime);
7809 ok(keys[1].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[1].dvTime);
7810 ok(keys[2].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[2].dvTime);
7811 ok(keys[3].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[3].dvTime);
7812 ok(keys[4].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[4].dvTime);
7813 ok(keys[5].dvTime == 80.0f, "Unexpected key time %.8e.\n", keys[5].dvTime);
7814 ok(keys[6].dvTime == 99.0f, "Unexpected key time %.8e.\n", keys[6].dvTime);
7815 ok(keys[7].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[7].dvTime);
7816 ok(keys[8].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[8].dvTime);
7818 hr = IDirect3DRMAnimation_DeleteKey(animation, -100.0f);
7819 ok(SUCCEEDED(hr), "Failed to delete keys, hr %#x.\n", hr);
7821 hr = IDirect3DRMAnimation_DeleteKey(animation, 100.0f);
7822 ok(SUCCEEDED(hr), "Failed to delete keys, hr %#x.\n", hr);
7824 /* Only first Position keys are not removed. */
7825 hr = IDirect3DRMAnimation_DeleteKey(animation, 0.0f);
7826 ok(SUCCEEDED(hr), "Failed to delete keys, hr %#x.\n", hr);
7828 count = 0;
7829 memset(keys, 0, sizeof(keys));
7830 hr = IDirect3DRMAnimation2_GetKeys(animation2, 0.0f, 100.0f, &count, keys);
7831 ok(SUCCEEDED(hr), "Failed to get key count, hr %#x.\n", hr);
7832 ok(count == 6, "Unexpected key count %u.\n", count);
7834 ok(keys[0].dwKeyType == D3DRMANIMATION_ROTATEKEY, "Unexpected key type %u.\n", keys[0].dwKeyType);
7835 ok(keys[1].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[1].dwKeyType);
7836 ok(keys[2].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[2].dwKeyType);
7837 ok(keys[3].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[3].dwKeyType);
7838 ok(keys[4].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[4].dwKeyType);
7839 ok(keys[5].dwKeyType == D3DRMANIMATION_SCALEKEY, "Unexpected key type %u.\n", keys[5].dwKeyType);
7841 ok(keys[0].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[0].dvTime);
7842 ok(keys[1].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[1].dvTime);
7843 ok(keys[2].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[2].dvTime);
7844 ok(keys[3].dvTime == 80.0f, "Unexpected key time %.8e.\n", keys[3].dvTime);
7845 ok(keys[4].dvTime == 99.0f, "Unexpected key time %.8e.\n", keys[4].dvTime);
7846 ok(keys[5].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[5].dvTime);
7848 hr = IDirect3DRMAnimation_DeleteKey(animation, 0.0f);
7849 ok(SUCCEEDED(hr), "Failed to delete keys, hr %#x.\n", hr);
7851 count = 0;
7852 hr = IDirect3DRMAnimation2_GetKeys(animation2, 0.0f, 100.0f, &count, NULL);
7853 ok(SUCCEEDED(hr), "Failed to get key count, hr %#x.\n", hr);
7854 ok(count == 3, "Unexpected key count %u.\n", count);
7856 IDirect3DRMAnimation2_Release(animation2);
7857 IDirect3DRMAnimation_Release(animation);
7859 IDirect3DRM_Release(d3drm1);
7862 static void test_animation_qi(void)
7864 static const struct qi_test tests[] =
7866 { &IID_IDirect3DRMAnimation2, &IID_IUnknown, &IID_IDirect3DRMAnimation2, S_OK },
7867 { &IID_IDirect3DRMAnimation, &IID_IUnknown, &IID_IDirect3DRMAnimation, S_OK },
7868 { &IID_IDirect3DRM, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7869 { &IID_IDirect3DRMDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7870 { &IID_IDirect3DRMObject, &IID_IUnknown, &IID_IDirect3DRMAnimation, S_OK },
7871 { &IID_IDirect3DRMDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7872 { &IID_IDirect3DRMDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7873 { &IID_IDirect3DRMViewport, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7874 { &IID_IDirect3DRMViewport2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7875 { &IID_IDirect3DRM3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7876 { &IID_IDirect3DRM2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7877 { &IID_IDirect3DRMVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7878 { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7879 { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7880 { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7881 { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7882 { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7883 { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7884 { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7885 { &IID_IDirect3DRMTexture, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7886 { &IID_IDirect3DRMTexture2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7887 { &IID_IDirect3DRMTexture3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7888 { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7889 { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7890 { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7891 { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7892 { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7893 { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7894 { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7895 { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7896 { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7897 { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7898 { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7899 { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7900 { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7901 { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7902 { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7903 { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7904 { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7905 { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7906 { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7907 { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7908 { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7909 { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7910 { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7911 { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7912 { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7913 { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7914 { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7915 { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7916 { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7917 { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7918 { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7919 { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7920 { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7921 { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7922 { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7923 { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7924 { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7925 { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7926 { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7927 { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7928 { &IID_IUnknown, &IID_IUnknown, NULL, S_OK },
7930 IDirect3DRMAnimation2 *animation2;
7931 IDirect3DRMAnimation *animation;
7932 IDirect3DRM3 *d3drm3;
7933 IDirect3DRM *d3drm1;
7934 IUnknown *unknown;
7935 HRESULT hr;
7937 hr = Direct3DRMCreate(&d3drm1);
7938 ok(SUCCEEDED(hr), "Failed to create d3drm instance, hr %#x.\n", hr);
7940 hr = IDirect3DRM_CreateAnimation(d3drm1, &animation);
7941 ok(SUCCEEDED(hr), "Failed to create animation hr %#x.\n", hr);
7943 hr = IDirect3DRMAnimation_QueryInterface(animation, &IID_IUnknown, (void **)&unknown);
7944 ok(SUCCEEDED(hr), "Failed to get IUnknown from animation, hr %#x.\n", hr);
7945 IDirect3DRMAnimation_Release(animation);
7947 test_qi("animation_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
7948 IUnknown_Release(unknown);
7950 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
7951 ok(SUCCEEDED(hr), "Failed to get IDirect3DRM3, hr %#x.\n", hr);
7953 hr = IDirect3DRM3_CreateAnimation(d3drm3, &animation2);
7954 ok(SUCCEEDED(hr), "Failed to create animation hr %#x.\n", hr);
7956 hr = IDirect3DRMAnimation2_QueryInterface(animation2, &IID_IUnknown, (void **)&unknown);
7957 ok(SUCCEEDED(hr), "Failed to get IUnknown from animation, hr %#x.\n", hr);
7958 IDirect3DRMAnimation2_Release(animation2);
7960 test_qi("animation2_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
7961 IUnknown_Release(unknown);
7963 IDirect3DRM3_Release(d3drm3);
7964 IDirect3DRM_Release(d3drm1);
7967 static void test_wrap(void)
7969 IDirect3DRMWrap *wrap;
7970 IDirect3DRM *d3drm1;
7971 HRESULT hr;
7973 hr = Direct3DRMCreate(&d3drm1);
7974 ok(SUCCEEDED(hr), "Failed to create IDirect3DRM instance, hr %#x.\n", hr);
7976 hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_CDirect3DRMWrap, NULL, &IID_IDirect3DRMWrap, (void **)&wrap);
7977 ok(SUCCEEDED(hr), "Failed to create wrap instance, hr %#x.\n", hr);
7979 test_class_name((IDirect3DRMObject *)wrap, "");
7981 IDirect3DRMWrap_Release(wrap);
7982 IDirect3DRM_Release(d3drm1);
7985 static void test_wrap_qi(void)
7987 static const struct qi_test tests[] =
7989 { &IID_IDirect3DRMWrap, &IID_IUnknown, &IID_IDirect3DRMWrap, S_OK },
7990 { &IID_IDirect3DRM, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7991 { &IID_IDirect3DRMDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7992 { &IID_IDirect3DRMObject, &IID_IUnknown, &IID_IDirect3DRMWrap, S_OK },
7993 { &IID_IDirect3DRMDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7994 { &IID_IDirect3DRMDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7995 { &IID_IDirect3DRMViewport, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7996 { &IID_IDirect3DRMViewport2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7997 { &IID_IDirect3DRM3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7998 { &IID_IDirect3DRM2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7999 { &IID_IDirect3DRMVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8000 { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8001 { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8002 { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8003 { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8004 { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8005 { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8006 { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8007 { &IID_IDirect3DRMTexture, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8008 { &IID_IDirect3DRMTexture2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8009 { &IID_IDirect3DRMTexture3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8010 { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8011 { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8012 { &IID_IDirect3DRMAnimation, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8013 { &IID_IDirect3DRMAnimation2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8014 { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8015 { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8016 { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8017 { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8018 { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8019 { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8020 { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8021 { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8022 { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8023 { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8024 { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8025 { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8026 { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8027 { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8028 { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8029 { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8030 { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8031 { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8032 { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8033 { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8034 { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8035 { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8036 { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8037 { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8038 { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8039 { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8040 { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8041 { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8042 { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8043 { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8044 { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8045 { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8046 { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8047 { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8048 { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8049 { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8050 { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8051 { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8052 { &IID_IUnknown, &IID_IUnknown, NULL, S_OK },
8054 IDirect3DRMWrap *wrap;
8055 IDirect3DRM *d3drm1;
8056 IUnknown *unknown;
8057 HRESULT hr;
8059 hr = Direct3DRMCreate(&d3drm1);
8060 ok(SUCCEEDED(hr), "Failed to create d3drm instance, hr %#x.\n", hr);
8062 hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_CDirect3DRMWrap, NULL, &IID_IDirect3DRMWrap, (void **)&wrap);
8063 ok(SUCCEEDED(hr), "Failed to create wrap instance, hr %#x.\n", hr);
8065 hr = IDirect3DRMWrap_QueryInterface(wrap, &IID_IUnknown, (void **)&unknown);
8066 ok(SUCCEEDED(hr), "Failed to get IUnknown from wrap (hr = %#x)\n", hr);
8067 IDirect3DRMWrap_Release(wrap);
8068 test_qi("wrap_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
8069 IUnknown_Release(unknown);
8071 IDirect3DRM_Release(d3drm1);
8073 START_TEST(d3drm)
8075 test_MeshBuilder();
8076 test_MeshBuilder3();
8077 test_Mesh();
8078 test_Face();
8079 test_Frame();
8080 test_Device();
8081 test_object();
8082 test_Viewport();
8083 test_Light();
8084 test_Material2();
8085 test_Texture();
8086 test_frame_transform();
8087 test_d3drm_load();
8088 test_frame_mesh_materials();
8089 test_d3drm_qi();
8090 test_frame_qi();
8091 test_device_qi();
8092 test_create_device_from_clipper1();
8093 test_create_device_from_clipper2();
8094 test_create_device_from_clipper3();
8095 test_create_device_from_surface1();
8096 test_create_device_from_surface2();
8097 test_create_device_from_surface3();
8098 test_create_device_from_d3d1();
8099 test_create_device_from_d3d2();
8100 test_create_device_from_d3d3();
8101 test_create_device_1();
8102 test_create_device_2();
8103 test_create_device_3();
8104 test_load_texture();
8105 test_texture_qi();
8106 test_viewport_qi();
8107 test_viewport_clear1();
8108 test_viewport_clear2();
8109 test_create_texture_from_surface();
8110 test_animation();
8111 test_animation_qi();
8112 test_wrap();
8113 test_wrap_qi();