d3drm: Implement IDirect3DRMTexture3::{Get,Set}DecalSize().
[wine.git] / dlls / d3drm / tests / d3drm.c
blob5745fea4b09346f4499b1d6b16a58b648578d986
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 %#lx.\n", hr);
183 hr = IDirect3DRMViewport_GetClassName(object, NULL, NULL);
184 ok_(__FILE__, line)(hr == E_INVALIDARG, "Got unexpected hr %#lx.\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 %#lx.\n", hr);
189 ok_(__FILE__, line)(size == strlen(name) + 1, "wrong size: %lu.\n", size);
191 size = size2 = !!*name;
192 hr = IDirect3DRMObject_GetClassName(object, &size, cname);
193 ok_(__FILE__, line)(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
194 ok_(__FILE__, line)(size == size2, "Got size %lu.\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 %#lx.\n", hr);
199 ok_(__FILE__, line)(size == strlen(name) + 1, "wrong size: %lu.\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 %#lx.\n", hr);
205 ok_(__FILE__, line)(size == strlen(name) + 1, "wrong size: %lu.\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 %#lx.\n", hr);
212 ok_(__FILE__, line)(size == strlen(name), "Wrong classname size: %lu.\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 %#lx.\n", hr);
226 name[0] = 0x1f;
227 hr = IDirect3DRMObject_GetName(object, NULL, name);
228 ok_(__FILE__, line)(hr == E_INVALIDARG, "Got unexpected hr %#lx.\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 %#lx.\n", hr);
235 ok_(__FILE__, line)(size == 0, "Unexpected size %lu.\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 %#lx.\n", hr);
241 ok_(__FILE__, line)(size == 0, "Unexpected size %lu.\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 %#lx.\n", hr);
248 ok_(__FILE__, line)(size == 0, "Unexpected size %lu.\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 %#lx.\n", hr);
254 hr = IDirect3DRMObject_SetName(object, "name");
255 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to set a name, hr %#lx.\n", hr);
257 size = 0;
258 hr = IDirect3DRMObject_GetName(object, &size, NULL);
259 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#lx.\n", hr);
260 ok_(__FILE__, line)(size == strlen("name") + 1, "Unexpected size %lu.\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 %#lx.\n", hr);
265 ok_(__FILE__, line)(size == strlen("name") + 1, "Unexpected size %lu.\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 %#lx.\n", hr);
272 ok_(__FILE__, line)(size == 2, "Unexpected size %lu.\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 %#lx.\n", hr);
278 size = 1;
279 hr = IDirect3DRMObject_GetName(object, &size, NULL);
280 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get name size, hr %#lx.\n", hr);
281 ok_(__FILE__, line)(size == 0, "Unexpected size %lu.\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 %#lx.\n", hr);
287 ok_(__FILE__, line)(size == 0, "Unexpected size %lu.\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 %#lx\n", hr);
459 hr = IDirect3DRM_CreateMeshBuilder(d3drm, &pMeshBuilder);
460 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder interface, hr %#lx\n", hr);
462 hr = IDirect3DRMMeshBuilder_QueryInterface(pMeshBuilder, &IID_IDirect3DRMObject, (void **)&unk);
463 ok(SUCCEEDED(hr), "Unexpected hr %#lx.\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), "Unexpected hr %#lx.\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), "Unexpected hr %#lx.\n", hr);
475 hr = IDirect3DRMMeshBuilder3_QueryInterface(meshbuilder3, &IID_IDirect3DRMObject, (void **)&unk);
476 ok(SUCCEEDED(hr), "Unexpected hr %#lx.\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), "Unexpected hr %#lx.\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 %#lx\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 %#lx\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 %#lx\n", hr);
505 size = sizeof(name);
506 hr = IDirect3DRMMeshBuilder_GetName(pMeshBuilder, &size, name);
507 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\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, "Unexpected hr %#lx.\n", hr);
512 hr = IDirect3DRMMeshBuilder_SetName(pMeshBuilder, NULL);
513 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
514 size = sizeof(name);
515 hr = IDirect3DRMMeshBuilder_GetName(pMeshBuilder, &size, name);
516 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
517 ok(size == 0, "Size should be 0 instead of %lu.\n", size);
518 hr = IDirect3DRMMeshBuilder_SetName(pMeshBuilder, "");
519 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
520 size = sizeof(name);
521 hr = IDirect3DRMMeshBuilder_GetName(pMeshBuilder, &size, name);
522 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\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 %#lx\n", hr);
533 ok(val1 == 4, "Wrong number of vertices %ld (must be 4)\n", val1);
534 ok(val2 == 4, "Wrong number of normals %ld (must be 4)\n", val2);
535 ok(val3 == 22, "Wrong number of face data bytes %ld (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 %#lx\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 %#lx\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 %#lx\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 %#lx\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 %#lx\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 %#lx\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 %#lx\n", hr);
577 hr = IDirect3DRMMeshBuilder_SetTextureCoordinates(pMeshBuilder, 4, valu, valv);
578 ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE, hr %#lx\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 %#lx\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 %#lx\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 %#lx.\n", hr);
595 if (hr == D3DRM_OK)
597 DWORD nb_groups;
599 nb_groups = IDirect3DRMMesh_GetGroupCount(mesh);
600 ok(nb_groups == 0, "GetCroupCount returned %lu\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 %#lx\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, "Unexpected hr %#lx.\n", hr);
620 hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, NULL, v, &val2, n, &val3, f);
621 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\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, "Unexpected hr %#lx.\n", hr);
625 hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, NULL, n, &val3, f);
626 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\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, "Unexpected hr %#lx.\n", hr);
630 hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, NULL, f);
631 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\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 %#lx\n", hr);
636 ok(val1 == 3, "Wrong number of vertices %ld (must be 3)\n", val1);
637 ok(val2 == 3, "Wrong number of normals %ld (must be 3)\n", val2);
638 ok(val3 == 8, "Wrong number of face data bytes %ld (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] = %ld (expected 3)\n", f[0]);
646 ok(f[1] == 0 , "Wrong component f[1] = %ld (expected 0)\n", f[1]);
647 ok(f[2] == 0 , "Wrong component f[2] = %ld (expected 0)\n", f[2]);
648 ok(f[3] == 1 , "Wrong component f[3] = %ld (expected 1)\n", f[3]);
649 ok(f[4] == 1 , "Wrong component f[4] = %ld (expected 1)\n", f[4]);
650 ok(f[5] == 2 , "Wrong component f[5] = %ld (expected 2)\n", f[5]);
651 ok(f[6] == 2 , "Wrong component f[6] = %ld (expected 2)\n", f[6]);
652 ok(f[7] == 0 , "Wrong component f[7] = %ld (expected 0)\n", f[7]);
654 hr = IDirect3DRMMeshBuilder_CreateMesh(pMeshBuilder, &mesh);
655 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\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 %lu.\n", nb_groups);
667 hr = IDirect3DRMMesh_GetGroup(mesh, 1, &nb_vertices, &nb_faces, &nb_face_vertices, &data_size, NULL);
668 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
669 hr = IDirect3DRMMesh_GetGroup(mesh, 0, &nb_vertices, &nb_faces, &nb_face_vertices, &data_size, NULL);
670 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\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 %lu (must be 3)\n", data_size);
675 color = IDirect3DRMMesh_GetGroupColor(mesh, 0);
676 ok(color == 0xff00ff00, "Wrong color returned %#lx instead of %#x\n", color, 0xff00ff00);
677 hr = IDirect3DRMMesh_GetGroupTexture(mesh, 0, &texture);
678 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
679 ok(texture == NULL, "No texture should be present\n");
680 hr = IDirect3DRMMesh_GetGroupMaterial(mesh, 0, &material);
681 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\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 %#lx.\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 %#lx.\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 %#lx.\n", hr);
703 hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, &val1, v, &val2, n, &val3, f);
704 ok(hr == D3DRM_OK, "Cannot get vertices information, hr %#lx\n", hr);
705 ok(val2 == 3, "Wrong number of normals %ld (must be 3)\n", val2);
706 ok(val1 == 3, "Wrong number of vertices %ld (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 %#lx\n", hr);
735 if (FAILED(hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM3, (void **)&d3drm3)))
737 win_skip("Cannot get IDirect3DRM3 interface, hr %#lx, 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 %#lx\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 %#lx\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 %#lx\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 %#lx\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 %#lx\n", hr);
771 ok(val1 == 4, "Wrong number of vertices %ld (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 %#lx\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 %#lx\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 %#lx\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 %#lx\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 %#lx\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 %#lx\n", hr);
805 hr = IDirect3DRMMeshBuilder3_SetTextureCoordinates(pMeshBuilder3, 4, valu, valv);
806 ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE, hr %#lx\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 %#lx\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 %#lx\n", hr);
830 hr = IDirect3DRM_CreateMesh(d3drm, &mesh);
831 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMesh interface, hr %#lx\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), "Unexpected hr %#lx.\n", hr);
838 IUnknown_Release(unk);
840 hr = IDirect3DRMMesh_QueryInterface(mesh, &IID_IDirect3DRMVisual, (void **)&unk);
841 ok(SUCCEEDED(hr), "Unexpected hr %#lx.\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;
866 D3DRMRENDERQUALITY quality;
868 hr = Direct3DRMCreate(&d3drm);
869 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx\n", hr);
871 hr = IDirect3DRM_CreateFace(d3drm, &face1);
872 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFace interface, hr %#lx\n", hr);
873 if (FAILED(hr))
875 skip("Cannot get IDirect3DRMFace interface, hr %#lx, skipping tests\n", hr);
876 IDirect3DRM_Release(d3drm);
877 return;
880 hr = IDirect3DRMFace_QueryInterface(face1, &IID_IDirect3DRMObject, (void **)&obj);
881 ok(SUCCEEDED(hr), "Unexpected hr %#lx.\n", hr);
882 ok(obj == (IDirect3DRMObject *)face1, "Unexpected interface pointer.\n");
883 IDirect3DRMObject_Release(obj);
885 test_class_name((IDirect3DRMObject *)face1, "Face");
886 test_object_name((IDirect3DRMObject *)face1);
888 icount = IDirect3DRMFace_GetVertexCount(face1);
889 ok(!icount, "wrong VertexCount: %i\n", icount);
891 IDirect3DRMFace_Release(face1);
893 if (FAILED(hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM2, (void **)&d3drm2)))
895 win_skip("Cannot get IDirect3DRM2 interface, hr %#lx, skipping tests\n", hr);
896 IDirect3DRM_Release(d3drm);
897 return;
900 hr = IDirect3DRM2_CreateMeshBuilder(d3drm2, &MeshBuilder2);
901 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder2 interface, hr %#lx\n", hr);
903 icount = IDirect3DRMMeshBuilder2_GetFaceCount(MeshBuilder2);
904 ok(!icount, "wrong FaceCount: %i\n", icount);
906 array1 = NULL;
907 hr = IDirect3DRMMeshBuilder2_GetFaces(MeshBuilder2, &array1);
908 todo_wine
909 ok(hr == D3DRM_OK, "Cannot get FaceArray, hr %#lx\n", hr);
911 hr = IDirect3DRMMeshBuilder2_CreateFace(MeshBuilder2, &face1);
912 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFace interface, hr %#lx\n", hr);
914 icount = IDirect3DRMMeshBuilder2_GetFaceCount(MeshBuilder2);
915 todo_wine
916 ok(icount == 1, "wrong FaceCount: %i\n", icount);
918 array1 = NULL;
919 hr = IDirect3DRMMeshBuilder2_GetFaces(MeshBuilder2, &array1);
920 todo_wine
921 ok(hr == D3DRM_OK, "Cannot get FaceArray, hr %#lx\n", hr);
922 todo_wine
923 ok(array1 != NULL, "pArray = %p\n", array1);
924 if (array1)
926 IDirect3DRMFace *face;
927 count = IDirect3DRMFaceArray_GetSize(array1);
928 ok(count == 1, "count = %lu\n", count);
929 hr = IDirect3DRMFaceArray_GetElement(array1, 0, &face);
930 ok(hr == D3DRM_OK, "Cannot get face, hr %#lx\n", hr);
931 IDirect3DRMFace_Release(face);
932 IDirect3DRMFaceArray_Release(array1);
935 icount = IDirect3DRMFace_GetVertexCount(face1);
936 ok(!icount, "wrong VertexCount: %i\n", icount);
938 quality = IDirect3DRMMeshBuilder3_GetQuality(MeshBuilder2);
939 ok(quality == D3DRMRENDER_GOURAUD, "Unexpected %lx.\n", quality);
941 hr = IDirect3DRMMeshBuilder3_SetQuality(MeshBuilder2, D3DRMRENDER_PHONG);
942 ok(hr == S_OK, "got %lx.\n", hr);
944 quality = IDirect3DRMMeshBuilder3_GetQuality(MeshBuilder2);
945 ok(quality == D3DRMRENDER_PHONG, "got %lx.\n", quality);
947 hr = IDirect3DRMMeshBuilder3_SetQuality(MeshBuilder2, D3DRMRENDER_GOURAUD);
948 ok(hr == S_OK, "got %lx.\n", hr);
950 IDirect3DRMFace_Release(face1);
951 IDirect3DRMMeshBuilder2_Release(MeshBuilder2);
953 if (FAILED(hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM3, (void **)&d3drm3)))
955 win_skip("Cannot get IDirect3DRM3 interface, hr %#lx, skipping tests\n", hr);
956 IDirect3DRM_Release(d3drm);
957 return;
960 hr = IDirect3DRM3_CreateMeshBuilder(d3drm3, &MeshBuilder3);
961 ok(hr == D3DRM_OK, "Unexpected hr %lx.\n", hr);
963 icount = IDirect3DRMMeshBuilder3_GetFaceCount(MeshBuilder3);
964 ok(!icount, "wrong FaceCount: %i\n", icount);
966 hr = IDirect3DRMMeshBuilder3_CreateFace(MeshBuilder3, &face2);
967 ok(hr == D3DRM_OK, "Unexpected hr %lx.\n", hr);
969 hr = IDirect3DRMFace2_QueryInterface(face2, &IID_IDirect3DRMObject, (void **)&obj);
970 ok(SUCCEEDED(hr), "Unexpected hr %#lx.\n", hr);
972 hr = IDirect3DRMFace2_QueryInterface(face2, &IID_IDirect3DRMFace, (void **)&face1);
973 ok(SUCCEEDED(hr), "Unexpected hr %#lx.\n", hr);
974 ok(obj == (IDirect3DRMObject *)face1, "Unexpected interface pointer.\n");
976 IDirect3DRMFace_Release(face1);
977 IDirect3DRMObject_Release(obj);
979 test_class_name((IDirect3DRMObject *)face2, "Face");
980 test_object_name((IDirect3DRMObject *)face2);
982 icount = IDirect3DRMMeshBuilder3_GetFaceCount(MeshBuilder3);
983 todo_wine
984 ok(icount == 1, "wrong FaceCount: %i\n", icount);
986 array1 = NULL;
987 hr = IDirect3DRMMeshBuilder3_GetFaces(MeshBuilder3, &array1);
988 todo_wine
989 ok(hr == D3DRM_OK, "Cannot get FaceArray, hr %#lx\n", hr);
990 todo_wine
991 ok(array1 != NULL, "pArray = %p\n", array1);
992 if (array1)
994 IDirect3DRMFace *face;
995 count = IDirect3DRMFaceArray_GetSize(array1);
996 ok(count == 1, "count = %lu\n", count);
997 hr = IDirect3DRMFaceArray_GetElement(array1, 0, &face);
998 ok(hr == D3DRM_OK, "Cannot get face, hr %#lx\n", hr);
999 IDirect3DRMFace_Release(face);
1000 IDirect3DRMFaceArray_Release(array1);
1003 icount = IDirect3DRMFace2_GetVertexCount(face2);
1004 ok(!icount, "wrong VertexCount: %i\n", icount);
1006 info.lpMemory = data_ok;
1007 info.dSize = strlen(data_ok);
1008 hr = IDirect3DRMMeshBuilder3_Load(MeshBuilder3, &info, NULL, D3DRMLOAD_FROMMEMORY, NULL, NULL);
1009 ok(hr == D3DRM_OK, "Cannot load mesh data, hr %#lx\n", hr);
1011 icount = IDirect3DRMMeshBuilder3_GetVertexCount(MeshBuilder3);
1012 ok(icount == 4, "Wrong number of vertices %d (must be 4)\n", icount);
1014 icount = IDirect3DRMMeshBuilder3_GetNormalCount(MeshBuilder3);
1015 ok(icount == 4, "Wrong number of normals %d (must be 4)\n", icount);
1017 icount = IDirect3DRMMeshBuilder3_GetFaceCount(MeshBuilder3);
1018 todo_wine
1019 ok(icount == 4, "Wrong number of faces %d (must be 4)\n", icount);
1021 count = 4;
1022 hr = IDirect3DRMMeshBuilder3_GetVertices(MeshBuilder3, 0, &count, v1);
1023 ok(hr == D3DRM_OK, "Cannot get vertices information, hr %#lx\n", hr);
1024 ok(count == 4, "Wrong number of vertices %ld (must be 4)\n", count);
1026 hr = IDirect3DRMMeshBuilder3_GetNormals(MeshBuilder3, 0, &count, n1);
1027 ok(hr == D3DRM_OK, "Cannot get normals information, hr %#lx\n", hr);
1028 ok(count == 4, "Wrong number of normals %ld (must be 4)\n", count);
1030 array1 = NULL;
1031 hr = IDirect3DRMMeshBuilder3_GetFaces(MeshBuilder3, &array1);
1032 todo_wine
1033 ok(hr == D3DRM_OK, "Cannot get FaceArray, hr %#lx\n", hr);
1034 todo_wine
1035 ok(array1 != NULL, "pArray = %p\n", array1);
1036 if (array1)
1038 IDirect3DRMFace *face;
1039 count = IDirect3DRMFaceArray_GetSize(array1);
1040 ok(count == 4, "count = %lu\n", count);
1041 hr = IDirect3DRMFaceArray_GetElement(array1, 1, &face);
1042 ok(hr == D3DRM_OK, "Cannot get face, hr %#lx\n", hr);
1043 hr = IDirect3DRMFace_GetVertices(face, &count, v2, n2);
1044 ok(hr == D3DRM_OK, "Cannot get vertices information, hr %#lx\n", hr);
1045 ok(count == 3, "Wrong number of vertices %ld (must be 3)\n", count);
1047 vector_eq(&v1[0], &v2[0]);
1048 vector_eq(&v1[1], &v2[1]);
1049 vector_eq(&v1[2], &v2[2]);
1051 vector_eq(&n1[0], &n2[0]);
1052 vector_eq(&n1[1], &n2[1]);
1053 vector_eq(&n1[2], &n2[2]);
1055 IDirect3DRMFace_Release(face);
1056 IDirect3DRMFaceArray_Release(array1);
1059 /* Setting face color. */
1060 hr = IDirect3DRMFace2_SetColor(face2, 0x1f180587);
1061 ok(SUCCEEDED(hr), "Failed to set face color, hr %#lx.\n", hr);
1062 color = IDirect3DRMFace2_GetColor(face2);
1063 ok(color == 0x1f180587, "Unexpected color %8lx.\n", color);
1065 hr = IDirect3DRMFace2_SetColorRGB(face2, 0.5f, 0.5f, 0.5f);
1066 ok(SUCCEEDED(hr), "Failed to set color, hr %#lx.\n", hr);
1067 color = IDirect3DRMFace2_GetColor(face2);
1068 ok(color == 0xff7f7f7f, "Unexpected color %8lx.\n", color);
1070 IDirect3DRMFace2_Release(face2);
1071 IDirect3DRMMeshBuilder3_Release(MeshBuilder3);
1072 IDirect3DRM3_Release(d3drm3);
1073 IDirect3DRM2_Release(d3drm2);
1074 IDirect3DRM_Release(d3drm);
1077 static void test_Frame(void)
1079 HRESULT hr;
1080 IDirect3DRM *d3drm;
1081 IDirect3DRMFrame *pFrameC;
1082 IDirect3DRMFrame *pFrameP1;
1083 IDirect3DRMFrame *pFrameP2;
1084 IDirect3DRMFrame *pFrameTmp;
1085 IDirect3DRMFrame *scene_frame;
1086 IDirect3DRMFrameArray *frame_array;
1087 IDirect3DRMMeshBuilder *mesh_builder;
1088 IDirect3DRMVisual *visual1;
1089 IDirect3DRMVisual *visual_tmp;
1090 IDirect3DRMVisualArray *visual_array;
1091 IDirect3DRMLight *light1;
1092 IDirect3DRMLight *light_tmp;
1093 IDirect3DRMLightArray *light_array;
1094 IDirect3DRMFrame3 *frame3;
1095 DWORD count, options;
1096 ULONG ref, ref2;
1097 D3DCOLOR color;
1099 hr = Direct3DRMCreate(&d3drm);
1100 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx\n", hr);
1102 ref = get_refcount((IUnknown *)d3drm);
1103 hr = IDirect3DRM_CreateFrame(d3drm, NULL, &pFrameC);
1104 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface, hr %#lx\n", hr);
1105 CHECK_REFCOUNT(pFrameC, 1);
1106 ref2 = get_refcount((IUnknown *)d3drm);
1107 ok(ref2 > ref, "Expected d3drm object to be referenced.\n");
1109 test_class_name((IDirect3DRMObject *)pFrameC, "Frame");
1110 test_object_name((IDirect3DRMObject *)pFrameC);
1112 hr = IDirect3DRMFrame_GetParent(pFrameC, NULL);
1113 ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE, hr %#lx\n", hr);
1114 pFrameTmp = (void*)0xdeadbeef;
1115 hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
1116 ok(hr == D3DRM_OK, "Cannot get parent frame, hr %#lx\n", hr);
1117 ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1118 CHECK_REFCOUNT(pFrameC, 1);
1120 frame_array = NULL;
1121 hr = IDirect3DRMFrame_GetChildren(pFrameC, &frame_array);
1122 ok(hr == D3DRM_OK, "Cannot get children, hr %#lx\n", hr);
1123 ok(!!frame_array, "frame_array = %p\n", frame_array);
1124 if (frame_array)
1126 count = IDirect3DRMFrameArray_GetSize(frame_array);
1127 ok(count == 0, "count = %lu\n", count);
1128 hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1129 ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE, hr %#lx\n", hr);
1130 ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1131 IDirect3DRMFrameArray_Release(frame_array);
1134 hr = IDirect3DRM_CreateFrame(d3drm, NULL, &pFrameP1);
1135 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface, hr %#lx\n", hr);
1137 /* GetParent with NULL pointer */
1138 hr = IDirect3DRMFrame_GetParent(pFrameP1, NULL);
1139 ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE, hr %#lx\n", hr);
1140 CHECK_REFCOUNT(pFrameP1, 1);
1142 /* [Add/Delete]Child with NULL pointer */
1143 hr = IDirect3DRMFrame_AddChild(pFrameP1, NULL);
1144 ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT, hr %#lx\n", hr);
1145 CHECK_REFCOUNT(pFrameP1, 1);
1147 hr = IDirect3DRMFrame_DeleteChild(pFrameP1, NULL);
1148 ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT, hr %#lx\n", hr);
1149 CHECK_REFCOUNT(pFrameP1, 1);
1151 /* Add child to first parent */
1152 pFrameTmp = (void*)0xdeadbeef;
1153 hr = IDirect3DRMFrame_GetParent(pFrameP1, &pFrameTmp);
1154 ok(hr == D3DRM_OK, "Cannot get parent frame, hr %#lx\n", hr);
1155 ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1157 hr = IDirect3DRMFrame_AddChild(pFrameP1, pFrameC);
1158 ok(hr == D3DRM_OK, "Cannot add child frame, hr %#lx\n", hr);
1159 CHECK_REFCOUNT(pFrameP1, 1);
1160 CHECK_REFCOUNT(pFrameC, 2);
1162 hr = IDirect3DRMFrame_GetScene(pFrameC, NULL);
1163 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
1164 hr = IDirect3DRMFrame_GetScene(pFrameC, &scene_frame);
1165 ok(SUCCEEDED(hr), "Cannot get scene, hr %#lx.\n", hr);
1166 ok(scene_frame == pFrameP1, "Expected scene frame == %p, got %p.\n", pFrameP1, scene_frame);
1167 CHECK_REFCOUNT(pFrameP1, 2);
1168 IDirect3DRMFrame_Release(scene_frame);
1169 hr = IDirect3DRMFrame_GetScene(pFrameP1, &scene_frame);
1170 ok(SUCCEEDED(hr), "Cannot get scene, hr %#lx.\n", hr);
1171 ok(scene_frame == pFrameP1, "Expected scene frame == %p, got %p.\n", pFrameP1, scene_frame);
1172 CHECK_REFCOUNT(pFrameP1, 2);
1173 IDirect3DRMFrame_Release(scene_frame);
1175 frame_array = NULL;
1176 hr = IDirect3DRMFrame_GetChildren(pFrameP1, &frame_array);
1177 ok(hr == D3DRM_OK, "Cannot get children, hr %#lx\n", hr);
1178 /* In some older version of d3drm, creating IDirect3DRMFrameArray object with GetChildren does not increment refcount of children frames */
1179 ok((get_refcount((IUnknown*)pFrameC) == 3) || broken(get_refcount((IUnknown*)pFrameC) == 2),
1180 "Invalid refcount. Expected 3 (or 2) got %ld\n", get_refcount((IUnknown*)pFrameC));
1181 if (frame_array)
1183 count = IDirect3DRMFrameArray_GetSize(frame_array);
1184 ok(count == 1, "count = %lu\n", count);
1185 hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1186 ok(hr == D3DRM_OK, "Cannot get element, hr %#lx\n", hr);
1187 ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
1188 ok((get_refcount((IUnknown*)pFrameC) == 4) || broken(get_refcount((IUnknown*)pFrameC) == 3),
1189 "Invalid refcount. Expected 4 (or 3) got %ld\n", get_refcount((IUnknown*)pFrameC));
1190 IDirect3DRMFrame_Release(pFrameTmp);
1191 ok((get_refcount((IUnknown*)pFrameC) == 3) || broken(get_refcount((IUnknown*)pFrameC) == 2),
1192 "Invalid refcount. Expected 3 (or 2) got %ld\n", get_refcount((IUnknown*)pFrameC));
1193 IDirect3DRMFrameArray_Release(frame_array);
1194 CHECK_REFCOUNT(pFrameC, 2);
1197 pFrameTmp = (void*)0xdeadbeef;
1198 hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
1199 ok(hr == D3DRM_OK, "Cannot get parent frame, hr %#lx\n", hr);
1200 ok(pFrameTmp == pFrameP1, "pFrameTmp = %p\n", pFrameTmp);
1201 CHECK_REFCOUNT(pFrameP1, 2);
1202 IDirect3DRMFrame_Release(pFrameTmp);
1203 CHECK_REFCOUNT(pFrameP1, 1);
1205 /* Add child to second parent */
1206 hr = IDirect3DRM_CreateFrame(d3drm, NULL, &pFrameP2);
1207 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface, hr %#lx\n", hr);
1209 hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameC);
1210 ok(hr == D3DRM_OK, "Cannot add child frame, hr %#lx\n", hr);
1211 CHECK_REFCOUNT(pFrameC, 2);
1213 frame_array = NULL;
1214 hr = IDirect3DRMFrame_GetChildren(pFrameP2, &frame_array);
1215 ok(hr == D3DRM_OK, "Cannot get children, hr %#lx\n", hr);
1216 if (frame_array)
1218 count = IDirect3DRMFrameArray_GetSize(frame_array);
1219 ok(count == 1, "count = %lu\n", count);
1220 hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1221 ok(hr == D3DRM_OK, "Cannot get element, hr %#lx\n", hr);
1222 ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
1223 IDirect3DRMFrame_Release(pFrameTmp);
1224 IDirect3DRMFrameArray_Release(frame_array);
1227 frame_array = NULL;
1228 hr = IDirect3DRMFrame_GetChildren(pFrameP1, &frame_array);
1229 ok(hr == D3DRM_OK, "Cannot get children, hr %#lx\n", hr);
1230 if (frame_array)
1232 count = IDirect3DRMFrameArray_GetSize(frame_array);
1233 ok(count == 0, "count = %lu\n", count);
1234 pFrameTmp = (void*)0xdeadbeef;
1235 hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1236 ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE, hr %#lx\n", hr);
1237 ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1238 IDirect3DRMFrameArray_Release(frame_array);
1240 hr = IDirect3DRMFrame_GetScene(pFrameC, &scene_frame);
1241 ok(SUCCEEDED(hr), "Cannot get scene, hr %#lx.\n", hr);
1242 ok(scene_frame == pFrameP2, "Expected scene frame == %p, got %p.\n", pFrameP2, scene_frame);
1243 CHECK_REFCOUNT(pFrameP2, 2);
1244 IDirect3DRMFrame_Release(scene_frame);
1245 hr = IDirect3DRMFrame_GetScene(pFrameP2, &scene_frame);
1246 ok(SUCCEEDED(hr), "Cannot get scene, hr %#lx.\n", hr);
1247 ok(scene_frame == pFrameP2, "Expected scene frame == %p, got %p.\n", pFrameP2, scene_frame);
1248 CHECK_REFCOUNT(pFrameP2, 2);
1249 IDirect3DRMFrame_Release(scene_frame);
1251 pFrameTmp = (void*)0xdeadbeef;
1252 hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
1253 ok(hr == D3DRM_OK, "Cannot get parent frame, hr %#lx\n", hr);
1254 ok(pFrameTmp == pFrameP2, "pFrameTmp = %p\n", pFrameTmp);
1255 CHECK_REFCOUNT(pFrameP2, 2);
1256 CHECK_REFCOUNT(pFrameC, 2);
1257 IDirect3DRMFrame_Release(pFrameTmp);
1258 CHECK_REFCOUNT(pFrameP2, 1);
1260 /* Add child again */
1261 hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameC);
1262 ok(hr == D3DRM_OK, "Cannot add child frame, hr %#lx\n", hr);
1263 CHECK_REFCOUNT(pFrameC, 2);
1265 frame_array = NULL;
1266 hr = IDirect3DRMFrame_GetChildren(pFrameP2, &frame_array);
1267 ok(hr == D3DRM_OK, "Cannot get children, hr %#lx\n", hr);
1268 if (frame_array)
1270 count = IDirect3DRMFrameArray_GetSize(frame_array);
1271 ok(count == 1, "count = %lu\n", count);
1272 hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1273 ok(hr == D3DRM_OK, "Cannot get element, hr %#lx\n", hr);
1274 ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
1275 IDirect3DRMFrame_Release(pFrameTmp);
1276 IDirect3DRMFrameArray_Release(frame_array);
1279 /* Delete child */
1280 hr = IDirect3DRMFrame_DeleteChild(pFrameP2, pFrameC);
1281 ok(hr == D3DRM_OK, "Cannot delete child frame, hr %#lx\n", hr);
1282 CHECK_REFCOUNT(pFrameC, 1);
1284 frame_array = NULL;
1285 hr = IDirect3DRMFrame_GetChildren(pFrameP2, &frame_array);
1286 ok(hr == D3DRM_OK, "Cannot get children, hr %#lx\n", hr);
1287 if (frame_array)
1289 count = IDirect3DRMFrameArray_GetSize(frame_array);
1290 ok(count == 0, "count = %lu\n", count);
1291 pFrameTmp = (void*)0xdeadbeef;
1292 hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1293 ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE, hr %#lx\n", hr);
1294 ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1295 IDirect3DRMFrameArray_Release(frame_array);
1298 pFrameTmp = (void*)0xdeadbeef;
1299 hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
1300 ok(hr == D3DRM_OK, "Cannot get parent frame, hr %#lx\n", hr);
1301 ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
1303 /* Add two children */
1304 hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameC);
1305 ok(hr == D3DRM_OK, "Cannot add child frame, hr %#lx\n", hr);
1306 CHECK_REFCOUNT(pFrameC, 2);
1308 hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameP1);
1309 ok(hr == D3DRM_OK, "Cannot add child frame, hr %#lx\n", hr);
1310 CHECK_REFCOUNT(pFrameP1, 2);
1312 frame_array = NULL;
1313 hr = IDirect3DRMFrame_GetChildren(pFrameP2, &frame_array);
1314 ok(hr == D3DRM_OK, "Cannot get children, hr %#lx\n", hr);
1315 if (frame_array)
1317 count = IDirect3DRMFrameArray_GetSize(frame_array);
1318 ok(count == 2, "count = %lu\n", count);
1319 hr = IDirect3DRMFrameArray_GetElement(frame_array, 0, &pFrameTmp);
1320 ok(hr == D3DRM_OK, "Cannot get element, hr %#lx\n", hr);
1321 ok(pFrameTmp == pFrameC, "pFrameTmp = %p\n", pFrameTmp);
1322 IDirect3DRMFrame_Release(pFrameTmp);
1323 hr = IDirect3DRMFrameArray_GetElement(frame_array, 1, &pFrameTmp);
1324 ok(hr == D3DRM_OK, "Cannot get element, hr %#lx\n", hr);
1325 ok(pFrameTmp == pFrameP1, "pFrameTmp = %p\n", pFrameTmp);
1326 IDirect3DRMFrame_Release(pFrameTmp);
1327 IDirect3DRMFrameArray_Release(frame_array);
1330 /* [Add/Delete]Visual with NULL pointer */
1331 hr = IDirect3DRMFrame_AddVisual(pFrameP1, NULL);
1332 ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT, hr %#lx\n", hr);
1333 CHECK_REFCOUNT(pFrameP1, 2);
1335 hr = IDirect3DRMFrame_DeleteVisual(pFrameP1, NULL);
1336 ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT, hr %#lx\n", hr);
1337 CHECK_REFCOUNT(pFrameP1, 2);
1339 /* Create Visual */
1340 hr = IDirect3DRM_CreateMeshBuilder(d3drm, &mesh_builder);
1341 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMeshBuilder interface, hr %#lx\n", hr);
1342 visual1 = (IDirect3DRMVisual *)mesh_builder;
1344 /* Add Visual to first parent */
1345 hr = IDirect3DRMFrame_AddVisual(pFrameP1, visual1);
1346 ok(hr == D3DRM_OK, "Cannot add visual, hr %#lx\n", hr);
1347 CHECK_REFCOUNT(pFrameP1, 2);
1348 CHECK_REFCOUNT(visual1, 2);
1350 visual_array = NULL;
1351 hr = IDirect3DRMFrame_GetVisuals(pFrameP1, &visual_array);
1352 ok(hr == D3DRM_OK, "Cannot get visuals, hr %#lx\n", hr);
1353 if (visual_array)
1355 count = IDirect3DRMVisualArray_GetSize(visual_array);
1356 ok(count == 1, "count = %lu\n", count);
1357 hr = IDirect3DRMVisualArray_GetElement(visual_array, 0, &visual_tmp);
1358 ok(hr == D3DRM_OK, "Cannot get element, hr %#lx\n", hr);
1359 ok(visual_tmp == visual1, "visual_tmp = %p\n", visual_tmp);
1360 IDirect3DRMVisual_Release(visual_tmp);
1361 IDirect3DRMVisualArray_Release(visual_array);
1364 /* Delete Visual */
1365 hr = IDirect3DRMFrame_DeleteVisual(pFrameP1, visual1);
1366 ok(hr == D3DRM_OK, "Cannot delete visual, hr %#lx\n", hr);
1367 CHECK_REFCOUNT(pFrameP1, 2);
1368 IDirect3DRMMeshBuilder_Release(mesh_builder);
1370 /* [Add/Delete]Light with NULL pointer */
1371 hr = IDirect3DRMFrame_AddLight(pFrameP1, NULL);
1372 ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT, hr %#lx\n", hr);
1373 CHECK_REFCOUNT(pFrameP1, 2);
1375 hr = IDirect3DRMFrame_DeleteLight(pFrameP1, NULL);
1376 ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT, hr %#lx\n", hr);
1377 CHECK_REFCOUNT(pFrameP1, 2);
1379 /* Create Light */
1380 hr = IDirect3DRM_CreateLightRGB(d3drm, D3DRMLIGHT_SPOT, 0.1, 0.2, 0.3, &light1);
1381 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMLight interface, hr %#lx\n", hr);
1383 /* Add Light to first parent */
1384 hr = IDirect3DRMFrame_AddLight(pFrameP1, light1);
1385 ok(hr == D3DRM_OK, "Cannot add light, hr %#lx\n", hr);
1386 CHECK_REFCOUNT(pFrameP1, 2);
1387 CHECK_REFCOUNT(light1, 2);
1389 light_array = NULL;
1390 hr = IDirect3DRMFrame_GetLights(pFrameP1, &light_array);
1391 ok(hr == D3DRM_OK, "Cannot get lights, hr %#lx\n", hr);
1392 if (light_array)
1394 count = IDirect3DRMLightArray_GetSize(light_array);
1395 ok(count == 1, "count = %lu\n", count);
1396 hr = IDirect3DRMLightArray_GetElement(light_array, 0, &light_tmp);
1397 ok(hr == D3DRM_OK, "Cannot get element, hr %#lx\n", hr);
1398 ok(light_tmp == light1, "light_tmp = %p\n", light_tmp);
1399 IDirect3DRMLight_Release(light_tmp);
1400 IDirect3DRMLightArray_Release(light_array);
1403 /* Delete Light */
1404 hr = IDirect3DRMFrame_DeleteLight(pFrameP1, light1);
1405 ok(hr == D3DRM_OK, "Cannot delete light, hr %#lx\n", hr);
1406 CHECK_REFCOUNT(pFrameP1, 2);
1407 IDirect3DRMLight_Release(light1);
1409 /* Test SceneBackground on first parent */
1410 color = IDirect3DRMFrame_GetSceneBackground(pFrameP1);
1411 ok(color == 0xff000000, "wrong color %lx.\n", color);
1413 hr = IDirect3DRMFrame_SetSceneBackground(pFrameP1, 0xff180587);
1414 ok(hr == D3DRM_OK, "Cannot set color, hr %#lx\n", hr);
1415 color = IDirect3DRMFrame_GetSceneBackground(pFrameP1);
1416 ok(color == 0xff180587, "wrong color %lx.\n", color);
1418 hr = IDirect3DRMFrame_SetSceneBackgroundRGB(pFrameP1, 0.5, 0.5, 0.5);
1419 ok(hr == D3DRM_OK, "Cannot set color, hr %#lx\n", hr);
1420 color = IDirect3DRMFrame_GetSceneBackground(pFrameP1);
1421 ok(color == 0xff7f7f7f, "wrong color %lx.\n", color);
1423 /* Traversal options. */
1424 hr = IDirect3DRMFrame_QueryInterface(pFrameP2, &IID_IDirect3DRMFrame3, (void **)&frame3);
1425 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMFrame3 interface, hr %#lx.\n", hr);
1427 hr = IDirect3DRMFrame3_GetTraversalOptions(frame3, NULL);
1428 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
1430 options = 0;
1431 hr = IDirect3DRMFrame3_GetTraversalOptions(frame3, &options);
1432 ok(SUCCEEDED(hr), "Failed to get traversal options, hr %#lx.\n", hr);
1433 ok(options == (D3DRMFRAME_RENDERENABLE | D3DRMFRAME_PICKENABLE), "Unexpected default options %#lx.\n", options);
1435 hr = IDirect3DRMFrame3_SetTraversalOptions(frame3, 0);
1436 ok(SUCCEEDED(hr), "Unexpected hr %#lx.\n", hr);
1438 hr = IDirect3DRMFrame3_SetTraversalOptions(frame3, 0xf0000000);
1439 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
1441 hr = IDirect3DRMFrame3_SetTraversalOptions(frame3, 0xf0000000 | D3DRMFRAME_PICKENABLE);
1442 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
1444 options = 0xf;
1445 hr = IDirect3DRMFrame3_GetTraversalOptions(frame3, &options);
1446 ok(SUCCEEDED(hr), "Failed to get traversal options, hr %#lx.\n", hr);
1447 ok(options == 0, "Unexpected traversal options %#lx.\n", options);
1449 hr = IDirect3DRMFrame3_SetTraversalOptions(frame3, D3DRMFRAME_PICKENABLE);
1450 ok(SUCCEEDED(hr), "Failed to set traversal options, hr %#lx.\n", hr);
1452 options = 0;
1453 hr = IDirect3DRMFrame3_GetTraversalOptions(frame3, &options);
1454 ok(SUCCEEDED(hr), "Failed to get traversal options, hr %#lx.\n", hr);
1455 ok(options == D3DRMFRAME_PICKENABLE, "Unexpected traversal options %#lx.\n", options);
1457 IDirect3DRMFrame3_Release(frame3);
1459 /* Cleanup */
1460 IDirect3DRMFrame_Release(pFrameP2);
1461 CHECK_REFCOUNT(pFrameC, 1);
1462 CHECK_REFCOUNT(pFrameP1, 1);
1464 IDirect3DRMFrame_Release(pFrameC);
1465 IDirect3DRMFrame_Release(pFrameP1);
1467 IDirect3DRM_Release(d3drm);
1470 struct destroy_context
1472 IDirect3DRMObject *obj;
1473 unsigned int test_idx;
1474 int called;
1477 struct callback_order
1479 void *callback;
1480 void *context;
1481 } corder[3], d3drm_corder[3];
1483 static void CDECL destroy_callback(IDirect3DRMObject *obj, void *arg)
1485 struct destroy_context *ctxt = arg;
1486 ok(ctxt->called == 1 || ctxt->called == 2, "got called counter %d\n", ctxt->called);
1487 ok(obj == ctxt->obj, "called with %p, expected %p\n", obj, ctxt->obj);
1488 d3drm_corder[ctxt->called].callback = &destroy_callback;
1489 d3drm_corder[ctxt->called++].context = ctxt;
1492 static void CDECL destroy_callback1(IDirect3DRMObject *obj, void *arg)
1494 struct destroy_context *ctxt = (struct destroy_context*)arg;
1495 ok(ctxt->called == 0, "got called counter %d\n", ctxt->called);
1496 ok(obj == ctxt->obj, "called with %p, expected %p\n", obj, ctxt->obj);
1497 d3drm_corder[ctxt->called].callback = &destroy_callback1;
1498 d3drm_corder[ctxt->called++].context = ctxt;
1501 static void test_destroy_callback(unsigned int test_idx, REFCLSID clsid, REFIID iid)
1503 struct destroy_context context;
1504 IDirect3DRMObject *obj;
1505 IUnknown *unknown;
1506 IDirect3DRM *d3drm;
1507 HRESULT hr;
1508 int i;
1510 hr = Direct3DRMCreate(&d3drm);
1511 ok(SUCCEEDED(hr), "Test %u: Cannot get IDirect3DRM interface, hr %#lx.\n", test_idx, hr);
1513 hr = IDirect3DRM_CreateObject(d3drm, clsid, NULL, iid, (void **)&unknown);
1514 ok(hr == D3DRM_OK, "Test %u: Cannot get IDirect3DRMObject interface, hr %#lx.\n", test_idx, hr);
1515 hr = IUnknown_QueryInterface(unknown, &IID_IDirect3DRMObject, (void**)&obj);
1516 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK, hr %#lx.\n", test_idx, hr);
1517 IUnknown_Release(unknown);
1519 context.called = 0;
1520 context.test_idx = test_idx;
1521 context.obj = obj;
1523 hr = IDirect3DRMObject_AddDestroyCallback(obj, NULL, &context);
1524 ok(hr == D3DRMERR_BADVALUE, "Test %u: expected D3DRMERR_BADVALUE, hr %#lx.\n", test_idx, hr);
1526 hr = IDirect3DRMObject_AddDestroyCallback(obj, destroy_callback, &context);
1527 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK, hr %#lx.\n", test_idx, hr);
1528 corder[2].callback = &destroy_callback;
1529 corder[2].context = &context;
1531 /* same callback added twice */
1532 hr = IDirect3DRMObject_AddDestroyCallback(obj, destroy_callback, &context);
1533 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK, hr %#lx.\n", test_idx, hr);
1534 corder[1].callback = &destroy_callback;
1535 corder[1].context = &context;
1537 hr = IDirect3DRMObject_DeleteDestroyCallback(obj, destroy_callback1, NULL);
1538 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK, hr %#lx.\n", test_idx, hr);
1540 hr = IDirect3DRMObject_DeleteDestroyCallback(obj, destroy_callback1, &context);
1541 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK, hr %#lx.\n", test_idx, hr);
1543 /* add one more */
1544 hr = IDirect3DRMObject_AddDestroyCallback(obj, destroy_callback1, &context);
1545 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK, hr %#lx.\n", test_idx, hr);
1546 corder[0].callback = &destroy_callback1;
1547 corder[0].context = &context;
1549 hr = IDirect3DRMObject_DeleteDestroyCallback(obj, NULL, NULL);
1550 ok(hr == D3DRMERR_BADVALUE, "Test %u: expected D3DRM_BADVALUE, hr %#lx.\n", test_idx, hr);
1552 context.called = 0;
1553 IDirect3DRMObject_Release(obj);
1554 ok(context.called == 3, "Test %u: got %d, expected 3.\n", test_idx, context.called);
1555 for (i = 0; i < context.called; i++)
1557 ok(corder[i].callback == d3drm_corder[i].callback
1558 && corder[i].context == d3drm_corder[i].context,
1559 "Expected callback = %p, context = %p. Got callback = %p, context = %p.\n", d3drm_corder[i].callback,
1560 d3drm_corder[i].context, corder[i].callback, corder[i].context);
1563 /* test this pattern - add cb1, add cb2, add cb1, delete cb1 */
1564 hr = IDirect3DRM_CreateObject(d3drm, clsid, NULL, iid, (void **)&unknown);
1565 ok(hr == D3DRM_OK, "Test %u: Cannot get IDirect3DRMObject interface, hr %#lx.\n", test_idx, hr);
1566 hr = IUnknown_QueryInterface(unknown, &IID_IDirect3DRMObject, (void**)&obj);
1567 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK, hr %#lx.\n", test_idx, hr);
1568 IUnknown_Release(unknown);
1570 hr = IDirect3DRMObject_AddDestroyCallback(obj, destroy_callback, &context);
1571 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK, hr %#lx.\n", test_idx, hr);
1572 corder[1].callback = &destroy_callback;
1573 corder[1].context = &context;
1575 hr = IDirect3DRMObject_AddDestroyCallback(obj, destroy_callback1, &context);
1576 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK, hr %#lx.\n", test_idx, hr);
1577 corder[0].callback = &destroy_callback1;
1578 corder[0].context = &context;
1580 hr = IDirect3DRMObject_AddDestroyCallback(obj, destroy_callback, &context);
1581 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK, hr %#lx.\n", test_idx, hr);
1583 hr = IDirect3DRMObject_DeleteDestroyCallback(obj, destroy_callback, &context);
1584 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK, hr %#lx.\n", test_idx, hr);
1586 context.called = 0;
1587 hr = IDirect3DRMObject_QueryInterface(obj, &IID_IDirect3DRMObject, (void**)&context.obj);
1588 ok(hr == D3DRM_OK, "Test %u: expected D3DRM_OK, hr %#lx.\n", test_idx, hr);
1589 IDirect3DRMObject_Release(context.obj);
1590 IUnknown_Release(unknown);
1591 ok(context.called == 2, "Test %u: got %d, expected 2.\n", test_idx, context.called);
1592 for (i = 0; i < context.called; i++)
1594 ok(corder[i].callback == d3drm_corder[i].callback
1595 && corder[i].context == d3drm_corder[i].context,
1596 "Expected callback = %p, context = %p. Got callback = %p, context = %p.\n", d3drm_corder[i].callback,
1597 d3drm_corder[i].context, corder[i].callback, corder[i].context);
1600 IDirect3DRM_Release(d3drm);
1603 static void test_object(void)
1605 static const struct
1607 REFCLSID clsid;
1608 REFIID iid;
1609 BOOL takes_d3drm_ref;
1611 tests[] =
1613 { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMDevice },
1614 { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMDevice2 },
1615 { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMDevice3 },
1616 { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMWinDevice },
1617 { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture },
1618 { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture2 },
1619 { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture3 },
1620 { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport },
1621 { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport2 },
1622 { &CLSID_CDirect3DRMFace, &IID_IDirect3DRMFace },
1623 { &CLSID_CDirect3DRMFace, &IID_IDirect3DRMFace2 },
1624 { &CLSID_CDirect3DRMMeshBuilder, &IID_IDirect3DRMMeshBuilder, TRUE },
1625 { &CLSID_CDirect3DRMMeshBuilder, &IID_IDirect3DRMMeshBuilder2, TRUE },
1626 { &CLSID_CDirect3DRMMeshBuilder, &IID_IDirect3DRMMeshBuilder3, TRUE },
1627 { &CLSID_CDirect3DRMFrame, &IID_IDirect3DRMFrame, TRUE },
1628 { &CLSID_CDirect3DRMFrame, &IID_IDirect3DRMFrame2, TRUE },
1629 { &CLSID_CDirect3DRMFrame, &IID_IDirect3DRMFrame3, TRUE },
1630 { &CLSID_CDirect3DRMLight, &IID_IDirect3DRMLight, TRUE },
1631 { &CLSID_CDirect3DRMMaterial, &IID_IDirect3DRMMaterial, TRUE },
1632 { &CLSID_CDirect3DRMMaterial, &IID_IDirect3DRMMaterial2, TRUE },
1633 { &CLSID_CDirect3DRMMesh, &IID_IDirect3DRMMesh, TRUE },
1634 { &CLSID_CDirect3DRMAnimation, &IID_IDirect3DRMAnimation, TRUE },
1635 { &CLSID_CDirect3DRMAnimation, &IID_IDirect3DRMAnimation2, TRUE },
1636 { &CLSID_CDirect3DRMWrap, &IID_IDirect3DRMWrap },
1638 IDirect3DRM *d3drm1;
1639 IDirect3DRM2 *d3drm2;
1640 IDirect3DRM3 *d3drm3;
1641 IUnknown *unknown = (IUnknown *)0xdeadbeef;
1642 HRESULT hr;
1643 ULONG ref1, ref2, ref3, ref4;
1644 int i;
1646 hr = Direct3DRMCreate(&d3drm1);
1647 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
1648 ref1 = get_refcount((IUnknown *)d3drm1);
1649 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
1650 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface, hr %#lx.\n", hr);
1651 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
1652 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr);
1654 hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_DirectDraw, NULL, &IID_IDirectDraw, (void **)&unknown);
1655 ok(hr == CLASSFACTORY_E_FIRST, "Expected hr == CLASSFACTORY_E_FIRST, got %#lx.\n", hr);
1656 ok(!unknown, "Expected object returned == NULL, got %p.\n", unknown);
1658 for (i = 0; i < ARRAY_SIZE(tests); ++i)
1660 winetest_push_context("Test %u", i);
1662 unknown = (IUnknown *)0xdeadbeef;
1663 hr = IDirect3DRM_CreateObject(d3drm1, NULL, NULL, tests[i].iid, (void **)&unknown);
1664 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
1665 ok(!unknown, "Expected object returned == NULL, got %p.\n", unknown);
1666 unknown = (IUnknown *)0xdeadbeef;
1667 hr = IDirect3DRM_CreateObject(d3drm1, tests[i].clsid, NULL, NULL, (void **)&unknown);
1668 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
1669 ok(!unknown, "Expected object returned == NULL, got %p.\n", unknown);
1670 hr = IDirect3DRM_CreateObject(d3drm1, tests[i].clsid, NULL, NULL, NULL);
1671 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
1673 hr = IDirect3DRM_CreateObject(d3drm1, tests[i].clsid, NULL, tests[i].iid, (void **)&unknown);
1674 ok(SUCCEEDED(hr), "Unexpected hr %#lx.\n", hr);
1675 if (SUCCEEDED(hr))
1677 ref2 = get_refcount((IUnknown *)d3drm1);
1678 if (tests[i].takes_d3drm_ref)
1679 ok(ref2 > ref1, "Unexpected ref2 > ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
1680 else
1681 ok(ref2 == ref1, "Unexpected ref2 == ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
1683 ref3 = get_refcount((IUnknown *)d3drm2);
1684 ok(ref3 == ref1, "Unexpected ref3 == ref1, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
1685 ref4 = get_refcount((IUnknown *)d3drm3);
1686 ok(ref4 == ref1, "Unexpected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
1687 IUnknown_Release(unknown);
1688 ref2 = get_refcount((IUnknown *)d3drm1);
1689 ok(ref2 == ref1, "Unexpected ref2 == ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
1690 ref3 = get_refcount((IUnknown *)d3drm2);
1691 ok(ref3 == ref1, "Unexpected ref3 == ref1, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
1692 ref4 = get_refcount((IUnknown *)d3drm3);
1693 ok(ref4 == ref1, "Unexpected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
1695 /* test Add/Destroy callbacks */
1696 test_destroy_callback(i, tests[i].clsid, tests[i].iid);
1698 hr = IDirect3DRM2_CreateObject(d3drm2, tests[i].clsid, NULL, tests[i].iid, (void **)&unknown);
1699 ok(SUCCEEDED(hr), "Unexpected hr %#lx.\n", hr);
1700 ref2 = get_refcount((IUnknown *)d3drm1);
1701 if (tests[i].takes_d3drm_ref)
1702 ok(ref2 > ref1, "Unexpected ref2 > ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
1703 else
1704 ok(ref2 == ref1, "Unexpected ref2 == ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
1705 ref3 = get_refcount((IUnknown *)d3drm2);
1706 ok(ref3 == ref1, "Unexpected ref3 == ref1, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
1707 ref4 = get_refcount((IUnknown *)d3drm3);
1708 ok(ref4 == ref1, "Unexpected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
1709 IUnknown_Release(unknown);
1710 ref2 = get_refcount((IUnknown *)d3drm1);
1711 ok(ref2 == ref1, "Unexpected ref2 == ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
1712 ref3 = get_refcount((IUnknown *)d3drm2);
1713 ok(ref3 == ref1, "Unexpected ref3 == ref1, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
1714 ref4 = get_refcount((IUnknown *)d3drm3);
1715 ok(ref4 == ref1, "Unexpected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
1717 hr = IDirect3DRM3_CreateObject(d3drm3, tests[i].clsid, NULL, tests[i].iid, (void **)&unknown);
1718 ok(SUCCEEDED(hr), "Unexpected hr %#lx.\n", hr);
1719 ref2 = get_refcount((IUnknown *)d3drm1);
1720 if (tests[i].takes_d3drm_ref)
1721 ok(ref2 > ref1, "Unexpected ref2 > ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
1722 else
1723 ok(ref2 == ref1, "Unexpected ref2 == ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
1724 ref3 = get_refcount((IUnknown *)d3drm2);
1725 ok(ref3 == ref1, "Unexpected ref3 == ref1, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
1726 ref4 = get_refcount((IUnknown *)d3drm3);
1727 ok(ref4 == ref1, "Unexpected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
1728 IUnknown_Release(unknown);
1729 ref2 = get_refcount((IUnknown *)d3drm1);
1730 ok(ref2 == ref1, "Unexpected ref2 == ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
1731 ref3 = get_refcount((IUnknown *)d3drm2);
1732 ok(ref3 == ref1, "Unexpected ref3 == ref1, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
1733 ref4 = get_refcount((IUnknown *)d3drm3);
1734 ok(ref4 == ref1, "Unexpected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
1737 winetest_pop_context();
1740 IDirect3DRM_Release(d3drm1);
1741 IDirect3DRM2_Release(d3drm2);
1742 IDirect3DRM3_Release(d3drm3);
1745 static void test_Viewport(void)
1747 IDirect3DRMFrame3 *frame3, *d3drm_frame3, *tmp_frame3;
1748 IDirect3DRMFrame *frame, *d3drm_frame, *tmp_frame1;
1749 float field, left, top, right, bottom, front, back;
1750 D3DRMPROJECTIONTYPE projection;
1751 IDirectDrawClipper *clipper;
1752 HRESULT hr;
1753 IDirect3DRM *d3drm1;
1754 IDirect3DRM2 *d3drm2;
1755 IDirect3DRM3 *d3drm3;
1756 IDirect3DRMDevice *device1, *d3drm_device1;
1757 IDirect3DRMDevice3 *device3, *d3drm_device3;
1758 IDirect3DRMViewport *viewport;
1759 IDirect3DRMViewport2 *viewport2;
1760 IDirect3DViewport *d3d_viewport;
1761 D3DVIEWPORT vp;
1762 D3DVALUE expected_val;
1763 IDirect3DRMObject *obj, *obj2;
1764 GUID driver;
1765 HWND window;
1766 RECT rc;
1767 DWORD data, ref1, ref2, ref3, ref4;
1768 DWORD initial_ref1, initial_ref2, initial_ref3, device_ref, frame_ref, frame_ref2, viewport_ref;
1770 window = create_window();
1771 GetClientRect(window, &rc);
1773 hr = Direct3DRMCreate(&d3drm1);
1774 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx\n", hr);
1775 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
1776 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface, hr %#lx.\n", hr);
1777 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
1778 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr);
1779 initial_ref1 = get_refcount((IUnknown *)d3drm1);
1780 initial_ref2 = get_refcount((IUnknown *)d3drm2);
1781 initial_ref3 = get_refcount((IUnknown *)d3drm3);
1783 hr = DirectDrawCreateClipper(0, &clipper, NULL);
1784 ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface, hr %#lx\n", hr);
1786 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
1787 ok(hr == DD_OK, "Cannot set HWnd to Clipper, hr %#lx\n", hr);
1789 memcpy(&driver, &IID_IDirect3DRGBDevice, sizeof(GUID));
1790 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, rc.right, rc.bottom, &device3);
1791 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMDevice interface, hr %#lx\n", hr);
1792 hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice, (void **)&device1);
1793 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface, hr %#lx.\n", hr);
1795 hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &frame);
1796 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface, hr %#lx\n", hr);
1797 hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &tmp_frame1);
1798 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
1799 hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &frame3);
1800 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame3 interface, hr %#lx.\n", hr);
1801 hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &tmp_frame3);
1802 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
1804 ref1 = get_refcount((IUnknown *)d3drm1);
1805 ref2 = get_refcount((IUnknown *)d3drm2);
1806 ref3 = get_refcount((IUnknown *)d3drm3);
1807 device_ref = get_refcount((IUnknown *)device1);
1808 frame_ref = get_refcount((IUnknown *)frame);
1810 hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, 0, 0, 0, 0, &viewport);
1811 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport interface, hr %#lx\n", hr);
1812 ref4 = get_refcount((IUnknown *)d3drm1);
1813 ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
1814 ref4 = get_refcount((IUnknown *)d3drm2);
1815 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %lu, ref4 = %lu.\n", ref2, ref4);
1816 ref4 = get_refcount((IUnknown *)d3drm3);
1817 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %lu, ref4 = %lu.\n", ref3, ref4);
1818 ref4 = get_refcount((IUnknown *)device1);
1819 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %lu, ref4 = %lu.\n", device_ref, ref4);
1820 ref4 = get_refcount((IUnknown *)frame);
1821 ok(ref4 > frame_ref, "Expected ref4 > frame_ref, got frame_ref = %lu, ref4 = %lu.\n", frame_ref, ref4);
1823 hr = IDirect3DRMViewport_GetDevice(viewport, &d3drm_device1);
1824 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface, hr %#lx\n", hr);
1825 ok(device1 == d3drm_device1, "Expected device returned = %p, got %p.\n", device1, d3drm_device1);
1826 IDirect3DRMDevice_Release(d3drm_device1);
1828 hr = IDirect3DRMViewport_SetCamera(viewport, NULL);
1829 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
1830 hr = IDirect3DRMViewport_GetCamera(viewport, &d3drm_frame);
1831 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
1832 ok(frame == d3drm_frame, "Expected frame returned = %p, got %p.\n", frame, d3drm_frame);
1833 IDirect3DRMFrame_Release(d3drm_frame);
1835 hr = IDirect3DRMViewport_SetCamera(viewport, tmp_frame1);
1836 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
1837 hr = IDirect3DRMViewport_GetCamera(viewport, &d3drm_frame);
1838 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
1839 ok(d3drm_frame == tmp_frame1, "Got unexpected frame %p, expected %p.\n", d3drm_frame, tmp_frame1);
1840 IDirect3DRMFrame_Release(d3drm_frame);
1842 IDirect3DRMViewport_Release(viewport);
1843 ref4 = get_refcount((IUnknown *)d3drm1);
1844 ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
1845 ref4 = get_refcount((IUnknown *)d3drm2);
1846 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %lu, ref4 = %lu.\n", ref2, ref4);
1847 ref4 = get_refcount((IUnknown *)d3drm3);
1848 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %lu, ref4 = %lu.\n", ref3, ref4);
1849 ref4 = get_refcount((IUnknown *)device1);
1850 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %lu, ref4 = %lu.\n", device_ref, ref4);
1851 ref4 = get_refcount((IUnknown *)frame);
1852 ok(ref4 == frame_ref, "Expected ref4 == frame_ref, got frame_ref = %lu, ref4 = %lu.\n", frame_ref, ref4);
1854 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, 0, 0, 0, 0, &viewport);
1855 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport interface, hr %#lx\n", hr);
1856 ref4 = get_refcount((IUnknown *)d3drm1);
1857 ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
1858 ref4 = get_refcount((IUnknown *)d3drm2);
1859 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %lu, ref4 = %lu.\n", ref2, ref4);
1860 ref4 = get_refcount((IUnknown *)d3drm3);
1861 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %lu, ref4 = %lu.\n", ref3, ref4);
1862 ref4 = get_refcount((IUnknown *)device1);
1863 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %lu, ref4 = %lu.\n", device_ref, ref4);
1864 ref4 = get_refcount((IUnknown *)frame);
1865 ok(ref4 > frame_ref, "Expected ref4 > frame_ref, got frame_ref = %lu, ref4 = %lu.\n", frame_ref, ref4);
1867 hr = IDirect3DRMViewport_GetDevice(viewport, &d3drm_device1);
1868 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface, hr %#lx\n", hr);
1869 ok(device1 == d3drm_device1, "Expected device returned = %p, got %p.\n", device1, d3drm_device1);
1870 IDirect3DRMDevice_Release(d3drm_device1);
1872 hr = IDirect3DRMViewport_SetCamera(viewport, NULL);
1873 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
1874 hr = IDirect3DRMViewport_GetCamera(viewport, &d3drm_frame);
1875 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
1876 ok(frame == d3drm_frame, "Expected frame returned = %p, got %p.\n", frame, d3drm_frame);
1877 IDirect3DRMFrame_Release(d3drm_frame);
1879 hr = IDirect3DRMViewport_SetCamera(viewport, tmp_frame1);
1880 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
1881 hr = IDirect3DRMViewport_GetCamera(viewport, &d3drm_frame);
1882 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
1883 ok(d3drm_frame == tmp_frame1, "Got unexpected frame %p, expected %p.\n", d3drm_frame, tmp_frame1);
1884 IDirect3DRMFrame_Release(d3drm_frame);
1886 IDirect3DRMViewport_Release(viewport);
1887 ref4 = get_refcount((IUnknown *)d3drm1);
1888 ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
1889 ref4 = get_refcount((IUnknown *)d3drm2);
1890 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %lu, ref4 = %lu.\n", ref2, ref4);
1891 ref4 = get_refcount((IUnknown *)d3drm3);
1892 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %lu, ref4 = %lu.\n", ref3, ref4);
1893 ref4 = get_refcount((IUnknown *)device1);
1894 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %lu, ref4 = %lu.\n", device_ref, ref4);
1895 ref4 = get_refcount((IUnknown *)frame);
1896 ok(ref4 == frame_ref, "Expected ref4 == frame_ref, got frame_ref = %lu, ref4 = %lu.\n", frame_ref, ref4);
1898 device_ref = get_refcount((IUnknown *)device3);
1899 frame_ref2 = get_refcount((IUnknown *)frame3);
1901 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, 0, 0, 0, 0, &viewport2);
1902 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport2 interface, hr %#lx\n", hr);
1903 ref4 = get_refcount((IUnknown *)d3drm1);
1904 ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
1905 ref4 = get_refcount((IUnknown *)d3drm2);
1906 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %lu, ref4 = %lu.\n", ref2, ref4);
1907 ref4 = get_refcount((IUnknown *)d3drm3);
1908 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %lu, ref4 = %lu.\n", ref3, ref4);
1909 ref4 = get_refcount((IUnknown *)device3);
1910 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %lu, ref4 = %lu.\n", device_ref, ref4);
1911 ref4 = get_refcount((IUnknown *)frame3);
1912 ok(ref4 > frame_ref2, "Expected ref4 > frame_ref2, got frame_ref2 = %lu, ref4 = %lu.\n", frame_ref2, ref4);
1914 hr = IDirect3DRMViewport2_GetDevice(viewport2, &d3drm_device3);
1915 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface, hr %#lx\n", hr);
1916 ok(device3 == d3drm_device3, "Expected device returned = %p, got %p.\n", device3, d3drm_device3);
1917 IDirect3DRMDevice3_Release(d3drm_device3);
1919 hr = IDirect3DRMViewport2_SetCamera(viewport2, NULL);
1920 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
1921 hr = IDirect3DRMViewport2_GetCamera(viewport2, &d3drm_frame3);
1922 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
1923 ok(frame3 == d3drm_frame3, "Expected frame returned = %p, got %p.\n", frame3, d3drm_frame3);
1924 IDirect3DRMFrame3_Release(d3drm_frame3);
1926 hr = IDirect3DRMViewport2_SetCamera(viewport2, tmp_frame3);
1927 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
1928 hr = IDirect3DRMViewport2_GetCamera(viewport2, &d3drm_frame3);
1929 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
1930 ok(d3drm_frame3 == tmp_frame3, "Got unexpected frame %p, expected %p.\n", d3drm_frame3, tmp_frame3);
1931 IDirect3DRMFrame3_Release(d3drm_frame3);
1933 IDirect3DRMViewport2_Release(viewport2);
1934 ref4 = get_refcount((IUnknown *)d3drm1);
1935 ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
1936 ref4 = get_refcount((IUnknown *)d3drm2);
1937 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %lu, ref4 = %lu.\n", ref2, ref4);
1938 ref4 = get_refcount((IUnknown *)d3drm3);
1939 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %lu, ref4 = %lu.\n", ref3, ref4);
1940 ref4 = get_refcount((IUnknown *)device3);
1941 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %lu, ref4 = %lu.\n", device_ref, ref4);
1942 ref4 = get_refcount((IUnknown *)frame3);
1943 ok(ref4 == frame_ref2, "Expected ref4 == frame_ref2, got frame_ref2 = %lu, ref4 = %lu.\n", frame_ref2, ref4);
1945 /* Test all failures together */
1946 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1947 hr = IDirect3DRM_CreateViewport(d3drm1, NULL, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1948 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
1949 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1950 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1951 hr = IDirect3DRM_CreateViewport(d3drm1, device1, NULL, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1952 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
1953 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1954 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1955 hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom + 1, &viewport);
1956 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
1957 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1958 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1959 hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom, &viewport);
1960 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
1961 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1962 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1963 hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right, rc.bottom + 1, &viewport);
1964 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
1965 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1966 hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right, rc.bottom, NULL);
1967 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
1969 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1970 hr = IDirect3DRM2_CreateViewport(d3drm2, NULL, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1971 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
1972 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1973 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1974 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, NULL, rc.left, rc.top, rc.right, rc.bottom, &viewport);
1975 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
1976 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1977 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1978 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom + 1, &viewport);
1979 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
1980 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1981 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1982 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom, &viewport);
1983 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
1984 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1985 viewport = (IDirect3DRMViewport *)0xdeadbeef;
1986 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right, rc.bottom + 1, &viewport);
1987 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
1988 ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport);
1989 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right, rc.bottom, NULL);
1990 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
1992 viewport2 = (IDirect3DRMViewport2 *)0xdeadbeef;
1993 hr = IDirect3DRM3_CreateViewport(d3drm3, NULL, frame3, rc.left, rc.top, rc.right, rc.bottom, &viewport2);
1994 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
1995 ok(!viewport2, "Expected viewport returned == NULL, got %p.\n", viewport2);
1996 viewport2 = (IDirect3DRMViewport2 *)0xdeadbeef;
1997 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, NULL, rc.left, rc.top, rc.right, rc.bottom, &viewport2);
1998 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
1999 ok(!viewport2, "Expected viewport returned == NULL, got %p.\n", viewport2);
2000 viewport2 = (IDirect3DRMViewport2 *)0xdeadbeef;
2001 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom + 1, &viewport2);
2002 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2003 ok(!viewport2, "Expected viewport returned == NULL, got %p.\n", viewport2);
2004 viewport2 = (IDirect3DRMViewport2 *)0xdeadbeef;
2005 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom, &viewport2);
2006 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2007 ok(!viewport2, "Expected viewport returned == NULL, got %p.\n", viewport2);
2008 viewport2 = (IDirect3DRMViewport2 *)0xdeadbeef;
2009 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right, rc.bottom + 1, &viewport2);
2010 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2011 ok(!viewport2, "Expected viewport returned == NULL, got %p.\n", viewport2);
2012 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right, rc.bottom, NULL);
2013 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2015 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport);
2016 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMViewport interface, hr %#lx\n", hr);
2017 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2018 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
2019 viewport_ref = get_refcount((IUnknown *)d3d_viewport);
2020 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2021 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
2022 ref4 = get_refcount((IUnknown *)d3d_viewport);
2023 ok(ref4 > viewport_ref, "Expected ref4 > viewport_ref, got ref4 = %lu, viewport_ref = %lu.\n", ref4, viewport_ref);
2024 IDirect3DViewport_Release(d3d_viewport);
2025 ref4 = get_refcount((IUnknown *)d3d_viewport);
2026 ok(ref4 == viewport_ref, "Expected ref4 == viewport_ref, got ref4 = %lu, viewport_ref = %lu.\n", ref4, viewport_ref);
2027 IDirect3DViewport_Release(d3d_viewport);
2029 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2030 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
2031 vp.dwSize = sizeof(vp);
2032 hr = IDirect3DViewport_GetViewport(d3d_viewport, &vp);
2033 ok(SUCCEEDED(hr), "Cannot get D3DVIEWPORT struct, hr %#lx.\n", hr);
2034 ok(vp.dwWidth == rc.right, "Expected viewport width = %lu, got %lu.\n", rc.right, vp.dwWidth);
2035 ok(vp.dwHeight == rc.bottom, "Expected viewport height = %lu, got %lu.\n", rc.bottom, vp.dwHeight);
2036 ok(vp.dwX == rc.left, "Expected viewport X position = %lu, got %lu.\n", rc.left, vp.dwX);
2037 ok(vp.dwY == rc.top, "Expected viewport Y position = %lu, got %lu.\n", rc.top, vp.dwY);
2038 expected_val = (rc.right > rc.bottom) ? (rc.right / 2.0f) : (rc.bottom / 2.0f);
2039 ok(vp.dvScaleX == expected_val, "Expected dvScaleX = %f, got %f.\n", expected_val, vp.dvScaleX);
2040 ok(vp.dvScaleY == expected_val, "Expected dvScaleY = %f, got %f.\n", expected_val, vp.dvScaleY);
2041 expected_val = vp.dwWidth / (2.0f * vp.dvScaleX);
2042 ok(vp.dvMaxX == expected_val, "Expected dvMaxX = %f, got %f.\n", expected_val, vp.dvMaxX);
2043 expected_val = vp.dwHeight / (2.0f * vp.dvScaleY);
2044 ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY);
2045 IDirect3DViewport_Release(d3d_viewport);
2046 IDirect3DRMViewport_Release(viewport);
2048 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right, rc.bottom, &viewport2);
2049 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMViewport2 interface, hr %#lx\n", hr);
2050 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
2051 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
2052 viewport_ref = get_refcount((IUnknown *)d3d_viewport);
2053 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
2054 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
2055 ref4 = get_refcount((IUnknown *)d3d_viewport);
2056 ok(ref4 > viewport_ref, "Expected ref4 > viewport_ref, got ref4 = %lu, viewport_ref = %lu.\n", ref4, viewport_ref);
2057 IDirect3DViewport_Release(d3d_viewport);
2058 ref4 = get_refcount((IUnknown *)d3d_viewport);
2059 ok(ref4 == viewport_ref, "Expected ref4 == viewport_ref, got ref4 = %lu, viewport_ref = %lu.\n", ref4, viewport_ref);
2060 IDirect3DViewport_Release(d3d_viewport);
2062 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
2063 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
2064 vp.dwSize = sizeof(vp);
2065 hr = IDirect3DViewport_GetViewport(d3d_viewport, &vp);
2066 ok(SUCCEEDED(hr), "Cannot get D3DVIEWPORT struct, hr %#lx.\n", hr);
2067 ok(vp.dwWidth == rc.right, "Expected viewport width = %lu, got %lu.\n", rc.right, vp.dwWidth);
2068 ok(vp.dwHeight == rc.bottom, "Expected viewport height = %lu, got %lu.\n", rc.bottom, vp.dwHeight);
2069 ok(vp.dwX == rc.left, "Expected viewport X position = %lu, got %lu.\n", rc.left, vp.dwX);
2070 ok(vp.dwY == rc.top, "Expected viewport Y position = %lu, got %lu.\n", rc.top, vp.dwY);
2071 expected_val = (rc.right > rc.bottom) ? (rc.right / 2.0f) : (rc.bottom / 2.0f);
2072 ok(vp.dvScaleX == expected_val, "Expected dvScaleX = %f, got %f.\n", expected_val, vp.dvScaleX);
2073 ok(vp.dvScaleY == expected_val, "Expected dvScaleY = %f, got %f.\n", expected_val, vp.dvScaleY);
2074 expected_val = vp.dwWidth / (2.0f * vp.dvScaleX);
2075 ok(vp.dvMaxX == expected_val, "Expected dvMaxX = %f, got %f.\n", expected_val, vp.dvMaxX);
2076 expected_val = vp.dwHeight / (2.0f * vp.dvScaleY);
2077 ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY);
2078 IDirect3DViewport_Release(d3d_viewport);
2079 IDirect3DRMViewport2_Release(viewport2);
2081 hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport);
2082 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMViewport interface, hr %#lx\n", hr);
2083 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2084 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
2085 viewport_ref = get_refcount((IUnknown *)d3d_viewport);
2086 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2087 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
2088 ref4 = get_refcount((IUnknown *)d3d_viewport);
2089 ok(ref4 > viewport_ref, "Expected ref4 > viewport_ref, got ref4 = %lu, viewport_ref = %lu.\n", ref4, viewport_ref);
2090 IDirect3DViewport_Release(d3d_viewport);
2091 ref4 = get_refcount((IUnknown *)d3d_viewport);
2092 ok(ref4 == viewport_ref, "Expected ref4 == viewport_ref, got ref4 = %lu, viewport_ref = %lu.\n", ref4, viewport_ref);
2093 IDirect3DViewport_Release(d3d_viewport);
2095 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2096 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
2097 vp.dwSize = sizeof(vp);
2098 hr = IDirect3DViewport_GetViewport(d3d_viewport, &vp);
2099 ok(SUCCEEDED(hr), "Cannot get D3DVIEWPORT struct, hr %#lx.\n", hr);
2100 ok(vp.dwWidth == rc.right, "Expected viewport width = %lu, got %lu.\n", rc.right, vp.dwWidth);
2101 ok(vp.dwHeight == rc.bottom, "Expected viewport height = %lu, got %lu.\n", rc.bottom, vp.dwHeight);
2102 ok(vp.dwX == rc.left, "Expected viewport X position = %lu, got %lu.\n", rc.left, vp.dwX);
2103 ok(vp.dwY == rc.top, "Expected viewport Y position = %lu, got %lu.\n", rc.top, vp.dwY);
2104 expected_val = (rc.right > rc.bottom) ? (rc.right / 2.0f) : (rc.bottom / 2.0f);
2105 ok(vp.dvScaleX == expected_val, "Expected dvScaleX = %f, got %f.\n", expected_val, vp.dvScaleX);
2106 ok(vp.dvScaleY == expected_val, "Expected dvScaleY = %f, got %f.\n", expected_val, vp.dvScaleY);
2107 expected_val = vp.dwWidth / (2.0f * vp.dvScaleX);
2108 ok(vp.dvMaxX == expected_val, "Expected dvMaxX = %f, got %f.\n", expected_val, vp.dvMaxX);
2109 expected_val = vp.dwHeight / (2.0f * vp.dvScaleY);
2110 ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY);
2111 IDirect3DViewport_Release(d3d_viewport);
2113 hr = IDirect3DRMViewport_QueryInterface(viewport, &IID_IDirect3DRMObject, (void**)&obj);
2114 ok(hr == D3DRM_OK, "expected D3DRM_OK, hr %#lx\n", hr);
2115 ok((IDirect3DRMObject*)viewport == obj, "got object pointer %p, expected %p\n", obj, viewport);
2117 hr = IDirect3DRMViewport_QueryInterface(viewport, &IID_IDirect3DRMViewport2, (void**)&viewport2);
2118 ok(hr == D3DRM_OK, "expected D3DRM_OK, hr %#lx\n", hr);
2120 hr = IDirect3DRMViewport2_QueryInterface(viewport2, &IID_IDirect3DRMObject, (void**)&obj2);
2121 ok(hr == D3DRM_OK, "expected D3DRM_OK, hr %#lx\n", hr);
2122 ok(obj == obj2, "got object pointer %p, expected %p\n", obj2, obj);
2123 ok((IUnknown*)viewport != (IUnknown*)viewport2, "got viewport1 %p, viewport2 %p\n", viewport, viewport2);
2125 IDirect3DRMViewport2_Release(viewport2);
2126 IDirect3DRMObject_Release(obj);
2127 IDirect3DRMObject_Release(obj2);
2129 test_class_name((IDirect3DRMObject *)viewport, "Viewport");
2130 test_object_name((IDirect3DRMObject *)viewport);
2132 /* AppData */
2133 hr = IDirect3DRMViewport_SetAppData(viewport, 0);
2134 ok(hr == D3DRM_OK, "expected D3DRM_OK, hr %#lx\n", hr);
2136 hr = IDirect3DRMViewport_SetAppData(viewport, 0);
2137 ok(hr == D3DRM_OK, "expected D3DRM_OK, hr %#lx\n", hr);
2139 hr = IDirect3DRMViewport_SetAppData(viewport, 1);
2140 ok(hr == D3DRM_OK, "expected D3DRM_OK, hr %#lx\n", hr);
2142 hr = IDirect3DRMViewport_SetAppData(viewport, 1);
2143 ok(hr == D3DRM_OK, "expected D3DRM_OK, hr %#lx\n", hr);
2145 hr = IDirect3DRMViewport_QueryInterface(viewport, &IID_IDirect3DRMViewport2, (void**)&viewport2);
2146 ok(hr == D3DRM_OK, "expected D3DRM_OK, hr %#lx\n", hr);
2148 data = IDirect3DRMViewport2_GetAppData(viewport2);
2149 ok(data == 1, "got %lx\n", data);
2150 IDirect3DRMViewport2_Release(viewport2);
2151 IDirect3DRMViewport_Release(viewport);
2153 /* IDirect3DRMViewport*::Init tests */
2154 ref1 = get_refcount((IUnknown *)d3drm1);
2155 ref2 = get_refcount((IUnknown *)d3drm2);
2156 ref3 = get_refcount((IUnknown *)d3drm3);
2157 hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_CDirect3DRMViewport, NULL, &IID_IDirect3DRMViewport,
2158 (void **)&viewport);
2159 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport interface, hr %#lx.\n", hr);
2160 ref4 = get_refcount((IUnknown *)d3drm1);
2161 ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
2162 ref4 = get_refcount((IUnknown *)d3drm2);
2163 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %lu, ref4 = %lu.\n", ref2, ref4);
2164 ref4 = get_refcount((IUnknown *)d3drm3);
2165 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %lu, ref4 = %lu.\n", ref3, ref4);
2167 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2168 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2169 hr = IDirect3DRMViewport_GetDevice(viewport, &d3drm_device1);
2170 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2171 hr = IDirect3DRMViewport_GetCamera(viewport, &d3drm_frame);
2172 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2173 field = IDirect3DRMViewport_GetField(viewport);
2174 ok(field == -1.0f, "Got unexpected field %.8e.\n", field);
2175 left = right = bottom = top = 10.0f;
2176 hr = IDirect3DRMViewport_GetPlane(viewport, &left, &right, &bottom, &top);
2177 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2178 ok(left == 10.0f, "Got unexpected left %.8e.\n", left);
2179 ok(right == 10.0f, "Got unexpected right %.8e.\n", right);
2180 ok(bottom == 10.0f, "Got unexpected bottom %.8e.\n", bottom);
2181 ok(top == 10.0f, "Got unexpected top %.8e.\n", top);
2182 front = IDirect3DRMViewport_GetFront(viewport);
2183 ok(front == -1.0f, "Got unexpected front %.8e\n", front);
2184 back = IDirect3DRMViewport_GetBack(viewport);
2185 ok(back == -1.0f, "Got unexpected back %.8e\n", back);
2186 projection = IDirect3DRMViewport_GetProjection(viewport);
2187 ok(projection == ~0u, "Got unexpected projection type %#x.\n", projection);
2189 hr = IDirect3DRMViewport_SetCamera(viewport, frame);
2190 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2191 hr = IDirect3DRMViewport_SetField(viewport, 0.5f);
2192 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2193 hr = IDirect3DRMViewport_SetPlane(viewport, -0.5f, 0.5f, -0.5f, 0.5f);
2194 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2195 hr = IDirect3DRMViewport_SetFront(viewport, 1.0f);
2196 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2197 hr = IDirect3DRMViewport_SetBack(viewport, 100.0f);
2198 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2199 hr = IDirect3DRMViewport_SetProjection(viewport, D3DRMPROJECT_PERSPECTIVE);
2200 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2202 /* Test all failures together */
2203 hr = IDirect3DRMViewport_Init(viewport, NULL, frame, rc.left, rc.top, rc.right, rc.bottom);
2204 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
2205 hr = IDirect3DRMViewport_Init(viewport, device1, NULL, rc.left, rc.top, rc.right, rc.bottom);
2206 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
2207 hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom + 1);
2208 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
2209 hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom);
2210 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
2211 hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right, rc.bottom + 1);
2212 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
2214 device_ref = get_refcount((IUnknown *)device1);
2215 frame_ref = get_refcount((IUnknown *)frame);
2216 hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right, rc.bottom);
2217 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMViewport interface, hr %#lx.\n", hr);
2218 ref4 = get_refcount((IUnknown *)d3drm1);
2219 ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
2220 ref4 = get_refcount((IUnknown *)d3drm2);
2221 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %lu, ref4 = %lu.\n", ref2, ref4);
2222 ref4 = get_refcount((IUnknown *)d3drm3);
2223 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %lu, ref4 = %lu.\n", ref3, ref4);
2224 ref4 = get_refcount((IUnknown *)device1);
2225 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %lu, ref4 = %lu.\n", device_ref, ref4);
2226 ref4 = get_refcount((IUnknown *)frame);
2227 ok(ref4 > frame_ref, "Expected ref4 > frame_ref, got frame_ref = %lu, ref4 = %lu.\n", frame_ref, ref4);
2229 hr = IDirect3DRMViewport_GetDevice(viewport, &d3drm_device1);
2230 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface, hr %#lx\n", hr);
2231 ok(device1 == d3drm_device1, "Expected device returned = %p, got %p.\n", device3, d3drm_device3);
2232 IDirect3DRMDevice_Release(d3drm_device1);
2234 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2235 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
2236 viewport_ref = get_refcount((IUnknown *)d3d_viewport);
2237 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2238 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
2239 ref4 = get_refcount((IUnknown *)d3d_viewport);
2240 ok(ref4 > viewport_ref, "Expected ref4 > viewport_ref, got ref4 = %lu, viewport_ref = %lu.\n", ref4, viewport_ref);
2241 IDirect3DViewport_Release(d3d_viewport);
2242 ref4 = get_refcount((IUnknown *)d3d_viewport);
2243 ok(ref4 == viewport_ref, "Expected ref4 == viewport_ref, got ref4 = %lu, viewport_ref = %lu.\n", ref4, viewport_ref);
2244 IDirect3DViewport_Release(d3d_viewport);
2246 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, &d3d_viewport);
2247 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
2248 vp.dwSize = sizeof(vp);
2249 hr = IDirect3DViewport_GetViewport(d3d_viewport, &vp);
2250 ok(SUCCEEDED(hr), "Cannot get D3DVIEWPORT struct, hr %#lx.\n", hr);
2251 ok(vp.dwWidth == rc.right, "Expected viewport width = %lu, got %lu.\n", rc.right, vp.dwWidth);
2252 ok(vp.dwHeight == rc.bottom, "Expected viewport height = %lu, got %lu.\n", rc.bottom, vp.dwHeight);
2253 ok(vp.dwX == rc.left, "Expected viewport X position = %lu, got %lu.\n", rc.left, vp.dwX);
2254 ok(vp.dwY == rc.top, "Expected viewport Y position = %lu, got %lu.\n", rc.top, vp.dwY);
2255 expected_val = (rc.right > rc.bottom) ? (rc.right / 2.0f) : (rc.bottom / 2.0f);
2256 ok(vp.dvScaleX == expected_val, "Expected dvScaleX = %f, got %f.\n", expected_val, vp.dvScaleX);
2257 ok(vp.dvScaleY == expected_val, "Expected dvScaleY = %f, got %f.\n", expected_val, vp.dvScaleY);
2258 expected_val = vp.dwWidth / (2.0f * vp.dvScaleX);
2259 ok(vp.dvMaxX == expected_val, "Expected dvMaxX = %f, got %f.\n", expected_val, vp.dvMaxX);
2260 expected_val = vp.dwHeight / (2.0f * vp.dvScaleY);
2261 ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY);
2262 IDirect3DViewport_Release(d3d_viewport);
2264 field = IDirect3DRMViewport_GetField(viewport);
2265 ok(field == 0.5f, "Got unexpected field %.8e.\n", field);
2266 hr = IDirect3DRMViewport_GetPlane(viewport, &left, &right, &bottom, &top);
2267 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2268 ok(left == -0.5f, "Got unexpected left %.8e.\n", left);
2269 ok(right == 0.5f, "Got unexpected right %.8e.\n", right);
2270 ok(bottom == -0.5f, "Got unexpected bottom %.8e.\n", bottom);
2271 ok(top == 0.5f, "Got unexpected top %.8e.\n", top);
2272 front = IDirect3DRMViewport_GetFront(viewport);
2273 ok(front == 1.0f, "Got unexpected front %.8e.\n", front);
2274 back = IDirect3DRMViewport_GetBack(viewport);
2275 ok(back == 100.0f, "Got unexpected back %.8e.\n", back);
2276 projection = IDirect3DRMViewport_GetProjection(viewport);
2277 ok(projection == D3DRMPROJECT_PERSPECTIVE, "Got unexpected projection type %#x.\n", projection);
2279 hr = IDirect3DRMViewport_SetField(viewport, 1.0f);
2280 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2281 field = IDirect3DRMViewport_GetField(viewport);
2282 ok(field == 1.0f, "Got unexpected field %.8e.\n", field);
2283 hr = IDirect3DRMViewport_GetPlane(viewport, &left, &right, &bottom, &top);
2284 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2285 ok(left == -1.0f, "Got unexpected left %.8e.\n", left);
2286 ok(right == 1.0f, "Got unexpected right %.8e.\n", right);
2287 ok(bottom == -1.0f, "Got unexpected bottom %.8e.\n", bottom);
2288 ok(top == 1.0f, "Got unexpected top %.8e.\n", top);
2290 hr = IDirect3DRMViewport_SetPlane(viewport, 5.0f, 3.0f, 2.0f, 0.0f);
2291 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2292 field = IDirect3DRMViewport_GetField(viewport);
2293 ok(field == -1.0f, "Got unexpected field %.8e.\n", field);
2294 hr = IDirect3DRMViewport_GetPlane(viewport, &left, &right, &bottom, &top);
2295 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2296 ok(left == 5.0f, "Got unexpected left %.8e.\n", left);
2297 ok(right == 3.0f, "Got unexpected right %.8e.\n", right);
2298 ok(bottom == 2.0f, "Got unexpected bottom %.8e.\n", bottom);
2299 ok(top == 0.0f, "Got unexpected top %.8e.\n", top);
2300 hr = IDirect3DRMViewport_SetFront(viewport, 2.0f);
2301 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2302 front = IDirect3DRMViewport_GetFront(viewport);
2303 ok(front == 2.0f, "Got unexpected front %.8e.\n", front);
2304 hr = IDirect3DRMViewport_SetBack(viewport, 200.0f);
2305 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2306 back = IDirect3DRMViewport_GetBack(viewport);
2307 ok(back == 200.0f, "Got unexpected back %.8e.\n", back);
2308 hr = IDirect3DRMViewport_SetProjection(viewport, D3DRMPROJECT_ORTHOGRAPHIC);
2309 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2310 projection = IDirect3DRMViewport_GetProjection(viewport);
2311 ok(projection == D3DRMPROJECT_ORTHOGRAPHIC, "Got unexpected projection type %#x.\n", projection);
2313 hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right, rc.bottom);
2314 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2315 hr = IDirect3DRMViewport_GetDevice(viewport, NULL);
2316 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2317 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, NULL);
2318 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2319 hr = IDirect3DRMViewport_GetCamera(viewport, NULL);
2320 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2321 hr = IDirect3DRMViewport_SetField(viewport, 0.0f);
2322 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2323 hr = IDirect3DRMViewport_SetField(viewport, -1.0f);
2324 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2325 hr = IDirect3DRMViewport_SetFront(viewport, 0.0f);
2326 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2327 hr = IDirect3DRMViewport_SetFront(viewport, -1.0f);
2328 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2329 front = IDirect3DRMViewport_GetFront(viewport);
2330 hr = IDirect3DRMViewport_SetBack(viewport, front);
2331 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2332 hr = IDirect3DRMViewport_SetBack(viewport, front / 2.0f);
2333 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2335 IDirect3DRMViewport_Release(viewport);
2336 ref4 = get_refcount((IUnknown *)d3drm1);
2337 todo_wine ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
2338 ref4 = get_refcount((IUnknown *)d3drm2);
2339 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %lu, ref4 = %lu.\n", ref2, ref4);
2340 ref4 = get_refcount((IUnknown *)d3drm3);
2341 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %lu, ref4 = %lu.\n", ref3, ref4);
2342 ref4 = get_refcount((IUnknown *)device1);
2343 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %lu, ref4 = %lu.\n", device_ref, ref4);
2344 ref4 = get_refcount((IUnknown *)frame);
2345 todo_wine ok(ref4 > frame_ref, "Expected ref4 > frame_ref, got frame_ref = %lu, ref4 = %lu.\n", frame_ref, ref4);
2347 ref1 = get_refcount((IUnknown *)d3drm1);
2348 ref2 = get_refcount((IUnknown *)d3drm2);
2349 ref3 = get_refcount((IUnknown *)d3drm3);
2350 hr = IDirect3DRM3_CreateObject(d3drm2, &CLSID_CDirect3DRMViewport, NULL, &IID_IDirect3DRMViewport2,
2351 (void **)&viewport2);
2352 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport2 interface, hr %#lx.\n", hr);
2353 ref4 = get_refcount((IUnknown *)d3drm1);
2354 ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
2355 ref4 = get_refcount((IUnknown *)d3drm2);
2356 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %lu, ref4 = %lu.\n", ref2, ref4);
2357 ref4 = get_refcount((IUnknown *)d3drm3);
2358 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %lu, ref4 = %lu.\n", ref3, ref4);
2360 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
2361 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2362 hr = IDirect3DRMViewport2_GetDevice(viewport2, &d3drm_device3);
2363 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2364 hr = IDirect3DRMViewport2_GetCamera(viewport2, &d3drm_frame3);
2365 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2366 field = IDirect3DRMViewport2_GetField(viewport2);
2367 ok(field == -1.0f, "Got unexpected field %.8e.\n", field);
2368 left = right = bottom = top = 10.0f;
2369 hr = IDirect3DRMViewport2_GetPlane(viewport2, &left, &right, &bottom, &top);
2370 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2371 ok(left == 10.0f, "Got unexpected left %.8e.\n", left);
2372 ok(right == 10.0f, "Got unexpected right %.8e.\n", right);
2373 ok(bottom == 10.0f, "Got unexpected bottom %.8e.\n", bottom);
2374 ok(top == 10.0f, "Got unexpected top %.8e.\n", top);
2375 front = IDirect3DRMViewport2_GetFront(viewport2);
2376 ok(front == -1.0f, "Got unexpected front %.8e\n", front);
2377 back = IDirect3DRMViewport2_GetBack(viewport2);
2378 ok(back == -1.0f, "Got unexpected back %.8e\n", back);
2379 projection = IDirect3DRMViewport2_GetProjection(viewport2);
2380 ok(projection == ~0u, "Got unexpected projection type %#x.\n", projection);
2382 hr = IDirect3DRMViewport2_SetCamera(viewport2, frame3);
2383 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2384 hr = IDirect3DRMViewport2_SetField(viewport2, 0.5f);
2385 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2386 hr = IDirect3DRMViewport2_SetPlane(viewport2, -0.5f, 0.5f, -0.5f, 0.5f);
2387 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2388 hr = IDirect3DRMViewport2_SetFront(viewport2, 1.0f);
2389 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2390 hr = IDirect3DRMViewport2_SetBack(viewport2, 100.0f);
2391 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2392 hr = IDirect3DRMViewport2_SetProjection(viewport2, D3DRMPROJECT_PERSPECTIVE);
2393 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
2395 hr = IDirect3DRMViewport2_Init(viewport2, NULL, frame3, rc.left, rc.top, rc.right, rc.bottom);
2396 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
2397 hr = IDirect3DRMViewport2_Init(viewport2, device3, NULL, rc.left, rc.top, rc.right, rc.bottom);
2398 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
2399 hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom + 1);
2400 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
2401 hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom);
2402 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
2403 hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right, rc.bottom + 1);
2404 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
2406 device_ref = get_refcount((IUnknown *)device3);
2407 frame_ref2 = get_refcount((IUnknown *)frame3);
2408 hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right, rc.bottom);
2409 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMViewport2 interface, hr %#lx.\n", hr);
2410 ref4 = get_refcount((IUnknown *)device3);
2411 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %lu, ref4 = %lu.\n", device_ref, ref4);
2412 ref4 = get_refcount((IUnknown *)frame3);
2413 ok(ref4 > frame_ref2, "Expected ref4 > frame_ref2, got frame_ref2 = %lu, ref4 = %lu.\n", frame_ref2, ref4);
2415 hr = IDirect3DRMViewport2_GetDevice(viewport2, &d3drm_device3);
2416 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface, hr %#lx\n", hr);
2417 ok(device3 == d3drm_device3, "Expected device returned = %p, got %p.\n", device3, d3drm_device3);
2418 IDirect3DRMDevice3_Release(d3drm_device3);
2420 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
2421 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
2422 viewport_ref = get_refcount((IUnknown *)d3d_viewport);
2423 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
2424 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
2425 ref4 = get_refcount((IUnknown *)d3d_viewport);
2426 ok(ref4 > viewport_ref, "Expected ref4 > viewport_ref, got ref4 = %lu, viewport_ref = %lu.\n", ref4, viewport_ref);
2427 IDirect3DViewport_Release(d3d_viewport);
2428 ref4 = get_refcount((IUnknown *)d3d_viewport);
2429 ok(ref4 == viewport_ref, "Expected ref4 == viewport_ref, got ref4 = %lu, viewport_ref = %lu.\n", ref4, viewport_ref);
2430 IDirect3DViewport_Release(d3d_viewport);
2432 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
2433 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
2434 vp.dwSize = sizeof(vp);
2435 hr = IDirect3DViewport_GetViewport(d3d_viewport, &vp);
2436 ok(SUCCEEDED(hr), "Cannot get D3DVIEWPORT struct, hr %#lx.\n", hr);
2437 ok(vp.dwWidth == rc.right, "Expected viewport width = %lu, got %lu.\n", rc.right, vp.dwWidth);
2438 ok(vp.dwHeight == rc.bottom, "Expected viewport height = %lu, got %lu.\n", rc.bottom, vp.dwHeight);
2439 ok(vp.dwX == rc.left, "Expected viewport X position = %lu, got %lu.\n", rc.left, vp.dwX);
2440 ok(vp.dwY == rc.top, "Expected viewport Y position = %lu, got %lu.\n", rc.top, vp.dwY);
2441 expected_val = (rc.right > rc.bottom) ? (rc.right / 2.0f) : (rc.bottom / 2.0f);
2442 ok(vp.dvScaleX == expected_val, "Expected dvScaleX = %f, got %f.\n", expected_val, vp.dvScaleX);
2443 ok(vp.dvScaleY == expected_val, "Expected dvScaleY = %f, got %f.\n", expected_val, vp.dvScaleY);
2444 expected_val = vp.dwWidth / (2.0f * vp.dvScaleX);
2445 ok(vp.dvMaxX == expected_val, "Expected dvMaxX = %f, got %f.\n", expected_val, vp.dvMaxX);
2446 expected_val = vp.dwHeight / (2.0f * vp.dvScaleY);
2447 ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY);
2448 IDirect3DViewport_Release(d3d_viewport);
2450 field = IDirect3DRMViewport2_GetField(viewport2);
2451 ok(field == 0.5f, "Got unexpected field %.8e.\n", field);
2452 hr = IDirect3DRMViewport2_GetPlane(viewport2, &left, &right, &bottom, &top);
2453 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2454 ok(left == -0.5f, "Got unexpected left %.8e.\n", left);
2455 ok(right == 0.5f, "Got unexpected right %.8e.\n", right);
2456 ok(bottom == -0.5f, "Got unexpected bottom %.8e.\n", bottom);
2457 ok(top == 0.5f, "Got unexpected top %.8e.\n", top);
2458 front = IDirect3DRMViewport2_GetFront(viewport2);
2459 ok(front == 1.0f, "Got unexpected front %.8e.\n", front);
2460 back = IDirect3DRMViewport2_GetBack(viewport2);
2461 ok(back == 100.0f, "Got unexpected back %.8e.\n", back);
2462 projection = IDirect3DRMViewport2_GetProjection(viewport2);
2463 ok(projection == D3DRMPROJECT_PERSPECTIVE, "Got unexpected projection type %#x.\n", projection);
2465 hr = IDirect3DRMViewport2_SetField(viewport2, 1.0f);
2466 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2467 field = IDirect3DRMViewport2_GetField(viewport2);
2468 ok(field == 1.0f, "Got unexpected field %.8e.\n", field);
2469 hr = IDirect3DRMViewport2_GetPlane(viewport2, &left, &right, &bottom, &top);
2470 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2471 ok(left == -1.0f, "Got unexpected left %.8e.\n", left);
2472 ok(right == 1.0f, "Got unexpected right %.8e.\n", right);
2473 ok(bottom == -1.0f, "Got unexpected bottom %.8e.\n", bottom);
2474 ok(top == 1.0f, "Got unexpected top %.8e.\n", top);
2476 hr = IDirect3DRMViewport2_SetPlane(viewport2, 5.0f, 3.0f, 2.0f, 0.0f);
2477 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2478 field = IDirect3DRMViewport2_GetField(viewport2);
2479 ok(field == -1.0f, "Got unexpected field %.8e.\n", field);
2480 hr = IDirect3DRMViewport2_GetPlane(viewport2, &left, &right, &bottom, &top);
2481 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2482 ok(left == 5.0f, "Got unexpected left %.8e.\n", left);
2483 ok(right == 3.0f, "Got unexpected right %.8e.\n", right);
2484 ok(bottom == 2.0f, "Got unexpected bottom %.8e.\n", bottom);
2485 ok(top == 0.0f, "Got unexpected top %.8e.\n", top);
2486 hr = IDirect3DRMViewport2_SetFront(viewport2, 2.0f);
2487 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2488 front = IDirect3DRMViewport2_GetFront(viewport2);
2489 ok(front == 2.0f, "Got unexpected front %.8e.\n", front);
2490 hr = IDirect3DRMViewport2_SetBack(viewport2, 200.0f);
2491 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2492 back = IDirect3DRMViewport2_GetBack(viewport2);
2493 ok(back == 200.0f, "Got unexpected back %.8e.\n", back);
2494 hr = IDirect3DRMViewport2_SetProjection(viewport2, D3DRMPROJECT_ORTHOGRAPHIC);
2495 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2496 projection = IDirect3DRMViewport2_GetProjection(viewport2);
2497 ok(projection == D3DRMPROJECT_ORTHOGRAPHIC, "Got unexpected projection type %#x.\n", projection);
2499 hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right, rc.bottom);
2500 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
2501 hr = IDirect3DRMViewport2_GetDevice(viewport2, NULL);
2502 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2503 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, NULL);
2504 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2505 hr = IDirect3DRMViewport2_GetCamera(viewport2, NULL);
2506 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2507 hr = IDirect3DRMViewport2_SetField(viewport2, 0.0f);
2508 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2509 hr = IDirect3DRMViewport2_SetField(viewport2, -1.0f);
2510 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2511 hr = IDirect3DRMViewport2_SetFront(viewport2, 0.0f);
2512 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2513 hr = IDirect3DRMViewport2_SetFront(viewport2, -1.0f);
2514 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2515 front = IDirect3DRMViewport2_GetFront(viewport2);
2516 hr = IDirect3DRMViewport2_SetBack(viewport2, front);
2517 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2518 hr = IDirect3DRMViewport2_SetBack(viewport2, front / 2.0f);
2519 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
2521 IDirect3DRMViewport2_Release(viewport2);
2522 ref4 = get_refcount((IUnknown *)d3drm1);
2523 todo_wine ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
2524 ref4 = get_refcount((IUnknown *)d3drm2);
2525 ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %lu, ref4 = %lu.\n", ref2, ref4);
2526 ref4 = get_refcount((IUnknown *)d3drm3);
2527 ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %lu, ref4 = %lu.\n", ref3, ref4);
2528 ref4 = get_refcount((IUnknown *)device3);
2529 ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %lu, ref4 = %lu.\n", device_ref, ref4);
2530 ref4 = get_refcount((IUnknown *)frame3);
2531 todo_wine ok(ref4 > frame_ref2, "Expected ref4 > frame_ref2, got frame_ref2 = %lu, ref4 = %lu.\n", frame_ref2, ref4);
2533 IDirect3DRMDevice3_Release(device3);
2534 IDirect3DRMDevice_Release(device1);
2535 ref4 = get_refcount((IUnknown *)d3drm1);
2536 ok(ref4 > initial_ref1, "Expected ref4 > initial_ref1, got initial_ref1 = %lu, ref4 = %lu.\n", initial_ref1, ref4);
2537 ref4 = get_refcount((IUnknown *)d3drm2);
2538 ok(ref4 == initial_ref2, "Expected ref4 == initial_ref2, got initial_ref2 = %lu, ref4 = %lu.\n", initial_ref2, ref4);
2539 ref4 = get_refcount((IUnknown *)d3drm3);
2540 ok(ref4 == initial_ref3, "Expected ref4 == initial_ref3, got initial_ref3 = %lu, ref4 = %lu.\n", initial_ref3, ref4);
2541 ref4 = get_refcount((IUnknown *)frame);
2542 ok(ref4 == frame_ref, "Expected ref4 == frame_ref, got frame_ref = %lu, ref4 = %lu.\n", frame_ref, ref4);
2543 ref4 = get_refcount((IUnknown *)frame3);
2544 ok(ref4 == frame_ref2, "Expected ref4 == frame_ref2, got frame_ref2 = %lu, ref4 = %lu.\n", frame_ref2, ref4);
2546 IDirect3DRMFrame3_Release(tmp_frame3);
2547 IDirect3DRMFrame3_Release(frame3);
2548 ref4 = get_refcount((IUnknown *)d3drm1);
2549 ok(ref4 > initial_ref1, "Expected ref4 > initial_ref1, got initial_ref1 = %lu, ref4 = %lu.\n", initial_ref1, ref4);
2550 ref4 = get_refcount((IUnknown *)d3drm2);
2551 ok(ref4 == initial_ref2, "Expected ref4 == initial_ref2, got initial_ref2 = %lu, ref4 = %lu.\n", initial_ref2, ref4);
2552 ref4 = get_refcount((IUnknown *)d3drm3);
2553 ok(ref4 == initial_ref3, "Expected ref4 == initial_ref3, got initial_ref3 = %lu, ref4 = %lu.\n", initial_ref3, ref4);
2555 IDirect3DRMFrame3_Release(tmp_frame1);
2556 IDirect3DRMFrame_Release(frame);
2557 ref4 = get_refcount((IUnknown *)d3drm1);
2558 ok(ref4 == initial_ref1, "Expected ref4 == initial_ref1, got initial_ref1 = %lu, ref4 = %lu.\n", initial_ref1, ref4);
2559 ref4 = get_refcount((IUnknown *)d3drm2);
2560 ok(ref4 == initial_ref2, "Expected ref4 == initial_ref2, got initial_ref2 = %lu, ref4 = %lu.\n", initial_ref2, ref4);
2561 ref4 = get_refcount((IUnknown *)d3drm3);
2562 ok(ref4 == initial_ref3, "Expected ref4 == initial_ref3, got initial_ref3 = %lu, ref4 = %lu.\n", initial_ref3, ref4);
2563 IDirectDrawClipper_Release(clipper);
2565 IDirect3DRM3_Release(d3drm3);
2566 IDirect3DRM2_Release(d3drm2);
2567 IDirect3DRM_Release(d3drm1);
2568 DestroyWindow(window);
2571 static void test_Light(void)
2573 IDirect3DRMObject *object;
2574 HRESULT hr;
2575 IDirect3DRM *d3drm;
2576 IDirect3DRMLight *light;
2577 D3DRMLIGHTTYPE type;
2578 D3DCOLOR color;
2580 hr = Direct3DRMCreate(&d3drm);
2581 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx\n", hr);
2583 hr = IDirect3DRM_CreateLightRGB(d3drm, D3DRMLIGHT_SPOT, 0.5, 0.5, 0.5, &light);
2584 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMLight interface, hr %#lx\n", hr);
2586 hr = IDirect3DRMLight_QueryInterface(light, &IID_IDirect3DRMObject, (void **)&object);
2587 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, hr %#lx.\n", hr);
2588 IDirect3DRMObject_Release(object);
2590 test_class_name((IDirect3DRMObject *)light, "Light");
2591 test_object_name((IDirect3DRMObject *)light);
2593 type = IDirect3DRMLight_GetType(light);
2594 ok(type == D3DRMLIGHT_SPOT, "wrong type (%u)\n", type);
2596 color = IDirect3DRMLight_GetColor(light);
2597 ok(color == 0xff7f7f7f, "wrong color %lx.\n", color);
2599 hr = IDirect3DRMLight_SetType(light, D3DRMLIGHT_POINT);
2600 ok(hr == D3DRM_OK, "Cannot set type, hr %#lx\n", hr);
2601 type = IDirect3DRMLight_GetType(light);
2602 ok(type == D3DRMLIGHT_POINT, "wrong type %u.\n", type);
2604 hr = IDirect3DRMLight_SetColor(light, 0xff180587);
2605 ok(hr == D3DRM_OK, "Cannot set color, hr %#lx\n", hr);
2606 color = IDirect3DRMLight_GetColor(light);
2607 ok(color == 0xff180587, "wrong color %#lx.\n", color);
2609 hr = IDirect3DRMLight_SetColor(light, 0x00c0c0c0);
2610 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2611 color = IDirect3DRMLight_GetColor(light);
2612 ok(color == 0xffc0c0c0, "Got unexpected color 0x%08lx.\n", color);
2614 hr = IDirect3DRMLight_SetColorRGB(light, 0.5, 0.5, 0.5);
2615 ok(hr == D3DRM_OK, "Cannot set color, hr %#lx\n", hr);
2616 color = IDirect3DRMLight_GetColor(light);
2617 ok(color == 0xff7f7f7f, "wrong color %#lx.\n", color);
2619 IDirect3DRMLight_Release(light);
2621 hr = IDirect3DRM_CreateLight(d3drm, D3DRMLIGHT_SPOT, 0x00c0c0c0, &light);
2622 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
2624 type = IDirect3DRMLight_GetType(light);
2625 ok(type == D3DRMLIGHT_SPOT, "Got unexpected type %#x.\n", type);
2627 color = IDirect3DRMLight_GetColor(light);
2628 ok(color == 0xffc0c0c0, "Got unexpected color 0x%08lx.\n", color);
2630 IDirect3DRMLight_Release(light);
2632 IDirect3DRM_Release(d3drm);
2635 static void test_Material2(void)
2637 HRESULT hr;
2638 IDirect3DRM *d3drm;
2639 IDirect3DRM3 *d3drm3;
2640 IDirect3DRMMaterial2 *material2;
2641 D3DVALUE r, g, b;
2643 hr = Direct3DRMCreate(&d3drm);
2644 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx\n", hr);
2646 if (FAILED(hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM3, (void **)&d3drm3)))
2648 win_skip("Cannot get IDirect3DRM3 interface, hr %#lx, skipping tests\n", hr);
2649 IDirect3DRM_Release(d3drm);
2650 return;
2653 hr = IDirect3DRM3_CreateMaterial(d3drm3, 18.5f, &material2);
2654 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMMaterial2 interface, hr %#lx\n", hr);
2656 test_class_name((IDirect3DRMObject *)material2, "Material");
2657 test_object_name((IDirect3DRMObject *)material2);
2659 r = IDirect3DRMMaterial2_GetPower(material2);
2660 ok(r == 18.5f, "wrong power (%f)\n", r);
2662 hr = IDirect3DRMMaterial2_GetEmissive(material2, &r, &g, &b);
2663 ok(hr == D3DRM_OK, "Cannot get emissive, hr %#lx\n", hr);
2664 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);
2666 hr = IDirect3DRMMaterial2_GetSpecular(material2, &r, &g, &b);
2667 ok(hr == D3DRM_OK, "Cannot get emissive, hr %#lx\n", hr);
2668 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);
2670 hr = IDirect3DRMMaterial2_GetAmbient(material2, &r, &g, &b);
2671 ok(hr == D3DRM_OK, "Cannot get emissive, hr %#lx\n", hr);
2672 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);
2674 hr = IDirect3DRMMaterial2_SetPower(material2, 5.87f);
2675 ok(hr == D3DRM_OK, "Cannot set power, hr %#lx\n", hr);
2676 r = IDirect3DRMMaterial2_GetPower(material2);
2677 ok(r == 5.87f, "wrong power (%f)\n", r);
2679 hr = IDirect3DRMMaterial2_SetEmissive(material2, 0.5f, 0.5f, 0.5f);
2680 ok(hr == D3DRM_OK, "Cannot set emissive, hr %#lx\n", hr);
2681 hr = IDirect3DRMMaterial2_GetEmissive(material2, &r, &g, &b);
2682 ok(hr == D3DRM_OK, "Cannot get emissive, hr %#lx\n", hr);
2683 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);
2685 hr = IDirect3DRMMaterial2_SetSpecular(material2, 0.6f, 0.6f, 0.6f);
2686 ok(hr == D3DRM_OK, "Cannot set specular, hr %#lx\n", hr);
2687 hr = IDirect3DRMMaterial2_GetSpecular(material2, &r, &g, &b);
2688 ok(hr == D3DRM_OK, "Cannot get specular, hr %#lx\n", hr);
2689 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);
2691 hr = IDirect3DRMMaterial2_SetAmbient(material2, 0.7f, 0.7f, 0.7f);
2692 ok(hr == D3DRM_OK, "Cannot set ambient, hr %#lx\n", hr);
2693 hr = IDirect3DRMMaterial2_GetAmbient(material2, &r, &g, &b);
2694 ok(hr == D3DRM_OK, "Cannot get ambient, hr %#lx\n", hr);
2695 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);
2697 IDirect3DRMMaterial2_Release(material2);
2699 IDirect3DRM3_Release(d3drm3);
2700 IDirect3DRM_Release(d3drm);
2703 static void test_Texture(void)
2705 HRESULT hr;
2706 IDirect3DRM *d3drm1;
2707 IDirect3DRM2 *d3drm2;
2708 IDirect3DRM3 *d3drm3;
2709 IDirect3DRMTexture *texture1;
2710 IDirect3DRMTexture2 *texture2;
2711 IDirect3DRMTexture3 *texture3;
2712 IDirectDrawSurface *surface;
2713 LONG decalx, decaly;
2714 DWORD colors, shades;
2715 BOOL transparency;
2716 D3DVALUE width, height;
2718 D3DRMIMAGE initimg =
2720 2, 2, 1, 1, 32,
2721 TRUE, 2 * sizeof(DWORD), NULL, NULL,
2722 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000, 0, NULL
2724 testimg =
2726 0, 0, 0, 0, 0,
2727 TRUE, 0, (void *)0xcafebabe, NULL,
2728 0x000000ff, 0x0000ff00, 0x00ff0000, 0, 0, NULL
2730 *d3drm_img = NULL;
2732 DWORD pixel[4] = { 20000, 30000, 10000, 0 };
2733 ULONG ref1, ref2, ref3, ref4;
2735 hr = Direct3DRMCreate(&d3drm1);
2736 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface, hr %#lx\n", hr);
2737 ref1 = get_refcount((IUnknown *)d3drm1);
2739 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
2740 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface, hr %#lx.\n", hr);
2742 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
2743 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr);
2745 /* Test NULL params */
2746 texture1 = (IDirect3DRMTexture *)0xdeadbeef;
2747 hr = IDirect3DRM_CreateTexture(d3drm1, NULL, &texture1);
2748 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2749 ok(!texture1, "Expected texture returned == NULL, got %p.\n", texture1);
2750 hr = IDirect3DRM_CreateTexture(d3drm1, NULL, NULL);
2751 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2753 texture2 = (IDirect3DRMTexture2 *)0xdeadbeef;
2754 hr = IDirect3DRM2_CreateTexture(d3drm2, NULL, &texture2);
2755 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2756 ok(!texture2, "Expected texture returned == NULL, got %p.\n", texture2);
2757 hr = IDirect3DRM2_CreateTexture(d3drm2, NULL, NULL);
2758 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2760 texture3 = (IDirect3DRMTexture3 *)0xdeadbeef;
2761 hr = IDirect3DRM3_CreateTexture(d3drm3, NULL, &texture3);
2762 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2763 ok(!texture3, "Expected texture returned == NULL, got %p.\n", texture3);
2764 hr = IDirect3DRM3_CreateTexture(d3drm3, NULL, NULL);
2765 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2767 /* Tests for validation of D3DRMIMAGE struct */
2768 hr = IDirect3DRM_CreateTexture(d3drm1, &testimg, &texture1);
2769 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture interface, hr %#lx\n", hr);
2770 hr = IDirect3DRM2_CreateTexture(d3drm2, &testimg, &texture2);
2771 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface, hr %#lx\n", hr);
2772 hr = IDirect3DRM3_CreateTexture(d3drm3, &testimg, &texture3);
2773 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface, hr %#lx\n", hr);
2774 IDirect3DRMTexture_Release(texture1);
2775 IDirect3DRMTexture2_Release(texture2);
2776 IDirect3DRMTexture3_Release(texture3);
2778 testimg.rgb = 0;
2779 testimg.palette = (void *)0xdeadbeef;
2780 testimg.palette_size = 0x39;
2781 hr = IDirect3DRM_CreateTexture(d3drm1, &testimg, &texture1);
2782 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture interface, hr %#lx\n", hr);
2783 hr = IDirect3DRM2_CreateTexture(d3drm2, &testimg, &texture2);
2784 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface, hr %#lx\n", hr);
2785 hr = IDirect3DRM3_CreateTexture(d3drm3, &testimg, &texture3);
2786 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface, hr %#lx\n", hr);
2787 IDirect3DRMTexture_Release(texture1);
2788 IDirect3DRMTexture2_Release(texture2);
2789 IDirect3DRMTexture3_Release(texture3);
2791 initimg.rgb = 0;
2792 texture1 = (IDirect3DRMTexture *)0xdeadbeef;
2793 hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2794 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2795 ok(!texture1, "Expected texture == NULL, got %p.\n", texture1);
2796 texture2 = (IDirect3DRMTexture2 *)0xdeadbeef;
2797 hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2798 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2799 ok(!texture2, "Expected texture == NULL, got %p.\n", texture2);
2800 texture3 = (IDirect3DRMTexture3 *)0xdeadbeef;
2801 hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2802 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2803 ok(!texture3, "Expected texture == NULL, got %p.\n", texture3);
2804 initimg.rgb = 1;
2805 initimg.red_mask = 0;
2806 hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2807 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2808 hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2809 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2810 hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2811 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2812 initimg.red_mask = 0x000000ff;
2813 initimg.green_mask = 0;
2814 hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2815 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2816 hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2817 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2818 hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2819 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2820 initimg.green_mask = 0x0000ff00;
2821 initimg.blue_mask = 0;
2822 hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2823 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2824 hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2825 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2826 hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2827 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2828 initimg.blue_mask = 0x00ff0000;
2829 initimg.buffer1 = NULL;
2830 hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2831 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2832 hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2833 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2834 hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2835 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2837 initimg.buffer1 = &pixel;
2838 hr = IDirect3DRM_CreateTexture(d3drm1, &initimg, &texture1);
2839 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture interface, hr %#lx\n", hr);
2840 ref2 = get_refcount((IUnknown *)d3drm1);
2841 ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %lu , ref2 = %lu.\n", ref1, ref2);
2842 ref3 = get_refcount((IUnknown *)d3drm2);
2843 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %lu , ref3 = %lu.\n", ref1, ref3);
2844 ref4 = get_refcount((IUnknown *)d3drm3);
2845 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %lu , ref4 = %lu.\n", ref1, ref4);
2846 hr = IDirect3DRM2_CreateTexture(d3drm2, &initimg, &texture2);
2847 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface, hr %#lx\n", hr);
2848 ref2 = get_refcount((IUnknown *)d3drm1);
2849 ok(ref2 > ref1 + 1, "expected ref2 > (ref1 + 1), got ref1 = %lu , ref2 = %lu.\n", ref1, ref2);
2850 ref3 = get_refcount((IUnknown *)d3drm2);
2851 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %lu , ref3 = %lu.\n", ref1, ref3);
2852 ref4 = get_refcount((IUnknown *)d3drm3);
2853 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %lu , ref4 = %lu.\n", ref1, ref4);
2854 hr = IDirect3DRM3_CreateTexture(d3drm3, &initimg, &texture3);
2855 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface, hr %#lx\n", hr);
2856 ref2 = get_refcount((IUnknown *)d3drm1);
2857 ok(ref2 > ref1 + 2, "expected ref2 > (ref1 + 2), got ref1 = %lu , ref2 = %lu.\n", ref1, ref2);
2858 ref3 = get_refcount((IUnknown *)d3drm2);
2859 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %lu , ref3 = %lu.\n", ref1, ref3);
2860 ref4 = get_refcount((IUnknown *)d3drm3);
2861 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %lu , ref4 = %lu.\n", ref1, ref4);
2863 /* Created from image, GetSurface() does not work. */
2864 hr = IDirect3DRMTexture3_GetSurface(texture3, 0, NULL);
2865 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
2867 hr = IDirect3DRMTexture3_GetSurface(texture3, 0, &surface);
2868 ok(hr == D3DRMERR_NOTCREATEDFROMDDS, "Unexpected hr %#lx.\n", hr);
2870 /* Test all failures together */
2871 test_class_name((IDirect3DRMObject *)texture1, "Texture");
2872 test_class_name((IDirect3DRMObject *)texture2, "Texture");
2873 test_class_name((IDirect3DRMObject *)texture3, "Texture");
2874 test_object_name((IDirect3DRMObject *)texture1);
2875 test_object_name((IDirect3DRMObject *)texture2);
2876 test_object_name((IDirect3DRMObject *)texture3);
2878 hr = IDirect3DRMTexture_GetDecalOrigin(texture1, &decalx, &decaly);
2879 ok(hr == S_OK, "got %#lx.\n", hr);
2880 ok(decalx == 0, "got %ld.\n", decalx);
2881 ok(decaly == 0, "got %ld.\n", decaly);
2883 hr = IDirect3DRMTexture_SetDecalOrigin(texture1, 1, 1);
2884 ok(hr == S_OK, "got %#lx.\n", hr);
2886 hr = IDirect3DRMTexture_GetDecalOrigin(texture1, &decalx, &decaly);
2887 ok(hr == S_OK, "got %#lx.\n", hr);
2888 ok(decalx == 1, "got %ld.\n", decalx);
2889 ok(decaly == 1, "got %ld.\n", decaly);
2891 hr = IDirect3DRMTexture_SetDecalOrigin(texture1, 0, 0);
2892 ok(hr == S_OK, "got %#lx.\n", hr);
2894 colors = IDirect3DRMTexture_GetColors(texture1);
2895 ok(colors == 8, "got %ld.\n", colors);
2897 hr = IDirect3DRMTexture_SetColors(texture1, 256);
2898 ok(hr == S_OK, "got %#lx.\n", hr);
2900 colors = IDirect3DRMTexture_GetColors(texture1);
2901 ok(colors == 256, "got %ld.\n", colors);
2903 hr = IDirect3DRMTexture_SetColors(texture1, 8);
2904 ok(hr == S_OK, "got %#lx.\n", hr);
2906 shades = IDirect3DRMTexture_GetShades(texture1);
2907 ok(shades == 16, "got %ld.\n", shades);
2909 hr = IDirect3DRMTexture_SetShades(texture1, 8);
2910 ok(hr == S_OK, "got %#lx.\n", hr);
2912 shades = IDirect3DRMTexture_GetShades(texture1);
2913 ok(shades == 8, "got %ld.\n", shades);
2915 hr = IDirect3DRMTexture_SetShades(texture1, 11);
2916 ok(hr == S_OK, "got %#lx.\n", hr);
2918 shades = IDirect3DRMTexture_GetShades(texture1);
2919 ok(shades == 11, "got %ld.\n", shades);
2921 hr = IDirect3DRMTexture_SetShades(texture1, 8);
2922 ok(hr == S_OK, "got %#lx.\n", hr);
2924 hr = IDirect3DRMTexture_GetDecalSize(texture1, &width, &height);
2925 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2926 ok(width == 1.0f, "Got %.8e.\n", width);
2927 ok(height == 1.0f, "Got %.8e.\n", height);
2929 hr = IDirect3DRMTexture_SetDecalSize(texture1, 8.0f, 7.0f);
2930 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2932 hr = IDirect3DRMTexture_GetDecalSize(texture1, &width, &height);
2933 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2934 ok(width == 8.0f, "Got %.8e.\n", width);
2935 ok(height == 7.0f, "Got %.8e.\n", height);
2937 hr = IDirect3DRMTexture_SetDecalSize(texture1, 1.0f, 1.0f);
2938 ok(hr == S_OK, "got %#lx.\n", hr);
2940 transparency = IDirect3DRMTexture_GetDecalTransparency(texture1);
2941 ok(transparency == FALSE, "Got %d.\n", transparency);
2943 hr = IDirect3DRMTexture_SetDecalTransparency(texture1, TRUE);
2944 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2946 transparency = IDirect3DRMTexture_GetDecalTransparency(texture1);
2947 ok(transparency == TRUE, "Got %d.\n", transparency);
2949 hr = IDirect3DRMTexture_SetDecalTransparency(texture1, FALSE);
2950 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2952 d3drm_img = IDirect3DRMTexture_GetImage(texture1);
2953 ok(!!d3drm_img, "Failed to get image.\n");
2954 ok(d3drm_img == &initimg, "Expected image returned == %p, got %p.\n", &initimg, d3drm_img);
2956 IDirect3DRMTexture_Release(texture1);
2957 ref2 = get_refcount((IUnknown *)d3drm1);
2958 ok(ref2 - 2 == ref1, "expected (ref2 - 2) == ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
2959 ref3 = get_refcount((IUnknown *)d3drm2);
2960 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
2961 ref4 = get_refcount((IUnknown *)d3drm3);
2962 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
2964 d3drm_img = NULL;
2965 d3drm_img = IDirect3DRMTexture2_GetImage(texture2);
2966 ok(!!d3drm_img, "Failed to get image.\n");
2967 ok(d3drm_img == &initimg, "Expected image returned == %p, got %p.\n", &initimg, d3drm_img);
2969 IDirect3DRMTexture2_Release(texture2);
2970 ref2 = get_refcount((IUnknown *)d3drm1);
2971 ok(ref2 - 1 == ref1, "expected (ref2 - 1) == ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
2972 ref3 = get_refcount((IUnknown *)d3drm2);
2973 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
2974 ref4 = get_refcount((IUnknown *)d3drm3);
2975 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
2977 d3drm_img = NULL;
2978 d3drm_img = IDirect3DRMTexture3_GetImage(texture3);
2979 ok(!!d3drm_img, "Failed to get image.\n");
2980 ok(d3drm_img == &initimg, "Expected image returned == %p, got %p.\n", &initimg, d3drm_img);
2982 IDirect3DRMTexture3_Release(texture3);
2983 ref2 = get_refcount((IUnknown *)d3drm1);
2984 ok(ref2 == ref1, "expected ref2 == ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
2985 ref3 = get_refcount((IUnknown *)d3drm2);
2986 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
2987 ref4 = get_refcount((IUnknown *)d3drm3);
2988 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
2990 /* InitFromImage tests */
2991 /* Tests for validation of D3DRMIMAGE struct */
2992 testimg.rgb = 1;
2993 testimg.palette = NULL;
2994 testimg.palette_size = 0;
2995 hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture2,
2996 (void **)&texture2);
2997 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface, hr %#lx.\n", hr);
2998 hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture3,
2999 (void **)&texture3);
3000 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface, hr %#lx.\n", hr);
3001 hr = IDirect3DRMTexture2_InitFromImage(texture2, &testimg);
3002 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture2 interface, hr %#lx\n", hr);
3003 hr = IDirect3DRMTexture3_InitFromImage(texture3, &testimg);
3004 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture3 interface, hr %#lx\n", hr);
3005 IDirect3DRMTexture2_Release(texture2);
3006 IDirect3DRMTexture3_Release(texture3);
3008 testimg.rgb = 0;
3009 testimg.palette = (void *)0xdeadbeef;
3010 testimg.palette_size = 0x39;
3011 hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture2,
3012 (void **)&texture2);
3013 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface, hr %#lx.\n", hr);
3014 hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture3,
3015 (void **)&texture3);
3016 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface, hr %#lx.\n", hr);
3017 hr = IDirect3DRMTexture2_InitFromImage(texture2, &testimg);
3018 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture2 interface, hr %#lx\n", hr);
3019 hr = IDirect3DRMTexture3_InitFromImage(texture3, &testimg);
3020 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture3 interface, hr %#lx\n", hr);
3021 IDirect3DRMTexture2_Release(texture2);
3022 IDirect3DRMTexture3_Release(texture3);
3024 hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture2,
3025 (void **)&texture2);
3026 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture2 interface, hr %#lx.\n", hr);
3027 ref2 = get_refcount((IUnknown *)texture2);
3028 hr = IDirect3DRMTexture2_InitFromImage(texture2, NULL);
3029 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
3030 ref3 = get_refcount((IUnknown *)texture2);
3031 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
3033 hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture3,
3034 (void **)&texture3);
3035 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface, hr %#lx.\n", hr);
3036 ref2 = get_refcount((IUnknown *)texture3);
3037 hr = IDirect3DRMTexture3_InitFromImage(texture3, NULL);
3038 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
3039 ref3 = get_refcount((IUnknown *)texture3);
3040 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
3042 initimg.rgb = 0;
3043 hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
3044 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
3045 hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
3046 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
3047 initimg.rgb = 1;
3048 initimg.red_mask = 0;
3049 hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
3050 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
3051 hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
3052 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
3053 initimg.red_mask = 0x000000ff;
3054 initimg.green_mask = 0;
3055 hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
3056 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
3057 hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
3058 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
3059 initimg.green_mask = 0x0000ff00;
3060 initimg.blue_mask = 0;
3061 hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
3062 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
3063 hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
3064 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
3065 initimg.blue_mask = 0x00ff0000;
3066 initimg.buffer1 = NULL;
3067 hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
3068 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
3069 hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
3070 ok(hr == D3DRMERR_BADOBJECT, "Unexpected hr %#lx.\n", hr);
3071 initimg.buffer1 = &pixel;
3073 d3drm_img = NULL;
3074 hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
3075 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture2 from image, hr %#lx.\n", hr);
3076 ref2 = get_refcount((IUnknown *)d3drm1);
3077 ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %lu , ref2 = %lu.\n", ref1, ref2);
3078 ref3 = get_refcount((IUnknown *)d3drm2);
3079 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %lu , ref3 = %lu.\n", ref1, ref3);
3080 ref4 = get_refcount((IUnknown *)d3drm3);
3081 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %lu , ref4 = %lu.\n", ref1, ref4);
3083 hr = IDirect3DRMTexture2_InitFromImage(texture2, &initimg);
3084 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got hr %#lx.\n", hr);
3085 /* Release leaked reference to d3drm1 */
3086 IDirect3DRM_Release(d3drm1);
3088 d3drm_img = IDirect3DRMTexture2_GetImage(texture2);
3089 ok(!!d3drm_img, "Failed to get image.\n");
3090 ok(d3drm_img == &initimg, "Expected image returned == %p, got %p.\n", &initimg, d3drm_img);
3091 IDirect3DRMTexture2_Release(texture2);
3092 ref2 = get_refcount((IUnknown *)d3drm1);
3093 ok(ref2 == ref1, "expected ref2 == ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
3094 ref3 = get_refcount((IUnknown *)d3drm2);
3095 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
3096 ref4 = get_refcount((IUnknown *)d3drm3);
3097 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
3099 d3drm_img = NULL;
3100 hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
3101 ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMTexture3 from image, hr %#lx.\n", hr);
3102 ref2 = get_refcount((IUnknown *)d3drm1);
3103 ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %lu , ref2 = %lu.\n", ref1, ref2);
3104 ref3 = get_refcount((IUnknown *)d3drm2);
3105 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %lu , ref3 = %lu.\n", ref1, ref3);
3106 ref4 = get_refcount((IUnknown *)d3drm3);
3107 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %lu , ref4 = %lu.\n", ref1, ref4);
3109 hr = IDirect3DRMTexture3_InitFromImage(texture3, &initimg);
3110 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got hr %#lx.\n", hr);
3111 IDirect3DRM_Release(d3drm1);
3113 d3drm_img = IDirect3DRMTexture3_GetImage(texture3);
3114 ok(!!d3drm_img, "Failed to get image.\n");
3115 ok(d3drm_img == &initimg, "Expected image returned == %p, got %p.\n", &initimg, d3drm_img);
3116 IDirect3DRMTexture3_Release(texture3);
3117 ref2 = get_refcount((IUnknown *)d3drm1);
3118 ok(ref2 == ref1, "expected ref2 == ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
3119 ref3 = get_refcount((IUnknown *)d3drm2);
3120 ok(ref3 == ref1, "expected ref3 == ref1, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
3121 ref4 = get_refcount((IUnknown *)d3drm3);
3122 ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %lu, ref4 = %lu.\n", ref1, ref4);
3124 IDirect3DRM3_Release(d3drm3);
3125 IDirect3DRM2_Release(d3drm2);
3126 IDirect3DRM_Release(d3drm1);
3129 static void test_Device(void)
3131 IDirectDrawClipper *pClipper;
3132 HRESULT hr;
3133 IDirect3DRM *d3drm;
3134 IDirect3DRMDevice *device;
3135 IDirect3DRMWinDevice *win_device;
3136 GUID driver;
3137 HWND window;
3138 RECT rc;
3140 window = create_window();
3141 GetClientRect(window, &rc);
3143 hr = Direct3DRMCreate(&d3drm);
3144 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx\n", hr);
3146 hr = DirectDrawCreateClipper(0, &pClipper, NULL);
3147 ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface, hr %#lx\n", hr);
3149 hr = IDirectDrawClipper_SetHWnd(pClipper, 0, window);
3150 ok(hr == DD_OK, "Cannot set HWnd to Clipper, hr %#lx\n", hr);
3152 memcpy(&driver, &IID_IDirect3DRGBDevice, sizeof(GUID));
3153 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm, pClipper, &driver, rc.right, rc.bottom, &device);
3154 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMDevice interface, hr %#lx\n", hr);
3156 test_class_name((IDirect3DRMObject *)device, "Device");
3157 test_object_name((IDirect3DRMObject *)device);
3159 /* WinDevice */
3160 if (FAILED(hr = IDirect3DRMDevice_QueryInterface(device, &IID_IDirect3DRMWinDevice, (void **)&win_device)))
3162 win_skip("Cannot get IDirect3DRMWinDevice interface, hr %#lx, skipping tests\n", hr);
3163 goto cleanup;
3166 test_class_name((IDirect3DRMObject *)win_device, "Device");
3167 test_object_name((IDirect3DRMObject *)win_device);
3168 IDirect3DRMWinDevice_Release(win_device);
3170 cleanup:
3171 IDirect3DRMDevice_Release(device);
3172 IDirectDrawClipper_Release(pClipper);
3174 IDirect3DRM_Release(d3drm);
3175 DestroyWindow(window);
3178 static void test_frame_transform(void)
3180 IDirect3DRMFrame *frame, *subframe;
3181 D3DRMMATRIX4D matrix, add_matrix;
3182 IDirect3DRM *d3drm;
3183 D3DVECTOR v1, v2;
3184 HRESULT hr;
3186 hr = Direct3DRMCreate(&d3drm);
3187 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3189 hr = IDirect3DRM_CreateFrame(d3drm, NULL, &frame);
3190 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3192 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3193 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3194 expect_matrix(matrix,
3195 1.0f, 0.0f, 0.0f, 0.0f,
3196 0.0f, 1.0f, 0.0f, 0.0f,
3197 0.0f, 0.0f, 1.0f, 0.0f,
3198 0.0f, 0.0f, 0.0f, 1.0f, 0);
3200 memcpy(add_matrix, identity, sizeof(add_matrix));
3201 add_matrix[3][0] = 3.0f;
3202 add_matrix[3][1] = 3.0f;
3203 add_matrix[3][2] = 3.0f;
3205 frame_set_transform(frame,
3206 2.0f, 0.0f, 0.0f, 0.0f,
3207 0.0f, 2.0f, 0.0f, 0.0f,
3208 0.0f, 0.0f, 2.0f, 0.0f,
3209 0.0f, 0.0f, 0.0f, 1.0f);
3210 hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_REPLACE, add_matrix);
3211 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3212 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3213 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3214 expect_matrix(matrix,
3215 1.0f, 0.0f, 0.0f, 0.0f,
3216 0.0f, 1.0f, 0.0f, 0.0f,
3217 0.0f, 0.0f, 1.0f, 0.0f,
3218 3.0f, 3.0f, 3.0f, 1.0f, 1);
3220 frame_set_transform(frame,
3221 2.0f, 0.0f, 0.0f, 0.0f,
3222 0.0f, 2.0f, 0.0f, 0.0f,
3223 0.0f, 0.0f, 2.0f, 0.0f,
3224 0.0f, 0.0f, 0.0f, 1.0f);
3225 hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_BEFORE, add_matrix);
3226 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3227 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3228 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3229 expect_matrix(matrix,
3230 2.0f, 0.0f, 0.0f, 0.0f,
3231 0.0f, 2.0f, 0.0f, 0.0f,
3232 0.0f, 0.0f, 2.0f, 0.0f,
3233 6.0f, 6.0f, 6.0f, 1.0f, 1);
3235 frame_set_transform(frame,
3236 2.0f, 0.0f, 0.0f, 0.0f,
3237 0.0f, 2.0f, 0.0f, 0.0f,
3238 0.0f, 0.0f, 2.0f, 0.0f,
3239 0.0f, 0.0f, 0.0f, 1.0f);
3240 hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_AFTER, add_matrix);
3241 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3242 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3243 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3244 expect_matrix(matrix,
3245 2.0f, 0.0f, 0.0f, 0.0f,
3246 0.0f, 2.0f, 0.0f, 0.0f,
3247 0.0f, 0.0f, 2.0f, 0.0f,
3248 3.0f, 3.0f, 3.0f, 1.0f, 1);
3250 add_matrix[3][3] = 2.0f;
3251 hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_REPLACE, add_matrix);
3252 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
3254 frame_set_transform(frame,
3255 2.0f, 0.0f, 0.0f, 0.0f,
3256 0.0f, 2.0f, 0.0f, 0.0f,
3257 0.0f, 0.0f, 2.0f, 0.0f,
3258 0.0f, 0.0f, 0.0f, 1.0f);
3259 hr = IDirect3DRMFrame_AddTranslation(frame, D3DRMCOMBINE_REPLACE, 3.0f, 3.0f, 3.0f);
3260 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3261 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3262 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3263 expect_matrix(matrix,
3264 1.0f, 0.0f, 0.0f, 0.0f,
3265 0.0f, 1.0f, 0.0f, 0.0f,
3266 0.0f, 0.0f, 1.0f, 0.0f,
3267 3.0f, 3.0f, 3.0f, 1.0f, 1);
3269 frame_set_transform(frame,
3270 2.0f, 0.0f, 0.0f, 0.0f,
3271 0.0f, 2.0f, 0.0f, 0.0f,
3272 0.0f, 0.0f, 2.0f, 0.0f,
3273 0.0f, 0.0f, 0.0f, 1.0f);
3274 hr = IDirect3DRMFrame_AddTranslation(frame, D3DRMCOMBINE_BEFORE, 3.0f, 3.0f, 3.0f);
3275 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3276 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3277 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3278 expect_matrix(matrix,
3279 2.0f, 0.0f, 0.0f, 0.0f,
3280 0.0f, 2.0f, 0.0f, 0.0f,
3281 0.0f, 0.0f, 2.0f, 0.0f,
3282 6.0f, 6.0f, 6.0f, 1.0f, 1);
3284 frame_set_transform(frame,
3285 2.0f, 0.0f, 0.0f, 0.0f,
3286 0.0f, 2.0f, 0.0f, 0.0f,
3287 0.0f, 0.0f, 2.0f, 0.0f,
3288 0.0f, 0.0f, 0.0f, 1.0f);
3289 hr = IDirect3DRMFrame_AddTranslation(frame, D3DRMCOMBINE_AFTER, 3.0f, 3.0f, 3.0f);
3290 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3291 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3292 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3293 expect_matrix(matrix,
3294 2.0f, 0.0f, 0.0f, 0.0f,
3295 0.0f, 2.0f, 0.0f, 0.0f,
3296 0.0f, 0.0f, 2.0f, 0.0f,
3297 3.0f, 3.0f, 3.0f, 1.0f, 1);
3299 frame_set_transform(frame,
3300 1.0f, 0.0f, 0.0f, 0.0f,
3301 0.0f, 1.0f, 0.0f, 0.0f,
3302 0.0f, 0.0f, 1.0f, 0.0f,
3303 3.0f, 3.0f, 3.0f, 1.0f);
3304 hr = IDirect3DRMFrame_AddScale(frame, D3DRMCOMBINE_REPLACE, 2.0f, 2.0f, 2.0f);
3305 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3306 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3307 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3308 expect_matrix(matrix,
3309 2.0f, 0.0f, 0.0f, 0.0f,
3310 0.0f, 2.0f, 0.0f, 0.0f,
3311 0.0f, 0.0f, 2.0f, 0.0f,
3312 0.0f, 0.0f, 0.0f, 1.0f, 1);
3314 frame_set_transform(frame,
3315 1.0f, 0.0f, 0.0f, 0.0f,
3316 0.0f, 1.0f, 0.0f, 0.0f,
3317 0.0f, 0.0f, 1.0f, 0.0f,
3318 3.0f, 3.0f, 3.0f, 1.0f);
3319 hr = IDirect3DRMFrame_AddScale(frame, D3DRMCOMBINE_BEFORE, 2.0f, 2.0f, 2.0f);
3320 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3321 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3322 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3323 expect_matrix(matrix,
3324 2.0f, 0.0f, 0.0f, 0.0f,
3325 0.0f, 2.0f, 0.0f, 0.0f,
3326 0.0f, 0.0f, 2.0f, 0.0f,
3327 3.0f, 3.0f, 3.0f, 1.0f, 1);
3329 frame_set_transform(frame,
3330 1.0f, 0.0f, 0.0f, 0.0f,
3331 0.0f, 1.0f, 0.0f, 0.0f,
3332 0.0f, 0.0f, 1.0f, 0.0f,
3333 3.0f, 3.0f, 3.0f, 1.0f);
3334 hr = IDirect3DRMFrame_AddScale(frame, D3DRMCOMBINE_AFTER, 2.0f, 2.0f, 2.0f);
3335 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3336 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3337 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3338 expect_matrix(matrix,
3339 2.0f, 0.0f, 0.0f, 0.0f,
3340 0.0f, 2.0f, 0.0f, 0.0f,
3341 0.0f, 0.0f, 2.0f, 0.0f,
3342 6.0f, 6.0f, 6.0f, 1.0f, 1);
3344 frame_set_transform(frame,
3345 1.0f, 0.0f, 0.0f, 0.0f,
3346 0.0f, 1.0f, 0.0f, 0.0f,
3347 0.0f, 0.0f, 1.0f, 0.0f,
3348 3.0f, 3.0f, 3.0f, 1.0f);
3349 hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 1.0f, 0.0f, 0.0f, M_PI_2);
3350 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3351 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3352 matrix_sanitise(matrix);
3353 expect_matrix(matrix,
3354 1.0f, 0.0f, 0.0f, 0.0f,
3355 0.0f, 0.0f, 1.0f, 0.0f,
3356 0.0f, -1.0f, 0.0f, 0.0f,
3357 0.0f, 0.0f, 0.0f, 1.0f, 1);
3359 frame_set_transform(frame,
3360 1.0f, 0.0f, 0.0f, 0.0f,
3361 0.0f, 1.0f, 0.0f, 0.0f,
3362 0.0f, 0.0f, 1.0f, 0.0f,
3363 3.0f, 3.0f, 3.0f, 1.0f);
3364 hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_BEFORE, 1.0f, 0.0f, 0.0f, M_PI_2);
3365 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3366 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3367 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3368 matrix_sanitise(matrix);
3369 expect_matrix(matrix,
3370 1.0f, 0.0f, 0.0f, 0.0f,
3371 0.0f, 0.0f, 1.0f, 0.0f,
3372 0.0f, -1.0f, 0.0f, 0.0f,
3373 3.0f, 3.0f, 3.0f, 1.0f, 1);
3375 frame_set_transform(frame,
3376 1.0f, 0.0f, 0.0f, 0.0f,
3377 0.0f, 1.0f, 0.0f, 0.0f,
3378 0.0f, 0.0f, 1.0f, 0.0f,
3379 3.0f, 3.0f, 3.0f, 1.0f);
3380 hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_AFTER, 1.0f, 0.0f, 0.0f, M_PI_2);
3381 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3382 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3383 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3384 matrix_sanitise(matrix);
3385 expect_matrix(matrix,
3386 1.0f, 0.0f, 0.0f, 0.0f,
3387 0.0f, 0.0f, 1.0f, 0.0f,
3388 0.0f, -1.0f, 0.0f, 0.0f,
3389 3.0f, -3.0f, 3.0f, 1.0f, 1);
3391 hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 0.0f, 0.0f, 1.0f, M_PI_2);
3392 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3393 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3394 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3395 matrix_sanitise(matrix);
3396 expect_matrix(matrix,
3397 0.0f, 1.0f, 0.0f, 0.0f,
3398 -1.0f, 0.0f, 0.0f, 0.0f,
3399 0.0f, 0.0f, 1.0f, 0.0f,
3400 0.0f, 0.0f, 0.0f, 1.0f, 1);
3402 hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 0.0f, 0.0f, 0.0f, M_PI_2);
3403 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3404 hr = IDirect3DRMFrame_GetTransform(frame, matrix);
3405 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3406 matrix_sanitise(matrix);
3407 expect_matrix(matrix,
3408 1.0f, 0.0f, 0.0f, 0.0f,
3409 0.0f, 0.0f, 1.0f, 0.0f,
3410 0.0f, -1.0f, 0.0f, 0.0f,
3411 0.0f, 0.0f, 0.0f, 1.0f, 1);
3413 frame_set_transform(frame,
3414 2.0f, 0.0f, 0.0f, 0.0f,
3415 0.0f, 4.0f, 0.0f, 0.0f,
3416 0.0f, 0.0f, 8.0f, 0.0f,
3417 64.0f, 64.0f, 64.0f, 1.0f);
3418 hr = IDirect3DRM_CreateFrame(d3drm, frame, &subframe);
3419 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3420 frame_set_transform(subframe,
3421 1.0f, 0.0f, 0.0f, 0.0f,
3422 0.0f, 1.0f, 0.0f, 0.0f,
3423 0.0f, 0.0f, 1.0f, 0.0f,
3424 11.0f, 11.0f, 11.0f, 1.0f);
3425 set_vector(&v1, 3.0f, 5.0f, 7.0f);
3427 hr = IDirect3DRMFrame_Transform(frame, &v2, &v1);
3428 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3429 expect_vector(&v2, 70.0f, 84.0f, 120.0f, 1);
3431 hr = IDirect3DRMFrame_Transform(subframe, &v2, &v1);
3432 ok(hr == D3DRM_OK, "Got unexpected hr %#lx.\n", hr);
3433 expect_vector(&v2, 92.0f, 128.0f, 208.0f, 1);
3435 IDirect3DRMFrame_Release(subframe);
3436 IDirect3DRMFrame_Release(frame);
3437 IDirect3DRM_Release(d3drm);
3440 static int nb_objects = 0;
3441 static const GUID* refiids[] =
3443 &IID_IDirect3DRMMeshBuilder,
3444 &IID_IDirect3DRMMeshBuilder,
3445 &IID_IDirect3DRMFrame,
3446 &IID_IDirect3DRMMaterial /* Not taken into account and not notified */
3449 static void __cdecl object_load_callback(IDirect3DRMObject *object, REFIID objectguid, void *arg)
3451 ok(object != NULL, "Arg 1 should not be null\n");
3452 ok(IsEqualGUID(objectguid, refiids[nb_objects]), "Arg 2 is incorrect\n");
3453 ok(arg == (void *)0xdeadbeef, "Arg 3 should be 0xdeadbeef (got %p)\n", arg);
3454 nb_objects++;
3457 static void test_d3drm_load(void)
3459 HRESULT hr;
3460 IDirect3DRM *d3drm;
3461 D3DRMLOADMEMORY info;
3462 const GUID* req_refiids[] = { &IID_IDirect3DRMMeshBuilder, &IID_IDirect3DRMFrame, &IID_IDirect3DRMMaterial };
3464 hr = Direct3DRMCreate(&d3drm);
3465 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx\n", hr);
3467 info.lpMemory = data_d3drm_load;
3468 info.dSize = strlen(data_d3drm_load);
3469 hr = IDirect3DRM_Load(d3drm, &info, NULL, (GUID **)req_refiids, 3, D3DRMLOAD_FROMMEMORY,
3470 object_load_callback, (void *)0xdeadbeef, NULL, NULL, NULL);
3471 ok(hr == D3DRM_OK, "Cannot load data, hr %#lx\n", hr);
3472 ok(nb_objects == 3, "Should have loaded 3 objects (got %d)\n", nb_objects);
3474 IDirect3DRM_Release(d3drm);
3477 IDirect3DRMMeshBuilder *mesh_builder = NULL;
3479 static void __cdecl object_load_callback_frame(IDirect3DRMObject *object, REFIID object_guid, void *arg)
3481 HRESULT hr;
3482 IDirect3DRMFrame *frame;
3483 IDirect3DRMVisualArray *array;
3484 IDirect3DRMVisual *visual;
3485 ULONG size;
3486 char name[128];
3488 hr = IDirect3DRMObject_QueryInterface(object, &IID_IDirect3DRMFrame, (void**)&frame);
3489 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
3491 hr = IDirect3DRMFrame_GetVisuals(frame, &array);
3492 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
3494 size = IDirect3DRMVisualArray_GetSize(array);
3495 ok(size == 1, "Wrong size %lu returned, expected 1\n", size);
3497 hr = IDirect3DRMVisualArray_GetElement(array, 0, &visual);
3498 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
3500 hr = IDirect3DRMVisual_QueryInterface(visual, &IID_IDirect3DRMMeshBuilder, (void**)&mesh_builder);
3501 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
3503 size = sizeof(name);
3504 hr = IDirect3DRMMeshBuilder_GetName(mesh_builder, &size, name);
3505 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
3506 ok(!strcmp(name, "mesh1"), "Wrong name %s, expected mesh1\n", name);
3508 IDirect3DRMVisual_Release(visual);
3509 IDirect3DRMVisualArray_Release(array);
3510 IDirect3DRMFrame_Release(frame);
3513 struct {
3514 int vertex_count;
3515 int face_count;
3516 int vertex_per_face;
3517 int face_data_size;
3518 DWORD color;
3519 float power;
3520 float specular[3];
3521 float emissive[3];
3522 } groups[3] = {
3523 { 4, 3, 3, 9, 0x4c0000ff, 30.0f, { 0.31f, 0.32f, 0.33f }, { 0.34f, 0.35f, 0.36f } },
3524 { 4, 2, 3, 6, 0x3300ff00, 20.0f, { 0.21f, 0.22f, 0.23f }, { 0.24f, 0.25f, 0.26f } },
3525 { 3, 1, 3, 3, 0x19ff0000, 10.0f, { 0.11f, 0.12f, 0.13f }, { 0.14f, 0.15f, 0.16f } }
3528 static void test_frame_mesh_materials(void)
3530 HRESULT hr;
3531 IDirect3DRM *d3drm;
3532 D3DRMLOADMEMORY info;
3533 const GUID *req_refiids[] = { &IID_IDirect3DRMFrame };
3534 IDirect3DRMMesh *mesh;
3535 ULONG size;
3536 IDirect3DRMMaterial *material;
3537 IDirect3DRMTexture *texture;
3538 unsigned int i;
3540 hr = Direct3DRMCreate(&d3drm);
3541 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
3543 info.lpMemory = data_frame_mesh_materials;
3544 info.dSize = strlen(data_frame_mesh_materials);
3545 hr = IDirect3DRM_Load(d3drm, &info, NULL, (GUID**)req_refiids, 1, D3DRMLOAD_FROMMEMORY, object_load_callback_frame, (void*)0xdeadbeef, NULL, NULL, NULL);
3546 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
3548 hr = IDirect3DRMMeshBuilder_CreateMesh(mesh_builder, &mesh);
3549 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
3551 size = IDirect3DRMMesh_GetGroupCount(mesh);
3552 ok(size == 3, "Unexpected count %lu.\n", size);
3554 for (i = 0; i < size; i++)
3556 D3DVALUE red, green, blue, power;
3557 D3DCOLOR color;
3558 unsigned vertex_count, face_count, vertex_per_face;
3559 DWORD face_data_size;
3561 winetest_push_context("Group %u", i);
3563 hr = IDirect3DRMMesh_GetGroup(mesh, i, &vertex_count, &face_count, &vertex_per_face, &face_data_size, NULL);
3564 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
3565 ok(vertex_count == groups[i].vertex_count, "Wrong vertex count %d, expected %d\n", vertex_count, groups[i].vertex_count);
3566 ok(face_count == groups[i].face_count, "Wrong face count %d; expected %d\n", face_count, groups[i].face_count);
3567 ok(vertex_per_face == groups[i].vertex_per_face, "Wrong vertex per face %d, expected %d\n", vertex_per_face, groups[i].vertex_per_face);
3568 ok(face_data_size == groups[i].face_data_size, "Wrong face data size %ld, expected %d\n", face_data_size, groups[i].face_data_size);
3570 color = IDirect3DRMMesh_GetGroupColor(mesh, i);
3571 ok(color == groups[i].color, "Wrong color %lx, expected %lx.\n", color, groups[i].color);
3573 hr = IDirect3DRMMesh_GetGroupMaterial(mesh, i, &material);
3574 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
3575 ok(material != NULL, "No material.\n");
3576 power = IDirect3DRMMaterial_GetPower(material);
3577 ok(power == groups[i].power, "Wrong power %f, expected %f\n", power, groups[i].power);
3578 hr = IDirect3DRMMaterial_GetSpecular(material, &red, &green, &blue);
3579 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
3580 ok(red == groups[i].specular[0], "Wrong specular red %f, expected %f\n", red, groups[i].specular[0]);
3581 ok(green == groups[i].specular[1], "Wrong specular green %f, pD3DRMexpected %f\n", green, groups[i].specular[1]);
3582 ok(blue == groups[i].specular[2], "Wrong specular blue %f, expected %f\n", blue, groups[i].specular[2]);
3583 hr = IDirect3DRMMaterial_GetEmissive(material, &red, &green, &blue);
3584 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
3585 ok(red == groups[i].emissive[0], "Wrong emissive red %f, expected %f\n", red, groups[i].emissive[0]);
3586 ok(green == groups[i].emissive[1], "Wrong emissive green %f, expected %f\n", green, groups[i].emissive[1]);
3587 ok(blue == groups[i].emissive[2], "Wrong emissive blue %f, expected %f\n", blue, groups[i].emissive[2]);
3589 hr = IDirect3DRMMesh_GetGroupTexture(mesh, i, &texture);
3590 ok(hr == D3DRM_OK, "Unexpected hr %#lx.\n", hr);
3591 ok(!texture, "Unexpected texture\n");
3593 if (material)
3594 IDirect3DRMMaterial_Release(material);
3595 if (texture)
3596 IDirect3DRMTexture_Release(texture);
3598 winetest_pop_context();
3601 IDirect3DRMMesh_Release(mesh);
3602 IDirect3DRMMeshBuilder_Release(mesh_builder);
3603 IDirect3DRM_Release(d3drm);
3606 struct qi_test
3608 REFIID iid;
3609 REFIID refcount_iid;
3610 REFIID vtable_iid;
3611 HRESULT hr;
3614 static void test_qi(const char *test_name, IUnknown *base_iface,
3615 REFIID refcount_iid, const struct qi_test *tests, UINT entry_count)
3617 ULONG refcount, expected_refcount;
3618 IUnknown *iface1, *iface2;
3619 HRESULT hr;
3620 UINT i, j;
3622 for (i = 0; i < entry_count; ++i)
3624 hr = IUnknown_QueryInterface(base_iface, tests[i].iid, (void **)&iface1);
3625 ok(hr == tests[i].hr, "Got hr %#lx for test \"%s\" %u.\n", hr, test_name, i);
3626 if (SUCCEEDED(hr))
3628 for (j = 0; j < entry_count; ++j)
3630 hr = IUnknown_QueryInterface(iface1, tests[j].iid, (void **)&iface2);
3631 ok(hr == tests[j].hr, "Got hr %#lx for test \"%s\" %u, %u.\n", hr, test_name, i, j);
3632 if (SUCCEEDED(hr))
3634 expected_refcount = 0;
3635 if (IsEqualGUID(refcount_iid, tests[j].refcount_iid))
3636 ++expected_refcount;
3637 if (IsEqualGUID(tests[i].refcount_iid, tests[j].refcount_iid))
3638 ++expected_refcount;
3639 refcount = IUnknown_Release(iface2);
3640 ok(refcount == expected_refcount, "Got refcount %lu for test \"%s\" %u, %u, expected %lu.\n",
3641 refcount, test_name, i, j, expected_refcount);
3642 if (tests[i].vtable_iid && tests[j].vtable_iid && IsEqualGUID(tests[i].vtable_iid, tests[j].vtable_iid))
3643 ok(iface1 == iface2,
3644 "Expected iface1 == iface2 for test \"%s\" %u, %u. Got iface1 = %p, iface 2 = %p.\n",
3645 test_name, i, j, iface1, iface2);
3646 else if (tests[i].vtable_iid && tests[j].vtable_iid)
3647 ok(iface1 != iface2,
3648 "Expected iface1 != iface2 for test \"%s\" %u, %u. Got iface1 == iface2 == %p.\n",
3649 test_name, i, j, iface1);
3653 expected_refcount = 0;
3654 if (IsEqualGUID(refcount_iid, tests[i].refcount_iid))
3655 ++expected_refcount;
3656 refcount = IUnknown_Release(iface1);
3657 ok(refcount == expected_refcount, "Got refcount %lu for test \"%s\" %u, expected %lu.\n",
3658 refcount, test_name, i, expected_refcount);
3663 static void test_d3drm_qi(void)
3665 static const struct qi_test tests[] =
3667 { &IID_IDirect3DRM3, &IID_IDirect3DRM3, &IID_IDirect3DRM3, S_OK },
3668 { &IID_IDirect3DRM2, &IID_IDirect3DRM2, &IID_IDirect3DRM2, S_OK },
3669 { &IID_IDirect3DRM, &IID_IDirect3DRM, &IID_IDirect3DRM, S_OK },
3670 { &IID_IDirect3DRMDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3671 { &IID_IDirect3DRMObject, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3672 { &IID_IDirect3DRMObject2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3673 { &IID_IDirect3DRMDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3674 { &IID_IDirect3DRMDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3675 { &IID_IDirect3DRMViewport, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3676 { &IID_IDirect3DRMViewport2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3677 { &IID_IDirect3DRMFrame, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3678 { &IID_IDirect3DRMFrame2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3679 { &IID_IDirect3DRMFrame3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3680 { &IID_IDirect3DRMVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3681 { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3682 { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3683 { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3684 { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3685 { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3686 { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3687 { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3688 { &IID_IDirect3DRMTexture, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3689 { &IID_IDirect3DRMTexture2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3690 { &IID_IDirect3DRMTexture3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3691 { &IID_IDirect3DRMWrap, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3692 { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3693 { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3694 { &IID_IDirect3DRMAnimation, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3695 { &IID_IDirect3DRMAnimation2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3696 { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3697 { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3698 { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3699 { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3700 { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3701 { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3702 { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3703 { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3704 { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3705 { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3706 { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3707 { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3708 { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3709 { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3710 { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3711 { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3712 { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3713 { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3714 { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3715 { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3716 { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3717 { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3718 { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3719 { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3720 { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3721 { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3722 { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3723 { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3724 { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3725 { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3726 { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3727 { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3728 { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3729 { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3730 { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3731 { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3732 { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3733 { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3734 { &IID_IUnknown, &IID_IDirect3DRM, &IID_IDirect3DRM, S_OK },
3736 HRESULT hr;
3737 IDirect3DRM *d3drm;
3739 hr = Direct3DRMCreate(&d3drm);
3740 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx\n", hr);
3742 test_qi("d3drm_qi", (IUnknown *)d3drm, &IID_IDirect3DRM, tests, ARRAY_SIZE(tests));
3744 IDirect3DRM_Release(d3drm);
3747 static void test_frame_qi(void)
3749 static const struct qi_test tests[] =
3751 { &IID_IDirect3DRMFrame3, &IID_IUnknown, &IID_IDirect3DRMFrame3, S_OK },
3752 { &IID_IDirect3DRMFrame2, &IID_IUnknown, &IID_IDirect3DRMFrame2, S_OK },
3753 { &IID_IDirect3DRMFrame, &IID_IUnknown, &IID_IDirect3DRMFrame, S_OK },
3754 { &IID_IDirect3DRM, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3755 { &IID_IDirect3DRMDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3756 { &IID_IDirect3DRMObject, &IID_IUnknown, &IID_IDirect3DRMFrame, S_OK },
3757 { &IID_IDirect3DRMDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3758 { &IID_IDirect3DRMDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3759 { &IID_IDirect3DRMViewport, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3760 { &IID_IDirect3DRMViewport2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3761 { &IID_IDirect3DRM3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3762 { &IID_IDirect3DRM2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3763 { &IID_IDirect3DRMVisual, &IID_IUnknown, &IID_IDirect3DRMFrame, S_OK },
3764 { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3765 { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3766 { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3767 { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3768 { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3769 { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3770 { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3771 { &IID_IDirect3DRMTexture, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3772 { &IID_IDirect3DRMTexture2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3773 { &IID_IDirect3DRMTexture3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3774 { &IID_IDirect3DRMWrap, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3775 { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3776 { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3777 { &IID_IDirect3DRMAnimation, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3778 { &IID_IDirect3DRMAnimation2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3779 { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3780 { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3781 { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3782 { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3783 { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3784 { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3785 { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3786 { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3787 { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3788 { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3789 { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3790 { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3791 { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3792 { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3793 { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3794 { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3795 { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3796 { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3797 { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3798 { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3799 { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3800 { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3801 { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3802 { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3803 { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3804 { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3805 { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3806 { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3807 { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3808 { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3809 { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3810 { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3811 { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3812 { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3813 { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3814 { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3815 { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3816 { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3817 { &IID_IUnknown, &IID_IUnknown, NULL, S_OK },
3819 HRESULT hr;
3820 IDirect3DRM *d3drm1;
3821 IDirect3DRM2 *d3drm2;
3822 IDirect3DRM3 *d3drm3;
3823 IDirect3DRMFrame *frame1;
3824 IDirect3DRMFrame2 *frame2;
3825 IDirect3DRMFrame3 *frame3;
3826 IUnknown *unknown;
3828 hr = Direct3DRMCreate(&d3drm1);
3829 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx\n", hr);
3831 hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &frame1);
3832 ok(hr == D3DRM_OK, "Failed to create frame1, hr %#lx\n", hr);
3833 hr = IDirect3DRMFrame_QueryInterface(frame1, &IID_IUnknown, (void **)&unknown);
3834 ok(hr == D3DRM_OK, "Failed to create IUnknown from frame1, hr %#lx\n", hr);
3835 IDirect3DRMFrame_Release(frame1);
3836 test_qi("frame1_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
3837 IUnknown_Release(unknown);
3839 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
3840 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM2 interface, hr %#lx.\n", hr);
3841 hr = IDirect3DRM2_CreateFrame(d3drm2, NULL, &frame2);
3842 ok(hr == D3DRM_OK, "Failed to create frame2, hr %#lx\n", hr);
3843 hr = IDirect3DRMFrame2_QueryInterface(frame2, &IID_IUnknown, (void **)&unknown);
3844 ok(hr == D3DRM_OK, "Failed to create IUnknown from frame2, hr %#lx\n", hr);
3845 IDirect3DRMFrame2_Release(frame2);
3846 test_qi("frame2_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
3847 IUnknown_Release(unknown);
3849 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
3850 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr);
3851 hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &frame3);
3852 ok(hr == D3DRM_OK, "Failed to create frame3, hr %#lx\n", hr);
3853 hr = IDirect3DRMFrame3_QueryInterface(frame3, &IID_IUnknown, (void **)&unknown);
3854 ok(hr == D3DRM_OK, "Failed to create IUnknown from frame3, hr %#lx\n", hr);
3855 IDirect3DRMFrame3_Release(frame3);
3856 test_qi("frame3_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
3857 IUnknown_Release(unknown);
3859 IDirect3DRM3_Release(d3drm3);
3860 IDirect3DRM2_Release(d3drm2);
3861 IDirect3DRM_Release(d3drm1);
3864 static void test_device_qi(void)
3866 static const struct qi_test tests[] =
3868 { &IID_IDirect3DRM3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3869 { &IID_IDirect3DRM2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3870 { &IID_IDirect3DRM, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3871 { &IID_IDirect3DRMDevice, &IID_IUnknown, &IID_IDirect3DRMDevice, S_OK, },
3872 { &IID_IDirect3DRMDevice2, &IID_IUnknown, &IID_IDirect3DRMDevice2, S_OK, },
3873 { &IID_IDirect3DRMDevice3, &IID_IUnknown, &IID_IDirect3DRMDevice3, S_OK, },
3874 { &IID_IDirect3DRMWinDevice, &IID_IUnknown, &IID_IDirect3DRMWinDevice, S_OK, },
3875 { &IID_IDirect3DRMObject, &IID_IUnknown, &IID_IDirect3DRMDevice, S_OK, },
3876 { &IID_IDirect3DRMViewport, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3877 { &IID_IDirect3DRMViewport2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3878 { &IID_IDirect3DRMFrame, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3879 { &IID_IDirect3DRMFrame2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3880 { &IID_IDirect3DRMFrame3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3881 { &IID_IDirect3DRMVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3882 { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3883 { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3884 { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3885 { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3886 { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3887 { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3888 { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3889 { &IID_IDirect3DRMTexture, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3890 { &IID_IDirect3DRMTexture2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3891 { &IID_IDirect3DRMTexture3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3892 { &IID_IDirect3DRMWrap, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3893 { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3894 { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3895 { &IID_IDirect3DRMAnimation, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3896 { &IID_IDirect3DRMAnimation2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3897 { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3898 { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3899 { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3900 { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3901 { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3902 { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3903 { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3904 { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3905 { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3906 { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3907 { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3908 { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3909 { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3910 { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3911 { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3912 { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3913 { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3914 { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3915 { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3916 { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3917 { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3918 { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3919 { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3920 { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3921 { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3922 { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3923 { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3924 { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3925 { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3926 { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3927 { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3928 { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3929 { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3930 { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3931 { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3932 { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3933 { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3934 { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
3935 { &IID_IUnknown, &IID_IUnknown, NULL, S_OK, },
3937 HRESULT hr;
3938 IDirect3DRM *d3drm1;
3939 IDirect3DRM2 *d3drm2;
3940 IDirect3DRM3 *d3drm3;
3941 IDirectDrawClipper *clipper;
3942 IDirect3DRMDevice *device1;
3943 IDirect3DRMDevice2 *device2;
3944 IDirect3DRMDevice3 *device3;
3945 IUnknown *unknown;
3946 HWND window;
3947 GUID driver;
3948 RECT rc;
3950 window = create_window();
3951 GetClientRect(window, &rc);
3952 hr = DirectDrawCreateClipper(0, &clipper, NULL);
3953 ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface, hr %#lx\n", hr);
3954 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
3955 ok(hr == DD_OK, "Cannot set HWnd to Clipper, hr %#lx\n", hr);
3957 hr = Direct3DRMCreate(&d3drm1);
3958 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface, hr %#lx\n", hr);
3959 memcpy(&driver, &IID_IDirect3DRGBDevice, sizeof(GUID));
3960 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, rc.right, rc.bottom, &device1);
3961 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface, hr %#lx\n", hr);
3962 hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IUnknown, (void **)&unknown);
3963 ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMDevice, hr %#lx\n", hr);
3964 IDirect3DRMDevice_Release(device1);
3965 test_qi("device1_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
3966 IUnknown_Release(unknown);
3968 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
3969 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface, hr %#lx.\n", hr);
3970 hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, clipper, &driver, rc.right, rc.bottom, &device2);
3971 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice2 interface, hr %#lx\n", hr);
3972 hr = IDirect3DRMDevice2_QueryInterface(device2, &IID_IUnknown, (void **)&unknown);
3973 ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMDevice2, hr %#lx\n", hr);
3974 IDirect3DRMDevice2_Release(device2);
3975 test_qi("device2_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
3976 IUnknown_Release(unknown);
3978 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
3979 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr);
3980 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, rc.right, rc.bottom, &device3);
3981 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface, hr %#lx\n", hr);
3982 hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IUnknown, (void **)&unknown);
3983 ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMDevice3, hr %#lx\n", hr);
3984 IDirect3DRMDevice3_Release(device3);
3985 test_qi("device3_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
3986 IUnknown_Release(unknown);
3988 IDirectDrawClipper_Release(clipper);
3989 IDirect3DRM3_Release(d3drm3);
3990 IDirect3DRM2_Release(d3drm2);
3991 IDirect3DRM_Release(d3drm1);
3992 DestroyWindow(window);
3996 static HRESULT CALLBACK surface_callback(IDirectDrawSurface *surface, DDSURFACEDESC *desc, void *context)
3998 IDirectDrawSurface **primary = context;
4000 if (desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
4002 *primary = surface;
4003 return DDENUMRET_CANCEL;
4005 IDirectDrawSurface_Release(surface);
4007 return DDENUMRET_OK;
4010 static void test_create_device_from_clipper1(void)
4012 DDSCAPS caps = { DDSCAPS_ZBUFFER };
4013 IDirect3DRM *d3drm1 = NULL;
4014 IDirectDraw *ddraw = NULL;
4015 IUnknown *unknown = NULL;
4016 IDirect3DRMDevice *device1 = (IDirect3DRMDevice *)0xdeadbeef;
4017 IDirect3DDevice *d3ddevice1 = NULL;
4018 IDirectDrawClipper *clipper = NULL, *d3drm_clipper = NULL;
4019 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_primary = NULL;
4020 IDirectDrawSurface7 *surface7 = NULL;
4021 DDSURFACEDESC desc, surface_desc;
4022 DWORD expected_flags, ret_val;
4023 HWND window;
4024 GUID driver = IID_IDirect3DRGBDevice;
4025 HRESULT hr;
4026 ULONG ref1, ref2, cref1, cref2;
4027 RECT rc;
4029 window = create_window();
4030 GetClientRect(window, &rc);
4031 hr = DirectDrawCreateClipper(0, &clipper, NULL);
4032 ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface, hr %#lx.\n", hr);
4033 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
4034 ok(hr == DD_OK, "Cannot set HWnd to Clipper, hr %#lx.\n", hr);
4036 hr = Direct3DRMCreate(&d3drm1);
4037 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
4038 ref1 = get_refcount((IUnknown *)d3drm1);
4039 cref1 = get_refcount((IUnknown *)clipper);
4041 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, 0, 0, &device1);
4042 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
4043 ok(device1 == NULL, "Expected device returned == NULL, got %p.\n", device1);
4045 /* If NULL is passed for clipper, CreateDeviceFromClipper returns D3DRMERR_BADVALUE */
4046 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, NULL, &driver, 300, 200, &device1);
4047 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
4049 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, 300, 200, NULL);
4050 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
4052 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, 300, 200, &device1);
4053 ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice interface, hr %#lx.\n", hr);
4054 ref2 = get_refcount((IUnknown *)d3drm1);
4055 ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %lu , ref2 = %lu.\n", ref1, ref2);
4056 cref2 = get_refcount((IUnknown *)clipper);
4057 ok(cref2 > cref1, "expected cref2 > cref1, got cref1 = %lu , cref2 = %lu.\n", cref1, cref2);
4058 ret_val = IDirect3DRMDevice_GetWidth(device1);
4059 ok(ret_val == 300, "Expected device width = 300, got %lu.\n", ret_val);
4060 ret_val = IDirect3DRMDevice_GetHeight(device1);
4061 ok(ret_val == 200, "Expected device height == 200, got %lu.\n", ret_val);
4063 /* Fetch immediate mode device in order to access render target */
4064 hr = IDirect3DRMDevice_GetDirect3DDevice(device1, &d3ddevice1);
4065 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice interface, hr %#lx.\n", hr);
4067 hr = IDirect3DDevice_QueryInterface(d3ddevice1, &IID_IDirectDrawSurface, (void **)&surface);
4068 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
4070 hr = IDirectDrawSurface_GetClipper(surface, &d3drm_clipper);
4071 ok(hr == DDERR_NOCLIPPERATTACHED, "Expected hr == DDERR_NOCLIPPERATTACHED, got hr %#lx.\n", hr);
4073 /* Check if CreateDeviceFromClipper creates a primary surface and attaches the clipper to it */
4074 hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **)&surface7);
4075 ok(hr == DD_OK, "Cannot get IDirectDrawSurface7 interface, hr %#lx.\n", hr);
4076 IDirectDrawSurface7_GetDDInterface(surface7, (void **)&unknown);
4077 hr = IUnknown_QueryInterface(unknown, &IID_IDirectDraw, (void **)&ddraw);
4078 ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
4079 IUnknown_Release(unknown);
4080 hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
4081 NULL, &d3drm_primary, surface_callback);
4082 ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#lx.\n", hr);
4083 ok(d3drm_primary != NULL, "No primary surface was enumerated.\n");
4084 hr = IDirectDrawSurface_GetClipper(d3drm_primary, &d3drm_clipper);
4085 ok(hr == DD_OK, "Cannot get attached clipper from primary surface, hr %#lx.\n", hr);
4086 ok(d3drm_clipper == clipper, "Expected clipper returned == %p, got %p.\n", clipper , d3drm_clipper);
4088 IDirectDrawClipper_Release(d3drm_clipper);
4089 IDirectDrawSurface_Release(d3drm_primary);
4090 IDirectDrawSurface7_Release(surface7);
4091 IDirectDraw_Release(ddraw);
4093 /* Check properties of render target and depth surface */
4094 surface_desc.dwSize = sizeof(surface_desc);
4095 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &surface_desc);
4096 ok(hr == DD_OK, "Cannot get surface desc structure, hr %#lx.\n", hr);
4098 ok((surface_desc.dwWidth == 300) && (surface_desc.dwHeight == 200), "Expected surface dimensions = 300, 200, got %lu, %lu.\n",
4099 surface_desc.dwWidth, surface_desc.dwHeight);
4100 ok((surface_desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE),
4101 "Unexpected caps %#lx.\n", surface_desc.ddsCaps.dwCaps);
4102 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4103 ok(surface_desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, surface_desc.dwFlags);
4105 hr = DirectDrawCreate(NULL, &ddraw, NULL);
4106 ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
4107 desc.dwSize = sizeof(desc);
4108 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4109 ok(hr == DD_OK, "Cannot get IDirectDraw display mode, hr %#lx\n", hr);
4110 ok(desc.ddpfPixelFormat.dwRGBBitCount == surface_desc.ddpfPixelFormat.dwRGBBitCount, "Expected %lu bpp, got %lu bpp.\n",
4111 surface_desc.ddpfPixelFormat.dwRGBBitCount, desc.ddpfPixelFormat.dwRGBBitCount);
4113 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4114 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
4116 desc.dwSize = sizeof(desc);
4117 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
4118 ok(hr == DD_OK, "Cannot get z surface desc structure, hr %#lx.\n", hr);
4120 ok((desc.dwWidth == 300) && (desc.dwHeight == 200), "Expected surface dimensions = 300, 200, got %lu, %lu.\n",
4121 desc.dwWidth, desc.dwHeight);
4122 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Unexpected caps %#lx.\n", desc.ddsCaps.dwCaps);
4123 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4124 ok(desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, desc.dwFlags);
4125 ok(desc.dwZBufferBitDepth == 16, "Expected 16 for Z buffer bit depth, got %lu.\n", desc.dwZBufferBitDepth);
4126 ok(!desc.ddpfPixelFormat.dwStencilBitMask, "Unexpected stencil mask %#lx.\n", desc.ddpfPixelFormat.dwStencilBitMask);
4128 /* Release old objects and check refcount of device and clipper */
4129 IDirectDrawSurface_Release(ds);
4130 ds = NULL;
4131 IDirectDrawSurface_Release(surface);
4132 surface = NULL;
4133 IDirect3DDevice_Release(d3ddevice1);
4134 d3ddevice1 = NULL;
4135 IDirect3DRMDevice_Release(device1);
4136 ref2 = get_refcount((IUnknown *)d3drm1);
4137 ok(ref1 == ref2, "expected ref1 == ref2, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
4138 cref2 = get_refcount((IUnknown *)clipper);
4139 ok(cref1 == cref2, "expected cref1 == cref2, got cref1 = %lu, cref2 = %lu.\n", cref1, cref2);
4141 /* Test if render target format follows the screen format */
4142 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4143 ok(hr == DD_OK, "Cannot get IDirectDraw display mode, hr %#lx\n", hr);
4144 hr = IDirectDraw_SetDisplayMode(ddraw, desc.dwWidth, desc.dwHeight, 16);
4145 ok(hr == DD_OK, "Cannot set display mode to 16bpp, hr %#lx.\n", hr);
4147 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4148 ok(hr == DD_OK, "Cannot get IDirectDraw display mode, hr %#lx\n", hr);
4149 ok(desc.ddpfPixelFormat.dwRGBBitCount == 16, "Expected 16 bpp, got %lu.\n", desc.ddpfPixelFormat.dwRGBBitCount);
4151 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, rc.right, rc.bottom, &device1);
4152 ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice interface, hr %#lx.\n", hr);
4154 hr = IDirect3DRMDevice_GetDirect3DDevice(device1, &d3ddevice1);
4155 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice interface, hr %#lx.\n", hr);
4157 hr = IDirect3DDevice_QueryInterface(d3ddevice1, &IID_IDirectDrawSurface, (void **)&surface);
4158 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
4160 surface_desc.dwSize = sizeof(surface_desc);
4161 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &surface_desc);
4162 ok(hr == DD_OK, "Cannot get surface desc structure, hr %#lx.\n", hr);
4163 ok(surface_desc.ddpfPixelFormat.dwRGBBitCount == 16, "Expected 16bpp, got %lubpp.\n",
4164 surface_desc.ddpfPixelFormat.dwRGBBitCount);
4166 hr = IDirectDraw2_RestoreDisplayMode(ddraw);
4167 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#lx.\n", hr);
4169 if (ds)
4170 IDirectDrawSurface_Release(ds);
4171 IDirectDrawSurface_Release(surface);
4172 IDirect3DDevice_Release(d3ddevice1);
4173 IDirect3DRMDevice_Release(device1);
4174 IDirect3DRM_Release(d3drm1);
4175 IDirectDrawClipper_Release(clipper);
4176 IDirectDraw_Release(ddraw);
4177 DestroyWindow(window);
4180 static void test_create_device_from_clipper2(void)
4182 DDSCAPS caps = { DDSCAPS_ZBUFFER };
4183 IDirect3DRM *d3drm1 = NULL;
4184 IDirect3DRM2 *d3drm2 = NULL;
4185 IDirectDraw *ddraw = NULL;
4186 IUnknown *unknown = NULL;
4187 IDirect3DRMDevice2 *device2 = (IDirect3DRMDevice2 *)0xdeadbeef;
4188 IDirect3DDevice2 *d3ddevice2 = NULL;
4189 IDirectDrawClipper *clipper = NULL, *d3drm_clipper = NULL;
4190 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_primary = NULL;
4191 IDirectDrawSurface7 *surface7 = NULL;
4192 DDSURFACEDESC desc, surface_desc;
4193 DWORD expected_flags, ret_val;
4194 HWND window;
4195 GUID driver = IID_IDirect3DRGBDevice;
4196 HRESULT hr;
4197 ULONG ref1, ref2, ref3, cref1, cref2;
4198 RECT rc;
4200 window = create_window();
4201 GetClientRect(window, &rc);
4202 hr = DirectDrawCreateClipper(0, &clipper, NULL);
4203 ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface, hr %#lx.\n", hr);
4204 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
4205 ok(hr == DD_OK, "Cannot set HWnd to Clipper, hr %#lx.\n", hr);
4207 hr = Direct3DRMCreate(&d3drm1);
4208 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
4209 ref1 = get_refcount((IUnknown *)d3drm1);
4210 cref1 = get_refcount((IUnknown *)clipper);
4212 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
4213 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM2 interface, hr %#lx.\n", hr);
4214 ref2 = get_refcount((IUnknown *)d3drm2);
4216 hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, clipper, &driver, 0, 0, &device2);
4217 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
4218 ok(device2 == NULL, "Expected device returned == NULL, got %p.\n", device2);
4220 /* If NULL is passed for clipper, CreateDeviceFromClipper returns D3DRMERR_BADVALUE */
4221 hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, NULL, &driver, 300, 200, &device2);
4222 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
4224 hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, clipper, &driver, 300, 200, NULL);
4225 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
4227 hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, clipper, &driver, 300, 200, &device2);
4228 ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice2 interface, hr %#lx.\n", hr);
4229 ref3 = get_refcount((IUnknown *)d3drm1);
4230 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %lu , ref3 = %lu.\n", ref1, ref3);
4231 ref3 = get_refcount((IUnknown *)d3drm2);
4232 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
4233 cref2 = get_refcount((IUnknown *)clipper);
4234 ok(cref2 > cref1, "expected cref2 > cref1, got cref1 = %lu , cref2 = %lu.\n", cref1, cref2);
4235 ret_val = IDirect3DRMDevice2_GetWidth(device2);
4236 ok(ret_val == 300, "Expected device width = 300, got %lu.\n", ret_val);
4237 ret_val = IDirect3DRMDevice2_GetHeight(device2);
4238 ok(ret_val == 200, "Expected device height == 200, got %lu.\n", ret_val);
4240 /* Fetch immediate mode device in order to access render target */
4241 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3ddevice2);
4242 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface, hr %#lx.\n", hr);
4244 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &surface);
4245 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
4247 hr = IDirectDrawSurface_GetClipper(surface, &d3drm_clipper);
4248 ok(hr == DDERR_NOCLIPPERATTACHED, "Expected hr == DDERR_NOCLIPPERATTACHED, got hr %#lx.\n", hr);
4250 /* Check if CreateDeviceFromClipper creates a primary surface and attaches the clipper to it */
4251 hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **)&surface7);
4252 ok(hr == DD_OK, "Cannot get IDirectDrawSurface7 interface, hr %#lx.\n", hr);
4253 IDirectDrawSurface7_GetDDInterface(surface7, (void **)&unknown);
4254 hr = IUnknown_QueryInterface(unknown, &IID_IDirectDraw, (void **)&ddraw);
4255 ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
4256 IUnknown_Release(unknown);
4257 hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
4258 NULL, &d3drm_primary, surface_callback);
4259 ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#lx.\n", hr);
4260 ok(d3drm_primary != NULL, "No primary surface was enumerated.\n");
4261 hr = IDirectDrawSurface_GetClipper(d3drm_primary, &d3drm_clipper);
4262 ok(hr == DD_OK, "Cannot get attached clipper from primary surface, hr %#lx.\n", hr);
4263 ok(d3drm_clipper == clipper, "Expected clipper returned == %p, got %p.\n", clipper , d3drm_clipper);
4265 IDirectDrawClipper_Release(d3drm_clipper);
4266 IDirectDrawSurface_Release(d3drm_primary);
4267 IDirectDrawSurface7_Release(surface7);
4268 IDirectDraw_Release(ddraw);
4270 /* Check properties of render target and depth surface */
4271 surface_desc.dwSize = sizeof(surface_desc);
4272 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &surface_desc);
4273 ok(hr == DD_OK, "Cannot get surface desc structure, hr %#lx.\n", hr);
4275 ok((surface_desc.dwWidth == 300) && (surface_desc.dwHeight == 200), "Expected surface dimensions = 300, 200, got %lu, %lu.\n",
4276 surface_desc.dwWidth, surface_desc.dwHeight);
4277 ok((surface_desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE),
4278 "Unexpected caps %#lx.\n", surface_desc.ddsCaps.dwCaps);
4279 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4280 ok(surface_desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, surface_desc.dwFlags);
4282 hr = DirectDrawCreate(NULL, &ddraw, NULL);
4283 ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
4284 desc.dwSize = sizeof(desc);
4285 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4286 ok(hr == DD_OK, "Cannot get IDirectDraw display mode, hr %#lx\n", hr);
4287 ok(desc.ddpfPixelFormat.dwRGBBitCount == surface_desc.ddpfPixelFormat.dwRGBBitCount, "Expected %lu bpp, got %lu bpp.\n",
4288 surface_desc.ddpfPixelFormat.dwRGBBitCount, desc.ddpfPixelFormat.dwRGBBitCount);
4290 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4291 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
4293 desc.dwSize = sizeof(desc);
4294 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
4295 ok(hr == DD_OK, "Cannot get z surface desc structure, hr %#lx.\n", hr);
4297 ok((desc.dwWidth == 300) && (desc.dwHeight == 200), "Expected surface dimensions = 300, 200, got %lu, %lu.\n",
4298 desc.dwWidth, desc.dwHeight);
4299 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Unexpected caps %#lx.\n", desc.ddsCaps.dwCaps);
4300 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4301 ok(desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, desc.dwFlags);
4302 ok(desc.dwZBufferBitDepth == 16, "Expected 16 for Z buffer bit depth, got %lu.\n", desc.dwZBufferBitDepth);
4303 ok(!desc.ddpfPixelFormat.dwStencilBitMask, "Expected stencil mask %#lx.\n", desc.ddpfPixelFormat.dwStencilBitMask);
4305 /* Release old objects and check refcount of device and clipper */
4306 IDirectDrawSurface_Release(ds);
4307 ds = NULL;
4308 IDirectDrawSurface_Release(surface);
4309 surface = NULL;
4310 IDirect3DDevice2_Release(d3ddevice2);
4311 d3ddevice2 = NULL;
4312 IDirect3DRMDevice2_Release(device2);
4313 ref3 = get_refcount((IUnknown *)d3drm1);
4314 ok(ref1 == ref3, "expected ref1 == ref3, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
4315 ref3 = get_refcount((IUnknown *)d3drm2);
4316 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
4317 cref2 = get_refcount((IUnknown *)clipper);
4318 ok(cref1 == cref2, "expected cref1 == cref2, got cref1 = %lu, cref2 = %lu.\n", cref1, cref2);
4320 /* Test if render target format follows the screen format */
4321 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4322 ok(hr == DD_OK, "Cannot get IDirectDraw display mode, hr %#lx\n", hr);
4323 hr = IDirectDraw_SetDisplayMode(ddraw, desc.dwWidth, desc.dwHeight, 16);
4324 ok(hr == DD_OK, "Cannot set display mode to 16bpp, hr %#lx.\n", hr);
4326 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4327 ok(hr == DD_OK, "Cannot get IDirectDraw display mode, hr %#lx\n", hr);
4328 ok(desc.ddpfPixelFormat.dwRGBBitCount == 16, "Expected 16 bpp, got %lu.\n", desc.ddpfPixelFormat.dwRGBBitCount);
4330 hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, clipper, &driver, rc.right, rc.bottom, &device2);
4331 ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice2 interface, hr %#lx.\n", hr);
4333 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3ddevice2);
4334 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface, hr %#lx.\n", hr);
4336 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &surface);
4337 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
4339 surface_desc.dwSize = sizeof(surface_desc);
4340 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &surface_desc);
4341 ok(hr == DD_OK, "Cannot get surface desc structure, hr %#lx.\n", hr);
4342 ok(surface_desc.ddpfPixelFormat.dwRGBBitCount == 16, "Expected 16bpp, got %lubpp.\n",
4343 surface_desc.ddpfPixelFormat.dwRGBBitCount);
4345 hr = IDirectDraw2_RestoreDisplayMode(ddraw);
4346 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#lx.\n", hr);
4348 IDirectDrawSurface_Release(surface);
4349 IDirect3DDevice2_Release(d3ddevice2);
4350 IDirect3DRMDevice2_Release(device2);
4351 IDirect3DRM2_Release(d3drm2);
4352 IDirect3DRM_Release(d3drm1);
4353 IDirectDrawClipper_Release(clipper);
4354 IDirectDraw_Release(ddraw);
4355 DestroyWindow(window);
4358 static void test_create_device_from_clipper3(void)
4360 DDSCAPS caps = { DDSCAPS_ZBUFFER };
4361 IDirect3DRM *d3drm1 = NULL;
4362 IDirect3DRM3 *d3drm3 = NULL;
4363 IDirectDraw *ddraw = NULL;
4364 IUnknown *unknown = NULL;
4365 IDirect3DRMDevice3 *device3 = (IDirect3DRMDevice3 *)0xdeadbeef;
4366 IDirect3DDevice2 *d3ddevice2 = NULL;
4367 IDirect3DDevice3 *d3ddevice3 = NULL;
4368 IDirectDrawClipper *clipper = NULL, *d3drm_clipper = NULL;
4369 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_primary = NULL;
4370 IDirectDrawSurface7 *surface7 = NULL;
4371 DDSURFACEDESC desc, surface_desc;
4372 DWORD expected_flags, ret_val;
4373 HWND window;
4374 GUID driver = IID_IDirect3DRGBDevice;
4375 HRESULT hr;
4376 ULONG ref1, ref2, ref3, cref1, cref2;
4377 RECT rc;
4379 window = create_window();
4380 GetClientRect(window, &rc);
4381 hr = DirectDrawCreateClipper(0, &clipper, NULL);
4382 ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface, hr %#lx.\n", hr);
4383 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
4384 ok(hr == DD_OK, "Cannot set HWnd to Clipper, hr %#lx.\n", hr);
4386 hr = Direct3DRMCreate(&d3drm1);
4387 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
4388 ref1 = get_refcount((IUnknown *)d3drm1);
4389 cref1 = get_refcount((IUnknown *)clipper);
4391 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
4392 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr);
4393 ref2 = get_refcount((IUnknown *)d3drm3);
4395 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, 0, 0, &device3);
4396 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
4397 ok(device3 == NULL, "Expected device returned == NULL, got %p.\n", device3);
4399 /* If NULL is passed for clipper, CreateDeviceFromClipper returns D3DRMERR_BADVALUE */
4400 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, NULL, &driver, 300, 200, &device3);
4401 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
4403 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, 300, 200, NULL);
4404 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
4406 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, 300, 200, &device3);
4407 ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice3 interface, hr %#lx.\n", hr);
4408 ref3 = get_refcount((IUnknown *)d3drm1);
4409 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %lu , ref3 = %lu.\n", ref1, ref3);
4410 ref3 = get_refcount((IUnknown *)d3drm3);
4411 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
4412 cref2 = get_refcount((IUnknown *)clipper);
4413 ok(cref2 > cref1, "expected cref2 > cref1, got cref1 = %lu , cref2 = %lu.\n", cref1, cref2);
4414 ret_val = IDirect3DRMDevice3_GetWidth(device3);
4415 ok(ret_val == 300, "Expected device width = 300, got %lu.\n", ret_val);
4416 ret_val = IDirect3DRMDevice3_GetHeight(device3);
4417 ok(ret_val == 200, "Expected device height == 200, got %lu.\n", ret_val);
4419 /* Fetch immediate mode device in order to access render target */
4420 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
4421 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface, hr %#lx.\n", hr);
4423 hr = IDirect3DDevice2_QueryInterface(d3ddevice2, &IID_IDirect3DDevice3, (void**)&d3ddevice3);
4424 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4425 IDirect3DDevice3_Release(d3ddevice3);
4427 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &surface);
4428 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
4430 hr = IDirectDrawSurface_GetClipper(surface, &d3drm_clipper);
4431 ok(hr == DDERR_NOCLIPPERATTACHED, "Expected hr == DDERR_NOCLIPPERATTACHED, got hr %#lx.\n", hr);
4433 /* Check if CreateDeviceFromClipper creates a primary surface and attaches the clipper to it */
4434 hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **)&surface7);
4435 ok(hr == DD_OK, "Cannot get IDirectDrawSurface7 interface, hr %#lx.\n", hr);
4436 IDirectDrawSurface7_GetDDInterface(surface7, (void **)&unknown);
4437 hr = IUnknown_QueryInterface(unknown, &IID_IDirectDraw, (void **)&ddraw);
4438 ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
4439 IUnknown_Release(unknown);
4440 hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
4441 NULL, &d3drm_primary, surface_callback);
4442 ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#lx.\n", hr);
4443 ok(d3drm_primary != NULL, "No primary surface was enumerated.\n");
4444 hr = IDirectDrawSurface_GetClipper(d3drm_primary, &d3drm_clipper);
4445 ok(hr == DD_OK, "Cannot get attached clipper from primary surface, hr %#lx.\n", hr);
4446 ok(d3drm_clipper == clipper, "Expected clipper returned == %p, got %p.\n", clipper , d3drm_clipper);
4448 IDirectDrawClipper_Release(d3drm_clipper);
4449 IDirectDrawSurface_Release(d3drm_primary);
4450 IDirectDrawSurface7_Release(surface7);
4451 IDirectDraw_Release(ddraw);
4453 /* Check properties of render target and depth surface */
4454 surface_desc.dwSize = sizeof(surface_desc);
4455 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &surface_desc);
4456 ok(hr == DD_OK, "Cannot get surface desc structure, hr %#lx.\n", hr);
4458 ok((surface_desc.dwWidth == 300) && (surface_desc.dwHeight == 200), "Expected surface dimensions = 300, 200, got %lu, %lu.\n",
4459 surface_desc.dwWidth, surface_desc.dwHeight);
4460 ok((surface_desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE),
4461 "Unexpected caps %#lx.\n", surface_desc.ddsCaps.dwCaps);
4462 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4463 ok(surface_desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, surface_desc.dwFlags);
4465 hr = DirectDrawCreate(NULL, &ddraw, NULL);
4466 ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
4467 desc.dwSize = sizeof(desc);
4468 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4469 ok(hr == DD_OK, "Cannot get IDirectDraw display mode, hr %#lx\n", hr);
4470 ok(desc.ddpfPixelFormat.dwRGBBitCount == surface_desc.ddpfPixelFormat.dwRGBBitCount, "Expected %lu bpp, got %lu bpp.\n",
4471 surface_desc.ddpfPixelFormat.dwRGBBitCount, desc.ddpfPixelFormat.dwRGBBitCount);
4473 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4474 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
4476 desc.dwSize = sizeof(desc);
4477 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
4478 ok(hr == DD_OK, "Cannot get z surface desc structure, hr %#lx.\n", hr);
4480 ok((desc.dwWidth == 300) && (desc.dwHeight == 200), "Expected surface dimensions = 300, 200, got %lu, %lu.\n",
4481 desc.dwWidth, desc.dwHeight);
4482 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Unexpected caps %#lx.\n", desc.ddsCaps.dwCaps);
4483 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4484 ok(desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, desc.dwFlags);
4485 ok(desc.dwZBufferBitDepth == 16, "Expected 16 for Z buffer bit depth, got %lu.\n", desc.dwZBufferBitDepth);
4486 ok(!desc.ddpfPixelFormat.dwStencilBitMask, "Unexpected stencil mask %#lx.\n", desc.ddpfPixelFormat.dwStencilBitMask);
4488 /* Release old objects and check refcount of device and clipper */
4489 IDirectDrawSurface_Release(ds);
4490 ds = NULL;
4491 IDirectDrawSurface_Release(surface);
4492 surface = NULL;
4493 IDirect3DDevice2_Release(d3ddevice2);
4494 d3ddevice2 = NULL;
4495 IDirect3DRMDevice3_Release(device3);
4496 ref3 = get_refcount((IUnknown *)d3drm1);
4497 ok(ref1 == ref3, "expected ref1 == ref3, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
4498 ref3 = get_refcount((IUnknown *)d3drm3);
4499 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
4500 cref2 = get_refcount((IUnknown *)clipper);
4501 ok(cref1 == cref2, "expected cref1 == cref2, got cref1 = %lu, cref2 = %lu.\n", cref1, cref2);
4503 /* Test if render target format follows the screen format */
4504 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4505 ok(hr == DD_OK, "Cannot get IDirectDraw display mode, hr %#lx\n", hr);
4506 hr = IDirectDraw_SetDisplayMode(ddraw, desc.dwWidth, desc.dwHeight, 16);
4507 ok(hr == DD_OK, "Cannot set display mode to 16bpp, hr %#lx.\n", hr);
4509 hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
4510 ok(hr == DD_OK, "Cannot get IDirectDraw display mode, hr %#lx\n", hr);
4511 ok(desc.ddpfPixelFormat.dwRGBBitCount == 16, "Expected 16 bpp, got %lu.\n", desc.ddpfPixelFormat.dwRGBBitCount);
4513 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, rc.right, rc.bottom, &device3);
4514 ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice3 interface, hr %#lx.\n", hr);
4516 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
4517 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface, hr %#lx.\n", hr);
4519 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &surface);
4520 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
4522 surface_desc.dwSize = sizeof(surface_desc);
4523 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &surface_desc);
4524 ok(hr == DD_OK, "Cannot get surface desc structure, hr %#lx.\n", hr);
4525 ok(surface_desc.ddpfPixelFormat.dwRGBBitCount == 16, "Expected 16bpp, got %lubpp.\n",
4526 surface_desc.ddpfPixelFormat.dwRGBBitCount);
4528 hr = IDirectDraw2_RestoreDisplayMode(ddraw);
4529 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#lx.\n", hr);
4531 IDirectDrawSurface_Release(surface);
4532 IDirect3DDevice2_Release(d3ddevice2);
4533 IDirect3DRMDevice3_Release(device3);
4534 IDirect3DRM3_Release(d3drm3);
4535 IDirect3DRM_Release(d3drm1);
4536 IDirectDrawClipper_Release(clipper);
4537 IDirectDraw_Release(ddraw);
4538 DestroyWindow(window);
4541 static void test_create_device_from_surface1(void)
4543 DDSCAPS caps = { DDSCAPS_ZBUFFER };
4544 DDSURFACEDESC desc;
4545 IDirectDraw *ddraw = NULL;
4546 IDirect3DRM *d3drm1 = NULL;
4547 IDirect3DRMDevice *device1 = (IDirect3DRMDevice *)0xdeadbeef;
4548 IDirect3DDevice *d3ddevice1 = NULL;
4549 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_surface = NULL, *d3drm_ds = NULL;
4550 DWORD expected_flags, ret_val;
4551 HWND window;
4552 GUID driver = IID_IDirect3DRGBDevice;
4553 ULONG ref1, ref2, surface_ref1, surface_ref2;
4554 RECT rc;
4555 BOOL use_sysmem_zbuffer = FALSE;
4556 HRESULT hr;
4558 hr = DirectDrawCreate(NULL, &ddraw, NULL);
4559 ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
4561 window = create_window();
4562 GetClientRect(window, &rc);
4564 hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
4565 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
4567 hr = Direct3DRMCreate(&d3drm1);
4568 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
4569 ref1 = get_refcount((IUnknown *)d3drm1);
4571 /* Create a surface and use it to create the retained mode device. */
4572 memset(&desc, 0, sizeof(desc));
4573 desc.dwSize = sizeof(desc);
4574 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4575 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
4576 desc.dwWidth = rc.right;
4577 desc.dwHeight = rc.bottom;
4579 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4580 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
4582 hr = IDirect3DRM_CreateDeviceFromSurface(d3drm1, &driver, ddraw, surface, &device1);
4583 ok(hr == DDERR_INVALIDCAPS, "Expected hr == DDERR_INVALIDCAPS, got hr %#lx.\n", hr);
4584 ok(device1 == NULL, "Expected device returned == NULL, got %p.\n", device1);
4585 IDirectDrawSurface_Release(surface);
4587 desc.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE;
4588 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4589 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
4590 surface_ref1 = get_refcount((IUnknown *)surface);
4592 hr = IDirect3DRM_CreateDeviceFromSurface(d3drm1, &driver, ddraw, surface, NULL);
4593 ok(hr == D3DRMERR_BADVALUE, "Expected hr == DDERR_BADVALUE, got hr %#lx.\n", hr);
4594 hr = IDirect3DRM_CreateDeviceFromSurface(d3drm1, &driver, ddraw, NULL, &device1);
4595 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == DDERR_BADDEVICE, got hr %#lx.\n", hr);
4596 hr = IDirect3DRM_CreateDeviceFromSurface(d3drm1, &driver, NULL, surface, &device1);
4597 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == DDERR_BADDEVICE, got hr %#lx.\n", hr);
4599 hr = IDirect3DRM_CreateDeviceFromSurface(d3drm1, &driver, ddraw, surface, &device1);
4600 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice interface, hr %#lx.\n", hr);
4601 ref2 = get_refcount((IUnknown *)d3drm1);
4602 ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %lu , ref2 = %lu.\n", ref1, ref2);
4603 surface_ref2 = get_refcount((IUnknown *)surface);
4604 ok(surface_ref2 > surface_ref1, "Expected surface_ref2 > surface_ref1, got surface_ref1 = %lu, surface_ref2 = %lu.\n", surface_ref1, surface_ref2);
4605 ret_val = IDirect3DRMDevice_GetWidth(device1);
4606 ok(ret_val == rc.right, "Expected device width = 300, got %lu.\n", ret_val);
4607 ret_val = IDirect3DRMDevice_GetHeight(device1);
4608 ok(ret_val == rc.bottom, "Expected device height == 200, got %lu.\n", ret_val);
4610 /* Check if CreateDeviceFromSurface creates a primary surface */
4611 hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
4612 NULL, &d3drm_surface, surface_callback);
4613 ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#lx.\n", hr);
4614 ok(d3drm_surface == NULL, "No primary surface should have enumerated (%p).\n", d3drm_surface);
4616 hr = IDirect3DRMDevice_GetDirect3DDevice(device1, &d3ddevice1);
4617 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice interface, hr %#lx.\n", hr);
4619 hr = IDirect3DDevice_QueryInterface(d3ddevice1, &IID_IDirectDrawSurface, (void **)&d3drm_surface);
4620 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
4621 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
4623 /* Check properties of attached depth surface */
4624 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &ds);
4625 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
4627 memset(&desc, 0, sizeof(desc));
4628 desc.dwSize = sizeof(desc);
4629 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
4630 ok(hr == DD_OK, "Cannot get z surface desc structure, hr %#lx.\n", hr);
4632 use_sysmem_zbuffer = desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY;
4633 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %lu, %lu, got %lu, %lu.\n",
4634 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
4635 ok(desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER, "Unexpected caps %lx.\n", desc.ddsCaps.dwCaps);
4636 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4637 ok(desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, desc.dwFlags);
4639 IDirectDrawSurface_Release(ds);
4640 IDirect3DDevice_Release(d3ddevice1);
4641 IDirectDrawSurface_Release(d3drm_surface);
4643 IDirect3DRMDevice_Release(device1);
4644 ref2 = get_refcount((IUnknown *)d3drm1);
4645 ok(ref1 == ref2, "expected ref1 == ref2, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
4646 surface_ref2 = get_refcount((IUnknown *)surface);
4647 ok(surface_ref2 == surface_ref1, "Expected surface_ref2 == surface_ref1, got surface_ref1 = %lu, surface_ref2 = %lu.\n",
4648 surface_ref1, surface_ref2);
4649 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4650 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
4651 /*The render target still holds a reference to ds as the depth surface remains attached to it, so refcount will be 1*/
4652 ref1 = IDirectDrawSurface_Release(ds);
4653 ok(ref1 == 1, "Unexpected refcount %lu.\n", ref1);
4654 ref1 = IDirectDrawSurface_Release(surface);
4655 ok(!ref1, "Unexpected refcount %lu.\n", ref1);
4657 memset(&desc, 0, sizeof(desc));
4658 desc.dwSize = sizeof(desc);
4659 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4660 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
4661 desc.dwWidth = rc.right;
4662 desc.dwHeight = rc.bottom;
4664 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4665 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
4667 memset(&desc, 0, sizeof(desc));
4668 desc.dwSize = sizeof(desc);
4669 desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT;
4670 desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | (use_sysmem_zbuffer ? DDSCAPS_SYSTEMMEMORY : 0);
4671 desc.dwZBufferBitDepth = 16;
4672 desc.dwWidth = rc.right;
4673 desc.dwHeight = rc.bottom;
4674 hr = IDirectDraw_CreateSurface(ddraw, &desc, &ds, NULL);
4675 ok(hr == DD_OK, "Cannot create depth surface, hr %#lx.\n", hr);
4676 hr = IDirectDrawSurface_AddAttachedSurface(surface, ds);
4677 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#lx.\n", hr);
4679 hr = IDirect3DRM_CreateDeviceFromSurface(d3drm1, &driver, ddraw, surface, &device1);
4680 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice interface, hr %#lx.\n", hr);
4682 hr = IDirect3DRMDevice2_GetDirect3DDevice(device1, &d3ddevice1);
4683 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice interface, hr %#lx.\n", hr);
4685 hr = IDirect3DDevice_QueryInterface(d3ddevice1, &IID_IDirectDrawSurface, (void **)&d3drm_surface);
4686 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
4687 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
4689 /* Check if depth surface matches the one we created */
4690 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &d3drm_ds);
4691 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
4692 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
4694 IDirectDrawSurface_Release(d3drm_ds);
4695 IDirectDrawSurface_Release(d3drm_surface);
4696 IDirectDrawSurface_Release(ds);
4698 IDirect3DDevice_Release(d3ddevice1);
4699 IDirect3DRMDevice_Release(device1);
4700 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4701 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
4702 /*The render target still holds a reference to ds as the depth surface remains attached to it, so refcount will be 1*/
4703 ref1 = IDirectDrawSurface_Release(ds);
4704 ok(ref1 == 1, "Unexpected refcount %lu.\n", ref1);
4705 ref1 = IDirectDrawSurface_Release(surface);
4706 ok(!ref1, "Unexpected refcount %lu.\n", ref1);
4707 IDirect3DRM_Release(d3drm1);
4708 IDirectDraw_Release(ddraw);
4709 DestroyWindow(window);
4712 static void test_create_device_from_surface2(void)
4714 DDSCAPS caps = { DDSCAPS_ZBUFFER };
4715 DDSURFACEDESC desc;
4716 IDirectDraw *ddraw = NULL;
4717 IDirect3DRM *d3drm1 = NULL;
4718 IDirect3DRM2 *d3drm2 = NULL;
4719 IDirect3DRMDevice2 *device2 = (IDirect3DRMDevice2 *)0xdeadbeef;
4720 IDirect3DDevice2 *d3ddevice2 = NULL;
4721 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_surface = NULL, *d3drm_ds = NULL;
4722 DWORD expected_flags, ret_val;
4723 HWND window;
4724 GUID driver = IID_IDirect3DRGBDevice;
4725 ULONG ref1, ref2, ref3, surface_ref1, surface_ref2;
4726 RECT rc;
4727 BOOL use_sysmem_zbuffer = FALSE;
4728 HRESULT hr;
4730 hr = DirectDrawCreate(NULL, &ddraw, NULL);
4731 ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
4733 window = create_window();
4734 GetClientRect(window, &rc);
4736 hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
4737 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
4739 hr = Direct3DRMCreate(&d3drm1);
4740 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
4741 ref1 = get_refcount((IUnknown *)d3drm1);
4743 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
4744 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM2 interface, hr %#lx.\n", hr);
4745 ref2 = get_refcount((IUnknown *)d3drm2);
4747 /* Create a surface and use it to create the retained mode device. */
4748 memset(&desc, 0, sizeof(desc));
4749 desc.dwSize = sizeof(desc);
4750 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4751 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
4752 desc.dwWidth = rc.right;
4753 desc.dwHeight = rc.bottom;
4755 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4756 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
4758 hr = IDirect3DRM2_CreateDeviceFromSurface(d3drm2, &driver, ddraw, surface, &device2);
4759 ok(hr == DDERR_INVALIDCAPS, "Expected hr == DDERR_INVALIDCAPS, got hr %#lx.\n", hr);
4760 ok(device2 == NULL, "Expected device returned == NULL, got %p.\n", device2);
4761 IDirectDrawSurface_Release(surface);
4763 desc.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE;
4764 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4765 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
4766 surface_ref1 = get_refcount((IUnknown *)surface);
4768 hr = IDirect3DRM2_CreateDeviceFromSurface(d3drm2, &driver, ddraw, surface, NULL);
4769 ok(hr == D3DRMERR_BADVALUE, "Expected hr == DDERR_BADVALUE, got hr %#lx.\n", hr);
4770 hr = IDirect3DRM2_CreateDeviceFromSurface(d3drm2, &driver, ddraw, NULL, &device2);
4771 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == DDERR_BADDEVICE, got hr %#lx.\n", hr);
4772 hr = IDirect3DRM2_CreateDeviceFromSurface(d3drm2, &driver, NULL, surface, &device2);
4773 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == DDERR_BADDEVICE, got hr %#lx.\n", hr);
4775 hr = IDirect3DRM2_CreateDeviceFromSurface(d3drm2, &driver, ddraw, surface, &device2);
4776 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice2 interface, hr %#lx.\n", hr);
4777 ref3 = get_refcount((IUnknown *)d3drm1);
4778 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %lu , ref3 = %lu.\n", ref1, ref3);
4779 ref3 = get_refcount((IUnknown *)d3drm2);
4780 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
4781 surface_ref2 = get_refcount((IUnknown *)surface);
4782 ok(surface_ref2 > surface_ref1, "Expected surface_ref2 > surface_ref1, got surface_ref1 = %lu, surface_ref2 = %lu.\n", surface_ref1, surface_ref2);
4783 ret_val = IDirect3DRMDevice2_GetWidth(device2);
4784 ok(ret_val == rc.right, "Expected device width = 300, got %lu.\n", ret_val);
4785 ret_val = IDirect3DRMDevice2_GetHeight(device2);
4786 ok(ret_val == rc.bottom, "Expected device height == 200, got %lu.\n", ret_val);
4788 /* Check if CreateDeviceFromSurface creates a primary surface */
4789 hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
4790 NULL, &d3drm_surface, surface_callback);
4791 ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#lx.\n", hr);
4792 ok(d3drm_surface == NULL, "No primary surface should have enumerated (%p).\n", d3drm_surface);
4794 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3ddevice2);
4795 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface, hr %#lx.\n", hr);
4797 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &d3drm_surface);
4798 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
4799 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
4801 /* Check properties of attached depth surface */
4802 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &ds);
4803 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
4805 memset(&desc, 0, sizeof(desc));
4806 desc.dwSize = sizeof(desc);
4807 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
4808 ok(hr == DD_OK, "Cannot get z surface desc structure, hr %#lx.\n", hr);
4810 use_sysmem_zbuffer = desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY;
4811 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %lu, %lu, got %lu, %lu.\n",
4812 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
4813 ok(desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER, "Unexpected caps %lx.\n", desc.ddsCaps.dwCaps);
4814 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4815 ok(desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, desc.dwFlags);
4817 IDirectDrawSurface_Release(ds);
4818 IDirect3DDevice2_Release(d3ddevice2);
4819 IDirectDrawSurface_Release(d3drm_surface);
4821 IDirect3DRMDevice2_Release(device2);
4822 ref3 = get_refcount((IUnknown *)d3drm1);
4823 ok(ref1 == ref3, "expected ref1 == ref3, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
4824 ref3 = get_refcount((IUnknown *)d3drm2);
4825 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
4826 surface_ref2 = get_refcount((IUnknown *)surface);
4827 ok(surface_ref2 == surface_ref1, "Expected surface_ref2 == surface_ref1, got surface_ref1 = %lu, surface_ref2 = %lu.\n",
4828 surface_ref1, surface_ref2);
4829 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4830 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
4831 /*The render target still holds a reference to ds as the depth surface remains attached to it, so refcount will be 1*/
4832 ref1 = IDirectDrawSurface_Release(ds);
4833 ok(ref1 == 1, "Unexpected refcount %lu.\n", ref1);
4835 ref1 = IDirectDrawSurface_Release(surface);
4836 ok(!ref1, "Unexpected refcount %lu.\n", ref1);
4838 memset(&desc, 0, sizeof(desc));
4839 desc.dwSize = sizeof(desc);
4840 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4841 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
4842 desc.dwWidth = rc.right;
4843 desc.dwHeight = rc.bottom;
4845 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4846 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
4848 memset(&desc, 0, sizeof(desc));
4849 desc.dwSize = sizeof(desc);
4850 desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT;
4851 desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | (use_sysmem_zbuffer ? DDSCAPS_SYSTEMMEMORY : 0);
4852 desc.dwZBufferBitDepth = 16;
4853 desc.dwWidth = rc.right;
4854 desc.dwHeight = rc.bottom;
4855 hr = IDirectDraw_CreateSurface(ddraw, &desc, &ds, NULL);
4856 ok(hr == DD_OK, "Cannot create depth surface, hr %#lx.\n", hr);
4857 hr = IDirectDrawSurface_AddAttachedSurface(surface, ds);
4858 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#lx.\n", hr);
4860 hr = IDirect3DRM2_CreateDeviceFromSurface(d3drm2, &driver, ddraw, surface, &device2);
4861 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice2 interface, hr %#lx.\n", hr);
4863 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3ddevice2);
4864 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface, hr %#lx.\n", hr);
4866 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &d3drm_surface);
4867 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
4868 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
4870 /* Check if depth surface matches the one we created */
4871 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &d3drm_ds);
4872 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
4873 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
4875 IDirectDrawSurface_Release(d3drm_ds);
4876 IDirectDrawSurface_Release(d3drm_surface);
4877 IDirectDrawSurface_Release(ds);
4879 IDirect3DDevice2_Release(d3ddevice2);
4880 IDirect3DRMDevice2_Release(device2);
4881 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
4882 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
4883 /*The render target still holds a reference to ds as the depth surface remains attached to it, so refcount will be 1*/
4884 ref1 = IDirectDrawSurface_Release(ds);
4885 ok(ref1 == 1, "Unexpected refcount %lu.\n", ref1);
4886 ref1 = IDirectDrawSurface_Release(surface);
4887 ok(!ref1, "Unexpected refcount %lu.\n", ref1);
4888 IDirect3DRM2_Release(d3drm2);
4889 IDirect3DRM_Release(d3drm1);
4890 IDirectDraw_Release(ddraw);
4891 DestroyWindow(window);
4894 static void test_create_device_from_surface3(void)
4896 DDSCAPS caps = { DDSCAPS_ZBUFFER };
4897 DDSURFACEDESC desc;
4898 IDirectDraw *ddraw = NULL;
4899 IDirect3DRM *d3drm1 = NULL;
4900 IDirect3DRM3 *d3drm3 = NULL;
4901 IDirect3DRMDevice3 *device3 = (IDirect3DRMDevice3 *)0xdeadbeef;
4902 IDirect3DDevice2 *d3ddevice2 = NULL;
4903 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_surface = NULL, *d3drm_ds = NULL;
4904 DWORD expected_flags, ret_val;
4905 HWND window;
4906 GUID driver = IID_IDirect3DRGBDevice;
4907 ULONG ref1, ref2, ref3, surface_ref1, surface_ref2;
4908 RECT rc;
4909 BOOL use_sysmem_zbuffer = FALSE;
4910 HRESULT hr;
4912 hr = DirectDrawCreate(NULL, &ddraw, NULL);
4913 ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
4915 window = create_window();
4916 GetClientRect(window, &rc);
4918 hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
4919 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
4921 hr = Direct3DRMCreate(&d3drm1);
4922 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
4923 ref1 = get_refcount((IUnknown *)d3drm1);
4925 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
4926 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr);
4927 ref2 = get_refcount((IUnknown *)d3drm3);
4929 /* Create a surface and use it to create the retained mode device. */
4930 memset(&desc, 0, sizeof(desc));
4931 desc.dwSize = sizeof(desc);
4932 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4933 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
4934 desc.dwWidth = rc.right;
4935 desc.dwHeight = rc.bottom;
4937 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4938 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
4940 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, ddraw, surface, 0, &device3);
4941 ok(hr == DDERR_INVALIDCAPS, "Expected hr == DDERR_INVALIDCAPS, got hr %#lx.\n", hr);
4942 ok(device3 == NULL, "Expected device returned == NULL, got %p.\n", device3);
4943 IDirectDrawSurface_Release(surface);
4945 desc.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE;
4946 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
4947 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
4948 surface_ref1 = get_refcount((IUnknown *)surface);
4950 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, ddraw, surface, 0, NULL);
4951 ok(hr == D3DRMERR_BADVALUE, "Expected hr == DDERR_BADVALUE, got hr %#lx.\n", hr);
4952 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, ddraw, NULL, 0, &device3);
4953 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == DDERR_BADDEVICE, got hr %#lx.\n", hr);
4954 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, NULL, surface, 0, &device3);
4955 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == DDERR_BADDEVICE, got hr %#lx.\n", hr);
4957 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, ddraw, surface, 0, &device3);
4958 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice3 interface, hr %#lx.\n", hr);
4959 ref3 = get_refcount((IUnknown *)d3drm1);
4960 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %lu , ref3 = %lu.\n", ref1, ref3);
4961 ref3 = get_refcount((IUnknown *)d3drm3);
4962 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
4963 surface_ref2 = get_refcount((IUnknown *)surface);
4964 ok(surface_ref2 > surface_ref1, "Expected surface_ref2 > surface_ref1, got surface_ref1 = %lu, surface_ref2 = %lu.\n", surface_ref1, surface_ref2);
4965 ret_val = IDirect3DRMDevice3_GetWidth(device3);
4966 ok(ret_val == rc.right, "Expected device width = 300, got %lu.\n", ret_val);
4967 ret_val = IDirect3DRMDevice3_GetHeight(device3);
4968 ok(ret_val == rc.bottom, "Expected device height == 200, got %lu.\n", ret_val);
4970 /* Check if CreateDeviceFromSurface creates a primary surface */
4971 hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
4972 NULL, &d3drm_surface, surface_callback);
4973 ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#lx.\n", hr);
4974 ok(d3drm_surface == NULL, "No primary surface should have enumerated (%p).\n", d3drm_surface);
4976 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
4977 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface, hr %#lx.\n", hr);
4979 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &d3drm_surface);
4980 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
4981 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
4983 /* Check properties of attached depth surface */
4984 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &ds);
4985 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
4987 memset(&desc, 0, sizeof(desc));
4988 desc.dwSize = sizeof(desc);
4989 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
4990 ok(hr == DD_OK, "Cannot get z surface desc structure, hr %#lx.\n", hr);
4992 use_sysmem_zbuffer = desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY;
4993 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %lu, %lu, got %lu, %lu.\n",
4994 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
4995 ok(desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER, "Unexpected caps %lx.\n", desc.ddsCaps.dwCaps);
4996 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
4997 ok(desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, desc.dwFlags);
4999 IDirectDrawSurface_Release(ds);
5000 IDirect3DDevice2_Release(d3ddevice2);
5001 IDirectDrawSurface_Release(d3drm_surface);
5002 IDirect3DRMDevice3_Release(device3);
5004 ref3 = get_refcount((IUnknown *)d3drm1);
5005 ok(ref1 == ref3, "expected ref1 == ref3, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
5006 ref3 = get_refcount((IUnknown *)d3drm3);
5007 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
5008 surface_ref2 = get_refcount((IUnknown *)surface);
5009 ok(surface_ref2 == surface_ref1, "Expected surface_ref2 == surface_ref1, got surface_ref1 = %lu, surface_ref2 = %lu.\n",
5010 surface_ref1, surface_ref2);
5011 /* In version 3, d3drm will destroy all references of the depth surface it created internally. */
5012 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
5013 todo_wine ok(hr == DDERR_NOTFOUND, "Expected hr == DDERR_NOTFOUND, got hr %#lx.\n", hr);
5014 if (SUCCEEDED(hr))
5015 IDirectDrawSurface_Release(ds);
5016 ref1 = IDirectDrawSurface_Release(surface);
5017 ok(!ref1, "Unexpected refcount %lu.\n", ref1);
5019 memset(&desc, 0, sizeof(desc));
5020 desc.dwSize = sizeof(desc);
5021 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
5022 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
5023 desc.dwWidth = rc.right;
5024 desc.dwHeight = rc.bottom;
5026 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
5027 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
5029 memset(&desc, 0, sizeof(desc));
5030 desc.dwSize = sizeof(desc);
5031 desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT;
5032 desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | (use_sysmem_zbuffer ? DDSCAPS_SYSTEMMEMORY : 0);
5033 desc.dwZBufferBitDepth = 16;
5034 desc.dwWidth = rc.right;
5035 desc.dwHeight = rc.bottom;
5036 hr = IDirectDraw_CreateSurface(ddraw, &desc, &ds, NULL);
5037 ok(hr == DD_OK, "Cannot create depth surface, hr %#lx.\n", hr);
5038 hr = IDirectDrawSurface_AddAttachedSurface(surface, ds);
5039 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#lx.\n", hr);
5041 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, ddraw, surface, D3DRMDEVICE_NOZBUFFER, &device3);
5042 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice3 interface, hr %#lx.\n", hr);
5044 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
5045 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface, hr %#lx.\n", hr);
5047 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &d3drm_surface);
5048 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
5049 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
5051 /* Check if depth surface matches the one we created */
5052 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &d3drm_ds);
5053 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
5054 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
5056 IDirectDrawSurface_Release(d3drm_ds);
5057 IDirectDrawSurface_Release(d3drm_surface);
5058 IDirectDrawSurface_Release(ds);
5059 IDirect3DDevice2_Release(d3ddevice2);
5060 IDirect3DRMDevice3_Release(device3);
5061 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
5062 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
5063 /* The render target still holds a reference to ds as the depth surface remains attached to it, so refcount will be 1*/
5064 ref1 = IDirectDrawSurface_Release(ds);
5065 ok(ref1 == 1, "Unexpected refcount %lu.\n", ref1);
5067 /* What happens if we pass no flags and still attach our own depth surface? */
5068 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, ddraw, surface, 0, &device3);
5069 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice3 interface, hr %#lx.\n", hr);
5071 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
5072 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface, hr %#lx.\n", hr);
5074 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &d3drm_surface);
5075 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
5076 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
5078 /* Check if depth surface matches the one we created */
5079 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &d3drm_ds);
5080 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
5081 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
5083 IDirectDrawSurface_Release(d3drm_ds);
5084 IDirectDrawSurface_Release(d3drm_surface);
5085 IDirect3DDevice2_Release(d3ddevice2);
5086 IDirect3DRMDevice3_Release(device3);
5087 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
5088 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
5089 /*The render target still holds a reference to ds as the depth surface remains attached to it, so refcount will be 1*/
5090 ref1 = IDirectDrawSurface_Release(ds);
5091 ok(ref1 == 1, "Unexpected refcount %lu.\n", ref1);
5092 ref1 = IDirectDrawSurface_Release(surface);
5093 ok(!ref1, "Unexpected refcount %lu.\n", ref1);
5095 memset(&desc, 0, sizeof(desc));
5096 desc.dwSize = sizeof(desc);
5097 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
5098 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
5099 desc.dwWidth = rc.right;
5100 desc.dwHeight = rc.bottom;
5102 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
5103 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
5105 /* What happens if we don't pass D3DRMDEVICE_NOZBUFFER and still not attach our own depth surface? */
5106 hr = IDirect3DRM3_CreateDeviceFromSurface(d3drm3, &driver, ddraw, surface, D3DRMDEVICE_NOZBUFFER, &device3);
5107 ok(SUCCEEDED(hr), "Cannot create IDirect3DRMDevice3 interface, hr %#lx.\n", hr);
5109 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
5110 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface, hr %#lx.\n", hr);
5112 hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &d3drm_surface);
5113 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
5114 ok(surface == d3drm_surface, "Expected surface returned == %p, got %p.\n", surface, d3drm_surface);
5116 /* Check if depth surface matches the one we created */
5117 hr = IDirectDrawSurface_GetAttachedSurface(d3drm_surface, &caps, &d3drm_ds);
5118 ok(hr == DDERR_NOTFOUND, "Expected hr == DDERR_NOTFOUND, got %#lx.\n", hr);
5119 IDirectDrawSurface_Release(d3drm_surface);
5121 IDirect3DDevice2_Release(d3ddevice2);
5122 IDirect3DRMDevice3_Release(device3);
5123 ref1 = IDirectDrawSurface_Release(surface);
5124 ok(!ref1, "Unexpected refcount %lu.\n", ref1);
5125 IDirect3DRM3_Release(d3drm3);
5126 IDirect3DRM_Release(d3drm1);
5127 IDirectDraw_Release(ddraw);
5128 DestroyWindow(window);
5131 static IDirect3DDevice *create_device1(IDirectDraw *ddraw, HWND window, IDirectDrawSurface **ds)
5133 static const DWORD z_depths[] = { 32, 24, 16 };
5134 IDirectDrawSurface *surface;
5135 IDirect3DDevice *device = NULL;
5136 DDSURFACEDESC surface_desc;
5137 unsigned int i;
5138 HRESULT hr;
5139 RECT rc;
5141 GetClientRect(window, &rc);
5142 hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
5143 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
5145 memset(&surface_desc, 0, sizeof(surface_desc));
5146 surface_desc.dwSize = sizeof(surface_desc);
5147 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
5148 surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
5149 surface_desc.dwWidth = rc.right;
5150 surface_desc.dwHeight = rc.bottom;
5152 hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL);
5153 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
5155 /* We used to use EnumDevices() for this, but it seems
5156 * D3DDEVICEDESC.dwDeviceZBufferBitDepth only has a very casual
5157 * relationship with reality. */
5158 for (i = 0; i < ARRAY_SIZE(z_depths); ++i)
5160 memset(&surface_desc, 0, sizeof(surface_desc));
5161 surface_desc.dwSize = sizeof(surface_desc);
5162 surface_desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT;
5163 surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
5164 U2(surface_desc).dwZBufferBitDepth = z_depths[i];
5165 surface_desc.dwWidth = rc.right;
5166 surface_desc.dwHeight = rc.bottom;
5167 if (FAILED(IDirectDraw_CreateSurface(ddraw, &surface_desc, ds, NULL)))
5168 continue;
5170 hr = IDirectDrawSurface_AddAttachedSurface(surface, *ds);
5171 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#lx.\n", hr);
5172 if (FAILED(hr))
5174 IDirectDrawSurface_Release(*ds);
5175 continue;
5178 if (SUCCEEDED(IDirectDrawSurface_QueryInterface(surface, &IID_IDirect3DHALDevice, (void **)&device)))
5179 break;
5181 IDirectDrawSurface_DeleteAttachedSurface(surface, 0, *ds);
5182 IDirectDrawSurface_Release(*ds);
5183 *ds = NULL;
5186 IDirectDrawSurface_Release(surface);
5187 return device;
5190 static void test_create_device_from_d3d1(void)
5192 IDirectDraw *ddraw1 = NULL, *temp_ddraw1;
5193 IDirect3D *d3d1 = NULL, *temp_d3d1;
5194 IDirect3DRM *d3drm1 = NULL;
5195 IDirect3DRMDevice *device1 = (IDirect3DRMDevice *)0xdeadbeef;
5196 IDirect3DRMDevice2 *device2;
5197 IDirect3DRMDevice3 *device3;
5198 IDirect3DDevice *d3ddevice1 = NULL, *d3drm_d3ddevice1 = NULL, *temp_d3ddevice1;
5199 IDirect3DDevice2 *d3ddevice2 = (IDirect3DDevice2 *)0xdeadbeef;
5200 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_ds = NULL;
5201 DWORD expected_flags, ret_val;
5202 DDSCAPS caps = { DDSCAPS_ZBUFFER };
5203 DDSURFACEDESC desc;
5204 RECT rc;
5205 HWND window;
5206 ULONG ref1, ref2, ref3, ref4, device_ref1, device_ref2, d3d_ref1, d3d_ref2;
5207 HRESULT hr;
5209 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
5210 ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
5212 window = create_window();
5213 GetClientRect(window, &rc);
5215 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1);
5216 ok(hr == DD_OK, "Cannot get IDirect3D2 interface, hr %#lx.\n", hr);
5217 d3d_ref1 = get_refcount((IUnknown *)d3d1);
5219 /* Create the immediate mode device */
5220 d3ddevice1 = create_device1(ddraw1, window, &ds);
5221 if (d3ddevice1 == NULL)
5223 win_skip("Cannot create IM device, skipping tests.\n");
5224 IDirect3D_Release(d3d1);
5225 IDirectDraw_Release(ddraw1);
5226 return;
5228 device_ref1 = get_refcount((IUnknown *)d3ddevice1);
5230 hr = Direct3DRMCreate(&d3drm1);
5231 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
5232 ref1 = get_refcount((IUnknown *)d3drm1);
5234 hr = IDirect3DRM_CreateDeviceFromD3D(d3drm1, NULL, d3ddevice1, &device1);
5235 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#lx.\n", hr);
5236 ok(device1 == NULL, "Expected device returned == NULL, got %p.\n", device1);
5237 hr = IDirect3DRM_CreateDeviceFromD3D(d3drm1, d3d1, NULL, &device1);
5238 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
5239 hr = IDirect3DRM_CreateDeviceFromD3D(d3drm1, d3d1, d3ddevice1, NULL);
5240 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
5242 hr = IDirect3DRM_CreateDeviceFromD3D(d3drm1, d3d1, d3ddevice1, &device1);
5243 ok(hr == DD_OK, "Failed to create IDirect3DRMDevice interface, hr %#lx\n", hr);
5244 ref2 = get_refcount((IUnknown *)d3drm1);
5245 ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
5246 device_ref2 = get_refcount((IUnknown *)d3ddevice1);
5247 ok(device_ref2 > device_ref1, "Expected device_ref2 > device_ref1, got device_ref1 = %lu, device_ref2 = %lu.\n", device_ref1, device_ref2);
5248 d3d_ref2 = get_refcount((IUnknown *)d3d1);
5249 ok(d3d_ref2 > d3d_ref1, "Expected d3d_ref2 > d3d_ref1, got d3d_ref1 = %lu, d3d_ref2 = %lu.\n", d3d_ref1, d3d_ref2);
5250 ret_val = IDirect3DRMDevice_GetWidth(device1);
5251 ok(ret_val == rc.right, "Expected device width = 300, got %lu.\n", ret_val);
5252 ret_val = IDirect3DRMDevice_GetHeight(device1);
5253 ok(ret_val == rc.bottom, "Expected device height == 200, got %lu.\n", ret_val);
5255 hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IDirect3DRMDevice2, (void **)&device2);
5256 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice2 Interface, hr %#lx.\n", hr);
5257 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3ddevice2);
5258 ok(SUCCEEDED(hr), "Expected hr == D3DRM_OK, got hr %#lx.\n", hr);
5259 ok(d3ddevice2 == NULL, "Expected d3ddevice2 == NULL, got %p.\n", d3ddevice2);
5260 IDirect3DRMDevice2_Release(device2);
5262 d3ddevice2 = (IDirect3DDevice2 *)0xdeadbeef;
5263 hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IDirect3DRMDevice3, (void **)&device3);
5264 ok(hr == DD_OK, "Cannot get IDirect3DRMDevice3 Interface, hr %#lx.\n", hr);
5265 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
5266 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got hr %#lx.\n", hr);
5267 ok(d3ddevice2 == NULL, "Expected d3ddevice2 == NULL, got %p.\n", d3ddevice2);
5268 IDirect3DRMDevice3_Release(device3);
5270 hr = IDirectDraw_EnumSurfaces(ddraw1, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
5271 NULL, &surface, surface_callback);
5272 ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#lx.\n", hr);
5273 ok(surface == NULL, "No primary surface should have enumerated (%p).\n", surface);
5275 hr = IDirect3DRMDevice_GetDirect3DDevice(device1, &d3drm_d3ddevice1);
5276 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice interface, hr %#lx.\n", hr);
5277 ok(d3ddevice1 == d3drm_d3ddevice1, "Expected Immediate Mode device created == %p, got %p.\n", d3ddevice1, d3drm_d3ddevice1);
5279 /* Check properties of render target and depth surfaces */
5280 hr = IDirect3DDevice_QueryInterface(d3drm_d3ddevice1, &IID_IDirectDrawSurface, (void **)&surface);
5281 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
5283 memset(&desc, 0, sizeof(desc));
5284 desc.dwSize = sizeof(desc);
5285 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
5286 ok(hr == DD_OK, "Cannot get surface desc structure, hr %#lx.\n", hr);
5288 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %lu, %lu, got %lu, %lu.\n",
5289 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5290 ok((desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE),
5291 "Unexpected caps %lx.\n", desc.ddsCaps.dwCaps);
5292 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5293 ok(desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, desc.dwFlags);
5295 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
5296 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
5297 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
5299 desc.dwSize = sizeof(desc);
5300 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
5301 ok(hr == DD_OK, "Cannot get z surface desc structure, hr %#lx.\n", hr);
5303 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %lu, %lu, got %lu, %lu.\n",
5304 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5305 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Unexpected caps %lx.\n", desc.ddsCaps.dwCaps);
5306 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5307 ok(desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, desc.dwFlags);
5309 IDirectDrawSurface_Release(d3drm_ds);
5310 IDirectDrawSurface_Release(ds);
5311 IDirectDrawSurface_Release(surface);
5312 IDirect3DDevice_Release(d3drm_d3ddevice1);
5313 IDirect3DRMDevice_Release(device1);
5314 ref2 = get_refcount((IUnknown *)d3drm1);
5315 ok(ref1 == ref2, "expected ref1 == ref2, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
5316 device_ref2 = get_refcount((IUnknown *)d3ddevice1);
5317 ok(device_ref2 == device_ref1, "Expected device_ref2 == device_ref1, got device_ref1 = %lu, device_ref2 = %lu.\n", device_ref1, device_ref2);
5319 /* InitFromD3D tests */
5320 hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_CDirect3DRMDevice, NULL, &IID_IDirect3DRMDevice, (void **)&device1);
5321 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface, hr %#lx.\n", hr);
5323 hr = IDirect3DRMDevice_InitFromD3D(device1, NULL, d3ddevice1);
5324 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
5325 hr = IDirect3DRMDevice_InitFromD3D(device1, d3d1, NULL);
5326 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
5328 hr = IDirect3DRMDevice_InitFromD3D(device1, d3d1, d3ddevice1);
5329 ok(SUCCEEDED(hr), "Failed to initialise IDirect3DRMDevice interface, hr %#lx\n", hr);
5330 ref2 = get_refcount((IUnknown *)d3drm1);
5331 ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
5332 device_ref2 = get_refcount((IUnknown *)d3ddevice1);
5333 ok(device_ref2 > device_ref1, "Expected device_ref2 > device_ref1, got device_ref1 = %lu, device_ref2 = %lu.\n",
5334 device_ref1, device_ref2);
5335 d3d_ref2 = get_refcount((IUnknown *)d3d1);
5336 ok(d3d_ref2 > d3d_ref1, "Expected d3d_ref2 > d3d_ref1, got d3d_ref1 = %lu, d3d_ref2 = %lu.\n", d3d_ref1, d3d_ref2);
5337 ret_val = IDirect3DRMDevice_GetWidth(device1);
5338 ok(ret_val == rc.right, "Expected device width = 300, got %lu.\n", ret_val);
5339 ret_val = IDirect3DRMDevice_GetHeight(device1);
5340 ok(ret_val == rc.bottom, "Expected device height == 200, got %lu.\n", ret_val);
5342 hr = IDirect3DRMDevice_InitFromD3D(device1, d3d1, d3ddevice1);
5343 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got hr %#lx.\n", hr);
5344 ref3 = get_refcount((IUnknown *)d3drm1);
5345 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %lu , ref3 = %lu.\n", ref1, ref3);
5346 ref3 = get_refcount((IUnknown *)d3ddevice1);
5347 ok(ref3 > device_ref2, "Expected ref3 > device_ref2, got ref3 = %lu, device_ref2 = %lu.\n", ref3, device_ref2);
5348 ref3 = get_refcount((IUnknown *)d3d1);
5349 ok(ref3 > d3d_ref2, "Expected ref3 > d3d_ref2, got ref3 = %lu, d3d_ref2 = %lu.\n", ref3, d3d_ref2);
5350 /* Release leaked references */
5351 while (IDirect3DRM_Release(d3drm1) > ref2);
5352 while (IDirect3DDevice_Release(d3ddevice1) > device_ref2);
5353 while (IDirect3D_Release(d3d1) > d3d_ref2);
5355 hr = DirectDrawCreate(NULL, &temp_ddraw1, NULL);
5356 ok(SUCCEEDED(hr), "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
5357 ref4 = get_refcount((IUnknown *)temp_ddraw1);
5359 hr = IDirectDraw_QueryInterface(temp_ddraw1, &IID_IDirect3D, (void **)&temp_d3d1);
5360 ok(SUCCEEDED(hr), "Cannot get IDirect3D2 interface, hr %#lx.\n", hr);
5361 temp_d3ddevice1 = create_device1(temp_ddraw1, window, &surface);
5362 hr = IDirect3DRMDevice_InitFromD3D(device1, temp_d3d1, temp_d3ddevice1);
5363 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got hr %#lx.\n", hr);
5364 ref3 = get_refcount((IUnknown *)d3drm1);
5365 ok(ref3 > ref2, "expected ref3 > ref1, got ref1 = %lu , ref3 = %lu.\n", ref1, ref3);
5366 ref3 = get_refcount((IUnknown *)temp_d3ddevice1);
5367 ok(ref3 == device_ref2, "Expected ref3 == device_ref2, got ref3 = %lu, device_ref2 = %lu.\n", ref3, device_ref2);
5368 ref3 = get_refcount((IUnknown *)temp_d3d1);
5369 todo_wine ok(ref3 < d3d_ref2, "Expected ref3 < d3d_ref2, got ref3 = %lu, d3d_ref2 = %lu.\n", ref3, d3d_ref2);
5370 /* Release leaked references */
5371 while (IDirect3DRM_Release(d3drm1) > ref2);
5372 while (IDirect3DDevice_Release(temp_d3ddevice1) > 0);
5373 while (IDirect3D_Release(temp_d3d1) > ref4);
5374 IDirectDrawSurface_Release(surface);
5375 IDirectDraw_Release(temp_ddraw1);
5377 d3ddevice2 = (IDirect3DDevice2 *)0xdeadbeef;
5378 hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IDirect3DRMDevice2, (void **)&device2);
5379 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice2 Interface, hr %#lx.\n", hr);
5380 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3ddevice2);
5381 ok(SUCCEEDED(hr), "Expected hr == D3DRM_OK, got hr %#lx.\n", hr);
5382 ok(d3ddevice2 == NULL, "Expected d3ddevice2 == NULL, got %p.\n", d3ddevice2);
5383 IDirect3DRMDevice2_Release(device2);
5385 d3ddevice2 = (IDirect3DDevice2 *)0xdeadbeef;
5386 hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IDirect3DRMDevice3, (void **)&device3);
5387 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 Interface, hr %#lx.\n", hr);
5388 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);
5389 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got hr %#lx.\n", hr);
5390 ok(d3ddevice2 == NULL, "Expected d3ddevice2 == NULL, got %p.\n", d3ddevice2);
5391 IDirect3DRMDevice3_Release(device3);
5393 surface = NULL;
5394 hr = IDirectDraw_EnumSurfaces(ddraw1, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
5395 NULL, &surface, surface_callback);
5396 ok(SUCCEEDED(hr), "Failed to enumerate surfaces, hr %#lx.\n", hr);
5397 ok(surface == NULL, "No primary surface should have enumerated (%p).\n", surface);
5399 hr = IDirect3DRMDevice_GetDirect3DDevice(device1, &d3drm_d3ddevice1);
5400 ok(SUCCEEDED(hr), "Cannot get IDirect3DDevice interface, hr %#lx.\n", hr);
5401 ok(d3ddevice1 == d3drm_d3ddevice1, "Expected Immediate Mode device created == %p, got %p.\n",
5402 d3ddevice1, d3drm_d3ddevice1);
5404 /* Check properties of render target and depth surfaces */
5405 hr = IDirect3DDevice_QueryInterface(d3drm_d3ddevice1, &IID_IDirectDrawSurface, (void **)&surface);
5406 ok(SUCCEEDED(hr), "Cannot get surface to the render target, hr %#lx.\n", hr);
5408 memset(&desc, 0, sizeof(desc));
5409 desc.dwSize = sizeof(desc);
5410 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
5411 ok(SUCCEEDED(hr), "Cannot get surface desc structure, hr %#lx.\n", hr);
5413 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %lu, %lu, got %lu, %lu.\n",
5414 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5415 ok((desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE),
5416 "Unexpected caps got %lx.\n", desc.ddsCaps.dwCaps);
5417 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5418 ok(desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, desc.dwFlags);
5420 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
5421 ok(SUCCEEDED(hr), "Cannot get attached depth surface, hr %#lx.\n", hr);
5422 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
5424 desc.dwSize = sizeof(desc);
5425 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
5426 ok(SUCCEEDED(hr), "Cannot get z surface desc structure, hr %#lx.\n", hr);
5428 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %lu, %lu, got %lu, %lu.\n",
5429 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5430 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Unexpected caps %#lx.\n", desc.ddsCaps.dwCaps);
5431 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5432 ok(desc.dwFlags == expected_flags, "Expected %#lx for flags, got %#lx.\n", expected_flags, desc.dwFlags);
5434 IDirectDrawSurface_Release(d3drm_ds);
5435 IDirectDrawSurface_Release(ds);
5436 IDirectDrawSurface_Release(surface);
5437 IDirect3DDevice_Release(d3drm_d3ddevice1);
5438 IDirect3DRMDevice_Release(device1);
5439 ref2 = get_refcount((IUnknown *)d3drm1);
5440 ok(ref1 == ref2, "expected ref1 == ref2, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
5441 device_ref2 = get_refcount((IUnknown *)d3ddevice1);
5442 ok(device_ref2 == device_ref1, "Expected device_ref2 == device_ref1, got device_ref1 = %lu, device_ref2 = %lu.\n",
5443 device_ref1, device_ref2);
5444 d3d_ref2 = get_refcount((IUnknown *)d3d1);
5445 todo_wine ok(d3d_ref2 > d3d_ref1, "Expected d3d_ref2 > d3d_ref1, got d3d_ref1 = %lu, d3d_ref2 = %lu.\n", d3d_ref1,
5446 d3d_ref2);
5448 IDirect3DRM_Release(d3drm1);
5449 IDirect3DDevice_Release(d3ddevice1);
5450 IDirect3D_Release(d3d1);
5451 IDirectDraw_Release(ddraw1);
5452 DestroyWindow(window);
5455 static IDirect3DDevice2 *create_device2(IDirectDraw2 *ddraw, HWND window, IDirectDrawSurface **ds)
5457 static const DWORD z_depths[] = { 32, 24, 16 };
5458 IDirectDrawSurface *surface;
5459 IDirect3DDevice2 *device = NULL;
5460 DDSURFACEDESC surface_desc;
5461 IDirect3D2 *d3d;
5462 unsigned int i;
5463 HRESULT hr;
5464 RECT rc;
5466 GetClientRect(window, &rc);
5467 hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
5468 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
5470 memset(&surface_desc, 0, sizeof(surface_desc));
5471 surface_desc.dwSize = sizeof(surface_desc);
5472 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
5473 surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
5474 surface_desc.dwWidth = rc.right;
5475 surface_desc.dwHeight = rc.bottom;
5477 hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface, NULL);
5478 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
5480 hr = IDirectDraw2_QueryInterface(ddraw, &IID_IDirect3D2, (void **)&d3d);
5481 if (FAILED(hr))
5483 IDirectDrawSurface_Release(surface);
5484 *ds = NULL;
5485 return NULL;
5488 /* We used to use EnumDevices() for this, but it seems
5489 * D3DDEVICEDESC.dwDeviceZBufferBitDepth only has a very casual
5490 * relationship with reality. */
5491 for (i = 0; i < ARRAY_SIZE(z_depths); ++i)
5493 memset(&surface_desc, 0, sizeof(surface_desc));
5494 surface_desc.dwSize = sizeof(surface_desc);
5495 surface_desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT;
5496 surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
5497 U2(surface_desc).dwZBufferBitDepth = z_depths[i];
5498 surface_desc.dwWidth = rc.right;
5499 surface_desc.dwHeight = rc.bottom;
5500 if (FAILED(IDirectDraw2_CreateSurface(ddraw, &surface_desc, ds, NULL)))
5501 continue;
5503 hr = IDirectDrawSurface_AddAttachedSurface(surface, *ds);
5504 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#lx.\n", hr);
5505 if (FAILED(hr))
5507 IDirectDrawSurface_Release(*ds);
5508 continue;
5511 if (SUCCEEDED(IDirect3D2_CreateDevice(d3d, &IID_IDirect3DHALDevice, surface, &device)))
5512 break;
5514 IDirectDrawSurface_DeleteAttachedSurface(surface, 0, *ds);
5515 IDirectDrawSurface_Release(*ds);
5516 *ds = NULL;
5519 IDirect3D2_Release(d3d);
5520 IDirectDrawSurface_Release(surface);
5521 return device;
5524 static void test_create_device_from_d3d2(void)
5526 IDirectDraw *ddraw1 = NULL, *temp_ddraw1;
5527 IDirectDraw2 *ddraw2 = NULL, *temp_ddraw2;
5528 IDirect3D* d3d1;
5529 IDirect3D2 *d3d2 = NULL, *temp_d3d2;
5530 IDirect3DRM *d3drm1 = NULL;
5531 IDirect3DRM2 *d3drm2 = NULL;
5532 IDirect3DRMDevice *device1;
5533 IDirect3DRMDevice2 *device2 = (IDirect3DRMDevice2 *)0xdeadbeef;
5534 IDirect3DDevice *d3ddevice1;
5535 IDirect3DDevice2 *d3ddevice2 = NULL, *d3drm_d3ddevice2 = NULL, *temp_d3ddevice2;
5536 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_ds = NULL;
5537 DWORD expected_flags, ret_val;
5538 DDSCAPS caps = { DDSCAPS_ZBUFFER };
5539 DDSURFACEDESC desc;
5540 RECT rc;
5541 HWND window;
5542 ULONG ref1, ref2, ref3, ref4, ref5, device_ref1, device_ref2, d3d_ref1, d3d_ref2;
5543 HRESULT hr;
5545 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
5546 ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
5548 window = create_window();
5549 GetClientRect(window, &rc);
5551 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D2, (void **)&d3d2);
5552 ok(hr == DD_OK, "Cannot get IDirect3D2 interface, hr %#lx.\n", hr);
5553 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2);
5554 ok(hr == DD_OK, "Cannot get IDirectDraw2 interface, hr %#lx.\n", hr);
5555 d3d_ref1 = get_refcount((IUnknown *)d3d2);
5557 /* Create the immediate mode device */
5558 d3ddevice2 = create_device2(ddraw2, window, &ds);
5559 if (d3ddevice2 == NULL)
5561 win_skip("Cannot create IM device, skipping tests.\n");
5562 IDirect3D2_Release(d3d2);
5563 IDirectDraw2_Release(ddraw2);
5564 IDirectDraw_Release(ddraw1);
5565 return;
5567 device_ref1 = get_refcount((IUnknown *)d3ddevice2);
5569 hr = Direct3DRMCreate(&d3drm1);
5570 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
5571 ref1 = get_refcount((IUnknown *)d3drm1);
5573 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
5574 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM2 interface, hr %#lx.\n", hr);
5575 ref2 = get_refcount((IUnknown *)d3drm2);
5577 hr = IDirect3DRM2_CreateDeviceFromD3D(d3drm2, NULL, d3ddevice2, &device2);
5578 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#lx.\n", hr);
5579 ok(device2 == NULL, "Expected device returned == NULL, got %p.\n", device2);
5580 hr = IDirect3DRM2_CreateDeviceFromD3D(d3drm2, d3d2, NULL, &device2);
5581 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#lx.\n", hr);
5582 hr = IDirect3DRM2_CreateDeviceFromD3D(d3drm2, d3d2, d3ddevice2, NULL);
5583 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
5585 hr = IDirect3DRM2_CreateDeviceFromD3D(d3drm2, d3d2, d3ddevice2, &device2);
5586 ok(hr == DD_OK, "Failed to create IDirect3DRMDevice2 interface, hr %#lx\n", hr);
5587 ref3 = get_refcount((IUnknown *)d3drm1);
5588 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %lu , ref3 = %lu.\n", ref1, ref3);
5589 ref3 = get_refcount((IUnknown *)d3drm2);
5590 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
5591 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
5592 ok(device_ref2 > device_ref1, "Expected device_ref2 > device_ref1, got device_ref1 = %lu, device_ref2 = %lu.\n", device_ref1, device_ref2);
5593 d3d_ref2 = get_refcount((IUnknown *)d3d2);
5594 ok(d3d_ref2 > d3d_ref1, "Expected d3d_ref2 > d3d_ref1, got d3d_ref1 = %lu, d3d_ref2 = %lu.\n", d3d_ref1, d3d_ref2);
5595 ret_val = IDirect3DRMDevice2_GetWidth(device2);
5596 ok(ret_val == rc.right, "Expected device width = 300, got %lu.\n", ret_val);
5597 ret_val = IDirect3DRMDevice2_GetHeight(device2);
5598 ok(ret_val == rc.bottom, "Expected device height == 200, got %lu.\n", ret_val);
5600 hr = IDirectDraw_EnumSurfaces(ddraw1, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
5601 NULL, &surface, surface_callback);
5602 ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#lx.\n", hr);
5603 ok(surface == NULL, "No primary surface should have enumerated (%p).\n", surface);
5605 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3drm_d3ddevice2);
5606 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface, hr %#lx.\n", hr);
5607 ok(d3ddevice2 == d3drm_d3ddevice2, "Expected Immediate Mode device created == %p, got %p.\n", d3ddevice2, d3drm_d3ddevice2);
5609 /* Check properties of render target and depth surfaces */
5610 hr = IDirect3DDevice2_GetRenderTarget(d3drm_d3ddevice2, &surface);
5611 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
5613 memset(&desc, 0, sizeof(desc));
5614 desc.dwSize = sizeof(desc);
5615 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
5616 ok(hr == DD_OK, "Cannot get surface desc structure, hr %#lx.\n", hr);
5618 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %lu, %lu, got %lu, %lu.\n",
5619 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5620 ok((desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE),
5621 "Unexpected caps %lx.\n", desc.ddsCaps.dwCaps);
5622 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5623 ok(desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, desc.dwFlags);
5625 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
5626 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
5627 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
5629 desc.dwSize = sizeof(desc);
5630 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
5631 ok(hr == DD_OK, "Cannot get z surface desc structure, hr %#lx.\n", hr);
5633 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %lu, %lu, got %lu, %lu.\n",
5634 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5635 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Unexpected caps %lx.\n", desc.ddsCaps.dwCaps);
5636 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5637 ok(desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, desc.dwFlags);
5639 IDirectDrawSurface_Release(d3drm_ds);
5640 IDirectDrawSurface_Release(ds);
5641 IDirectDrawSurface_Release(surface);
5642 IDirect3DDevice2_Release(d3drm_d3ddevice2);
5643 IDirect3DRMDevice2_Release(device2);
5644 ref3 = get_refcount((IUnknown *)d3drm1);
5645 ok(ref1 == ref3, "expected ref1 == ref3, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
5646 ref3 = get_refcount((IUnknown *)d3drm2);
5647 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
5648 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
5649 ok(device_ref2 == device_ref1, "Expected device_ref2 == device_ref1, got device_ref1 = %lu, device_ref2 = %lu.\n", device_ref1, device_ref2);
5650 d3d_ref2 = get_refcount((IUnknown *)d3d2);
5651 ok(d3d_ref2 == d3d_ref1, "Expected d3d_ref2 == d3d_ref1, got d3d_ref1 = %lu, d3d_ref2 = %lu.\n", d3d_ref1, d3d_ref2);
5653 /* InitFromD3D tests */
5654 hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMDevice, NULL, &IID_IDirect3DRMDevice2, (void **)&device2);
5655 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice2 interface, hr %#lx.\n", hr);
5657 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1);
5658 ok(SUCCEEDED(hr), "Cannot get IDirect3D interface, hr %#lx.\n", hr);
5659 if (SUCCEEDED(hr = IDirect3DDevice2_QueryInterface(d3ddevice2, &IID_IDirect3DDevice, (void **)&d3ddevice1)))
5661 hr = IDirect3DRMDevice2_InitFromD3D(device2, d3d1, d3ddevice1);
5662 ok(hr == E_NOINTERFACE, "Expected hr == E_NOINTERFACE, got hr %#lx.\n", hr);
5663 hr = IDirect3DRMDevice2_InitFromD3D(device2, NULL, d3ddevice1);
5664 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
5665 hr = IDirect3DRMDevice2_InitFromD3D(device2, d3d1, NULL);
5666 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
5667 hr = IDirect3DRMDevice2_QueryInterface(device2, &IID_IDirect3DRMDevice, (void **)&device1);
5668 ok(SUCCEEDED(hr), "Cannot obtain IDirect3DRMDevice interface, hr %#lx.\n", hr);
5669 hr = IDirect3DRMDevice_InitFromD3D(device1, d3d1, d3ddevice1);
5670 todo_wine ok(hr == E_NOINTERFACE, "Expected hr == E_NOINTERFACE, got hr %#lx.\n", hr);
5671 IDirect3DRMDevice_Release(device1);
5672 if (SUCCEEDED(hr))
5674 IDirect3DRMDevice_Release(device1);
5675 hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMDevice, NULL, &IID_IDirect3DRMDevice2,
5676 (void **)&device2);
5677 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice2 interface, hr %#lx.\n", hr);
5680 IDirect3D_Release(d3d1);
5681 IDirect3DDevice_Release(d3ddevice1);
5683 hr = IDirect3DRMDevice2_InitFromD3D2(device2, NULL, d3ddevice2);
5684 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
5685 hr = IDirect3DRMDevice2_InitFromD3D2(device2, d3d2, NULL);
5686 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
5688 hr = IDirect3DRMDevice2_InitFromD3D2(device2, d3d2, d3ddevice2);
5689 ok(SUCCEEDED(hr), "Failed to initialise IDirect3DRMDevice2 interface, hr %#lx\n", hr);
5690 ref4 = get_refcount((IUnknown *)d3drm1);
5691 ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %lu , ref4 = %lu.\n", ref1, ref4);
5692 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
5693 ok(device_ref2 > device_ref1, "Expected device_ref2 > device_ref1, got device_ref1 = %lu, device_ref2 = %lu.\n",
5694 device_ref1, device_ref2);
5695 d3d_ref2 = get_refcount((IUnknown *)d3d2);
5696 ok(d3d_ref2 > d3d_ref1, "Expected d3d_ref2 > d3d_ref1, got d3d_ref1 = %lu, d3d_ref2 = %lu.\n", d3d_ref1, d3d_ref2);
5697 ret_val = IDirect3DRMDevice2_GetWidth(device2);
5698 ok(ret_val == rc.right, "Expected device width = 300, got %lu.\n", ret_val);
5699 ret_val = IDirect3DRMDevice2_GetHeight(device2);
5700 ok(ret_val == rc.bottom, "Expected device height == 200, got %lu.\n", ret_val);
5702 hr = IDirect3DRMDevice2_InitFromD3D2(device2, d3d2, d3ddevice2);
5703 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got hr %#lx.\n", hr);
5704 ref3 = get_refcount((IUnknown *)d3drm1);
5705 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %lu , ref3 = %lu.\n", ref1, ref3);
5706 ref3 = get_refcount((IUnknown *)d3ddevice2);
5707 ok(ref3 > device_ref2, "Expected ref3 > device_ref2, got ref3 = %lu, device_ref2 = %lu.\n", ref3, device_ref2);
5708 ref3 = get_refcount((IUnknown *)d3d2);
5709 ok(ref3 > d3d_ref2, "Expected ref3 > d3d_ref2, got ref3 = %lu, d3d_ref2 = %lu.\n", ref3, d3d_ref2);
5710 /* Release leaked references */
5711 while (IDirect3DRM_Release(d3drm1) > ref4);
5712 while (IDirect3DDevice2_Release(d3ddevice2) > device_ref2);
5713 while (IDirect3D2_Release(d3d2) > d3d_ref2);
5715 hr = DirectDrawCreate(NULL, &temp_ddraw1, NULL);
5716 ok(SUCCEEDED(hr), "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
5717 hr = IDirectDraw_QueryInterface(temp_ddraw1, &IID_IDirect3D2, (void **)&temp_d3d2);
5718 ok(SUCCEEDED(hr), "Cannot get IDirect3D2 interface, hr %#lx.\n", hr);
5719 ref5 = get_refcount((IUnknown *)temp_d3d2);
5721 hr = IDirectDraw_QueryInterface(temp_ddraw1, &IID_IDirectDraw2, (void **)&temp_ddraw2);
5722 ok(SUCCEEDED(hr), "Cannot get IDirectDraw2 interface, hr %#lx.\n", hr);
5724 temp_d3ddevice2 = create_device2(temp_ddraw2, window, &surface);
5725 hr = IDirect3DRMDevice2_InitFromD3D2(device2, temp_d3d2, temp_d3ddevice2);
5726 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got hr %#lx.\n", hr);
5727 ref3 = get_refcount((IUnknown *)d3drm1);
5728 ok(ref3 > ref4, "expected ref3 > ref4, got ref3 = %lu , ref4 = %lu.\n", ref3, ref4);
5729 ref3 = get_refcount((IUnknown *)temp_d3ddevice2);
5730 ok(ref3 == device_ref2, "Expected ref3 == device_ref2, got ref3 = %lu, device_ref2 = %lu.\n", ref3, device_ref2);
5731 ref3 = get_refcount((IUnknown *)temp_d3d2);
5732 ok(ref3 == d3d_ref2, "Expected ref3 == d3d_ref2, got ref3 = %lu, d3d_ref2 = %lu.\n", ref3, d3d_ref2);
5733 /* Release leaked references */
5734 while (IDirect3DRM_Release(d3drm1) > ref4);
5735 while (IDirect3DDevice2_Release(temp_d3ddevice2) > 0);
5736 while (IDirect3D2_Release(temp_d3d2) >= ref5);
5737 IDirectDrawSurface_Release(surface);
5738 IDirectDraw2_Release(temp_ddraw2);
5739 IDirectDraw_Release(temp_ddraw1);
5741 surface = NULL;
5742 hr = IDirectDraw_EnumSurfaces(ddraw1, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
5743 NULL, &surface, surface_callback);
5744 ok(SUCCEEDED(hr), "Failed to enumerate surfaces, hr %#lx.\n", hr);
5745 ok(surface == NULL, "No primary surface should have enumerated (%p).\n", surface);
5747 hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3drm_d3ddevice2);
5748 ok(SUCCEEDED(hr), "Cannot get IDirect3DDevice2 interface, hr %#lx.\n", hr);
5749 ok(d3ddevice2 == d3drm_d3ddevice2, "Expected Immediate Mode device created == %p, got %p.\n", d3ddevice2,
5750 d3drm_d3ddevice2);
5752 /* Check properties of render target and depth surfaces */
5753 hr = IDirect3DDevice2_GetRenderTarget(d3drm_d3ddevice2, &surface);
5754 ok(SUCCEEDED(hr), "Cannot get surface to the render target, hr %#lx.\n", hr);
5756 memset(&desc, 0, sizeof(desc));
5757 desc.dwSize = sizeof(desc);
5758 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
5759 ok(SUCCEEDED(hr), "Cannot get surface desc structure, hr %#lx.\n", hr);
5761 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %lu, %lu, got %lu, %lu.\n",
5762 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5763 ok((desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE),
5764 "Unexpected caps %#lx.\n", desc.ddsCaps.dwCaps);
5765 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5766 ok(desc.dwFlags == expected_flags, "Expected %#lx for flags, got %#lx.\n", expected_flags, desc.dwFlags);
5768 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
5769 ok(SUCCEEDED(hr), "Cannot get attached depth surface, hr %#lx.\n", hr);
5770 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
5772 desc.dwSize = sizeof(desc);
5773 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
5774 ok(SUCCEEDED(hr), "Cannot get z surface desc structure, hr %#lx.\n", hr);
5776 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %lu, %lu, got %lu, %lu.\n",
5777 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5778 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Unexpected caps %#lx.\n", desc.ddsCaps.dwCaps);
5779 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5780 ok(desc.dwFlags == expected_flags, "Expected %#lx for flags, got %#lx.\n", expected_flags, desc.dwFlags);
5782 IDirectDrawSurface_Release(d3drm_ds);
5783 IDirectDrawSurface_Release(ds);
5784 IDirectDrawSurface_Release(surface);
5785 IDirect3DDevice2_Release(d3drm_d3ddevice2);
5786 IDirect3DRMDevice2_Release(device2);
5787 ref3 = get_refcount((IUnknown *)d3drm1);
5788 ok(ref1 == ref3, "Expected ref1 == ref3, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
5789 ref3 = get_refcount((IUnknown *)d3drm2);
5790 ok(ref3 == ref2, "Expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
5791 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
5792 ok(device_ref2 == device_ref1, "Expected device_ref2 == device_ref1, got device_ref1 = %lu, device_ref2 = %lu.\n",
5793 device_ref1, device_ref2);
5794 d3d_ref2 = get_refcount((IUnknown *)d3d2);
5795 ok(d3d_ref2 == d3d_ref1, "Expected d3d_ref2 == d3d_ref1, got d3d_ref1 = %lu, d3d_ref2 = %lu.\n", d3d_ref1, d3d_ref2);
5797 IDirect3DRM2_Release(d3drm2);
5798 IDirect3DRM_Release(d3drm1);
5799 IDirect3DDevice2_Release(d3ddevice2);
5800 IDirect3D2_Release(d3d2);
5801 IDirectDraw2_Release(ddraw2);
5802 IDirectDraw_Release(ddraw1);
5803 DestroyWindow(window);
5806 static void test_create_device_from_d3d3(void)
5808 IDirectDraw *ddraw1 = NULL, *temp_ddraw1;
5809 IDirectDraw2 *ddraw2 = NULL, *temp_ddraw2;
5810 IDirect3D *d3d1;
5811 IDirect3D2 *d3d2 = NULL, *temp_d3d2;
5812 IDirect3DRM *d3drm1 = NULL;
5813 IDirect3DRM3 *d3drm3 = NULL;
5814 IDirect3DRMDevice *device1;
5815 IDirect3DRMDevice3 *device3 = (IDirect3DRMDevice3 *)0xdeadbeef;
5816 IDirect3DDevice *d3ddevice1;
5817 IDirect3DDevice2 *d3ddevice2 = NULL, *d3drm_d3ddevice2 = NULL, *temp_d3ddevice2;
5818 IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_ds = NULL;
5819 DWORD expected_flags, ret_val;
5820 DDSCAPS caps = { DDSCAPS_ZBUFFER };
5821 DDSURFACEDESC desc;
5822 RECT rc;
5823 HWND window;
5824 ULONG ref1, ref2, ref3, ref4, ref5, device_ref1, device_ref2, d3d_ref1, d3d_ref2;
5825 HRESULT hr;
5827 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
5828 ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
5830 window = create_window();
5831 GetClientRect(window, &rc);
5833 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D2, (void **)&d3d2);
5834 ok(hr == DD_OK, "Cannot get IDirect3D2 interface, hr %#lx.\n", hr);
5835 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2);
5836 ok(hr == DD_OK, "Cannot get IDirectDraw2 interface, hr %#lx.\n", hr);
5837 d3d_ref1 = get_refcount((IUnknown *)d3d2);
5839 /* Create the immediate mode device */
5840 d3ddevice2 = create_device2(ddraw2, window, &ds);
5841 if (d3ddevice2 == NULL)
5843 win_skip("Cannot create IM device, skipping tests.\n");
5844 IDirect3D2_Release(d3d2);
5845 IDirectDraw2_Release(ddraw2);
5846 IDirectDraw_Release(ddraw1);
5847 return;
5849 device_ref1 = get_refcount((IUnknown *)d3ddevice2);
5851 hr = Direct3DRMCreate(&d3drm1);
5852 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
5853 ref1 = get_refcount((IUnknown *)d3drm1);
5855 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
5856 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr);
5857 ref2 = get_refcount((IUnknown *)d3drm3);
5859 hr = IDirect3DRM3_CreateDeviceFromD3D(d3drm3, NULL, d3ddevice2, &device3);
5860 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#lx.\n", hr);
5861 ok(device3 == NULL, "Expected device returned == NULL, got %p.\n", device3);
5862 hr = IDirect3DRM3_CreateDeviceFromD3D(d3drm3, d3d2, NULL, &device3);
5863 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
5864 hr = IDirect3DRM3_CreateDeviceFromD3D(d3drm3, d3d2, d3ddevice2, NULL);
5865 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
5867 hr = IDirect3DRM3_CreateDeviceFromD3D(d3drm3, d3d2, d3ddevice2, &device3);
5868 ok(hr == DD_OK, "Failed to create IDirect3DRMDevice3 interface, hr %#lx\n", hr);
5869 ref3 = get_refcount((IUnknown *)d3drm1);
5870 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %lu , ref3 = %lu.\n", ref1, ref3);
5871 ref3 = get_refcount((IUnknown *)d3drm3);
5872 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
5873 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
5874 ok(device_ref2 > device_ref1, "Expected device_ref2 > device_ref1, got device_ref1 = %lu, device_ref2 = %lu.\n", device_ref1, device_ref2);
5875 ret_val = IDirect3DRMDevice3_GetWidth(device3);
5876 ok(ret_val == rc.right, "Expected device width = 300, got %lu.\n", ret_val);
5877 ret_val = IDirect3DRMDevice3_GetHeight(device3);
5878 ok(ret_val == rc.bottom, "Expected device height == 200, got %lu.\n", ret_val);
5880 hr = IDirectDraw_EnumSurfaces(ddraw1, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
5881 NULL, &surface, surface_callback);
5882 ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#lx.\n", hr);
5883 ok(surface == NULL, "No primary surface should have enumerated (%p).\n", surface);
5885 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3drm_d3ddevice2);
5886 ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice2 interface, hr %#lx.\n", hr);
5887 ok(d3ddevice2 == d3drm_d3ddevice2, "Expected Immediate Mode device created == %p, got %p.\n", d3ddevice2, d3drm_d3ddevice2);
5889 /* Check properties of render target and depth surfaces */
5890 hr = IDirect3DDevice2_GetRenderTarget(d3drm_d3ddevice2, &surface);
5891 ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr);
5893 memset(&desc, 0, sizeof(desc));
5894 desc.dwSize = sizeof(desc);
5895 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
5896 ok(hr == DD_OK, "Cannot get surface desc structure, hr %#lx.\n", hr);
5898 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %lu, %lu, got %lu, %lu.\n",
5899 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5900 ok((desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE),
5901 "Unexpected caps %#lx.\n", desc.ddsCaps.dwCaps);
5902 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5903 ok(desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, desc.dwFlags);
5905 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
5906 ok(hr == DD_OK, "Cannot get attached depth surface, hr %#lx.\n", hr);
5907 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
5909 desc.dwSize = sizeof(desc);
5910 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
5911 ok(hr == DD_OK, "Cannot get z surface desc structure, hr %#lx.\n", hr);
5913 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %lu, %lu, got %lu, %lu.\n",
5914 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
5915 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Unexpected caps %lx.\n", desc.ddsCaps.dwCaps);
5916 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
5917 ok(desc.dwFlags == expected_flags, "Expected %lx for flags, got %lx.\n", expected_flags, desc.dwFlags);
5919 IDirectDrawSurface_Release(d3drm_ds);
5920 IDirectDrawSurface_Release(ds);
5921 IDirectDrawSurface_Release(surface);
5922 IDirect3DDevice2_Release(d3drm_d3ddevice2);
5923 IDirect3DRMDevice3_Release(device3);
5924 ref3 = get_refcount((IUnknown *)d3drm1);
5925 ok(ref1 == ref3, "expected ref1 == ref3, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
5926 ref3 = get_refcount((IUnknown *)d3drm3);
5927 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
5928 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
5929 ok(device_ref2 == device_ref1, "Expected device_ref2 == device_ref1, got device_ref1 = %lu, device_ref2 = %lu.\n", device_ref1, device_ref2);
5930 d3d_ref2 = get_refcount((IUnknown *)d3d2);
5931 ok(d3d_ref2 == d3d_ref1, "Expected d3d_ref2 == d3d_ref1, got d3d_ref1 = %lu, d3d_ref2 = %lu.\n", d3d_ref1, d3d_ref2);
5933 /* InitFromD3D tests */
5934 hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMDevice, NULL, &IID_IDirect3DRMDevice3, (void **)&device3);
5935 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface, hr %#lx.\n", hr);
5937 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1);
5938 ok(SUCCEEDED(hr), "Cannot get IDirect3D interface, hr %#lx.\n", hr);
5939 if (SUCCEEDED(hr = IDirect3DDevice2_QueryInterface(d3ddevice2, &IID_IDirect3DDevice, (void **)&d3ddevice1)))
5941 hr = IDirect3DRMDevice3_InitFromD3D(device3, d3d1, d3ddevice1);
5942 ok(hr == E_NOINTERFACE, "Expected hr == E_NOINTERFACE, got hr %#lx.\n", hr);
5943 hr = IDirect3DRMDevice3_InitFromD3D(device3, NULL, d3ddevice1);
5944 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
5945 hr = IDirect3DRMDevice3_InitFromD3D(device3, d3d1, NULL);
5946 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
5947 hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice, (void **)&device1);
5948 ok(SUCCEEDED(hr), "Cannot obtain IDirect3DRMDevice interface, hr %#lx.\n", hr);
5949 hr = IDirect3DRMDevice_InitFromD3D(device1, d3d1, d3ddevice1);
5950 todo_wine ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
5951 IDirect3DRMDevice_Release(device1);
5952 if (SUCCEEDED(hr))
5954 IDirect3DRMDevice_Release(device1);
5955 hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMDevice, NULL, &IID_IDirect3DRMDevice3,
5956 (void **)&device3);
5957 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface, hr %#lx.\n", hr);
5960 IDirect3D_Release(d3d1);
5961 IDirect3DDevice_Release(d3ddevice1);
5963 hr = IDirect3DRMDevice3_InitFromD3D2(device3, NULL, d3ddevice2);
5964 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
5965 hr = IDirect3DRMDevice3_InitFromD3D2(device3, d3d2, NULL);
5966 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
5968 hr = IDirect3DRMDevice3_InitFromD3D2(device3, d3d2, d3ddevice2);
5969 ok(SUCCEEDED(hr), "Failed to initialise IDirect3DRMDevice2 interface, hr %#lx\n", hr);
5970 ref4 = get_refcount((IUnknown *)d3drm1);
5971 ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %lu , ref4 = %lu.\n", ref1, ref4);
5972 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
5973 ok(device_ref2 > device_ref1, "Expected device_ref2 > device_ref1, got device_ref1 = %lu, device_ref2 = %lu.\n",
5974 device_ref1, device_ref2);
5975 d3d_ref2 = get_refcount((IUnknown *)d3d2);
5976 ok(d3d_ref2 > d3d_ref1, "Expected d3d_ref2 > d3d_ref1, got d3d_ref1 = %lu, d3d_ref2 = %lu.\n", d3d_ref1, d3d_ref2);
5977 ret_val = IDirect3DRMDevice3_GetWidth(device3);
5978 ok(ret_val == rc.right, "Expected device width = 300, got %lu.\n", ret_val);
5979 ret_val = IDirect3DRMDevice3_GetHeight(device3);
5980 ok(ret_val == rc.bottom, "Expected device height == 200, got %lu.\n", ret_val);
5982 hr = IDirect3DRMDevice3_InitFromD3D2(device3, d3d2, d3ddevice2);
5983 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got hr %#lx.\n", hr);
5984 ref3 = get_refcount((IUnknown *)d3drm1);
5985 ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %lu , ref3 = %lu.\n", ref1, ref3);
5986 ref3 = get_refcount((IUnknown *)d3ddevice2);
5987 ok(ref3 > device_ref2, "Expected ref3 > device_ref2, got ref3 = %lu, device_ref2 = %lu.\n", ref3, device_ref2);
5988 ref3 = get_refcount((IUnknown *)d3d2);
5989 ok(ref3 > d3d_ref2, "Expected ref3 > d3d_ref2, got ref3 = %lu, d3d_ref2 = %lu.\n", ref3, d3d_ref2);
5990 /* Release leaked references */
5991 while (IDirect3DRM_Release(d3drm1) > ref4);
5992 while (IDirect3DDevice2_Release(d3ddevice2) > device_ref2);
5993 while (IDirect3D2_Release(d3d2) > d3d_ref2);
5995 hr = DirectDrawCreate(NULL, &temp_ddraw1, NULL);
5996 ok(SUCCEEDED(hr), "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
5997 hr = IDirectDraw_QueryInterface(temp_ddraw1, &IID_IDirect3D2, (void **)&temp_d3d2);
5998 ok(SUCCEEDED(hr), "Cannot get IDirect3D2 interface, hr %#lx.\n", hr);
5999 ref5 = get_refcount((IUnknown *)temp_d3d2);
6001 hr = IDirectDraw_QueryInterface(temp_ddraw1, &IID_IDirectDraw2, (void **)&temp_ddraw2);
6002 ok(SUCCEEDED(hr), "Cannot get IDirectDraw2 interface, hr %#lx.\n", hr);
6004 temp_d3ddevice2 = create_device2(temp_ddraw2, window, &surface);
6005 hr = IDirect3DRMDevice3_InitFromD3D2(device3, temp_d3d2, temp_d3ddevice2);
6006 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got hr %#lx.\n", hr);
6007 ref3 = get_refcount((IUnknown *)d3drm1);
6008 ok(ref3 > ref4, "expected ref3 > ref4, got ref3 = %lu , ref4 = %lu.\n", ref3, ref4);
6009 ref3 = get_refcount((IUnknown *)temp_d3ddevice2);
6010 ok(ref3 == device_ref2, "Expected ref3 == device_ref2, got ref3 = %lu, device_ref2 = %lu.\n", ref3, device_ref2);
6011 ref3 = get_refcount((IUnknown *)temp_d3d2);
6012 ok(ref3 == d3d_ref2, "Expected ref3 == d3d_ref2, got ref3 = %lu, d3d_ref2 = %lu.\n", ref3, d3d_ref2);
6013 /* Release leaked references */
6014 while (IDirect3DRM_Release(d3drm1) > ref4);
6015 while (IDirect3DDevice2_Release(temp_d3ddevice2) > 0);
6016 while (IDirect3D2_Release(temp_d3d2) >= ref5);
6017 IDirectDrawSurface_Release(surface);
6018 IDirectDraw2_Release(temp_ddraw2);
6019 IDirectDraw_Release(temp_ddraw1);
6021 surface = NULL;
6022 hr = IDirectDraw_EnumSurfaces(ddraw1, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST,
6023 NULL, &surface, surface_callback);
6024 ok(SUCCEEDED(hr), "Failed to enumerate surfaces, hr %#lx.\n", hr);
6025 ok(surface == NULL, "No primary surface should have enumerated (%p).\n", surface);
6027 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3drm_d3ddevice2);
6028 ok(SUCCEEDED(hr), "Cannot get IDirect3DDevice2 interface, hr %#lx.\n", hr);
6029 ok(d3ddevice2 == d3drm_d3ddevice2, "Expected Immediate Mode device created == %p, got %p.\n", d3ddevice2,
6030 d3drm_d3ddevice2);
6032 /* Check properties of render target and depth surfaces */
6033 hr = IDirect3DDevice2_GetRenderTarget(d3drm_d3ddevice2, &surface);
6034 ok(SUCCEEDED(hr), "Cannot get surface to the render target, hr %#lx.\n", hr);
6036 memset(&desc, 0, sizeof(desc));
6037 desc.dwSize = sizeof(desc);
6038 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
6039 ok(SUCCEEDED(hr), "Cannot get surface desc structure, hr %#lx.\n", hr);
6041 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %lu, %lu, got %lu, %lu.\n",
6042 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
6043 ok((desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE)) == (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE),
6044 "Unexpected caps %#lx.\n", desc.ddsCaps.dwCaps);
6045 expected_flags = DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
6046 ok(desc.dwFlags == expected_flags, "Expected %#lx for flags, got %#lx.\n", expected_flags, desc.dwFlags);
6048 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
6049 ok(SUCCEEDED(hr), "Cannot get attached depth surface, hr %#lx.\n", hr);
6050 ok(ds == d3drm_ds, "Expected depth surface (%p) == surface created internally (%p).\n", ds, d3drm_ds);
6052 desc.dwSize = sizeof(desc);
6053 hr = IDirectDrawSurface_GetSurfaceDesc(ds, &desc);
6054 ok(SUCCEEDED(hr), "Cannot get z surface desc structure, hr %#lx.\n", hr);
6056 ok((desc.dwWidth == rc.right) && (desc.dwHeight == rc.bottom), "Expected surface dimensions = %lu, %lu, got %lu, %lu.\n",
6057 rc.right, rc.bottom, desc.dwWidth, desc.dwHeight);
6058 ok((desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER, "Unexpected caps %#lx.\n",desc.ddsCaps.dwCaps);
6059 expected_flags = DDSD_ZBUFFERBITDEPTH | DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
6060 ok(desc.dwFlags == expected_flags, "Expected %#lx for flags, got %#lx.\n", expected_flags, desc.dwFlags);
6062 IDirectDrawSurface_Release(d3drm_ds);
6063 IDirectDrawSurface_Release(ds);
6064 IDirectDrawSurface_Release(surface);
6065 IDirect3DDevice2_Release(d3drm_d3ddevice2);
6066 IDirect3DRMDevice3_Release(device3);
6067 ref3 = get_refcount((IUnknown *)d3drm1);
6068 ok(ref1 == ref3, "expected ref1 == ref3, got ref1 = %lu, ref3 = %lu.\n", ref1, ref3);
6069 ref3 = get_refcount((IUnknown *)d3drm3);
6070 ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %lu , ref3 = %lu.\n", ref2, ref3);
6071 device_ref2 = get_refcount((IUnknown *)d3ddevice2);
6072 ok(device_ref2 == device_ref1, "Expected device_ref2 == device_ref1, got device_ref1 = %lu, device_ref2 = %lu.\n",
6073 device_ref1, device_ref2);
6074 d3d_ref2 = get_refcount((IUnknown *)d3d2);
6075 ok(d3d_ref2 == d3d_ref1, "Expected d3d_ref2 == d3d_ref1, got d3d_ref1 = %lu, d3d_ref2 = %lu.\n", d3d_ref1, d3d_ref2);
6077 IDirect3DRM3_Release(d3drm3);
6078 IDirect3DRM_Release(d3drm1);
6079 IDirect3DDevice2_Release(d3ddevice2);
6080 IDirect3D2_Release(d3d2);
6081 IDirectDraw2_Release(ddraw2);
6082 IDirectDraw_Release(ddraw1);
6083 DestroyWindow(window);
6086 static void test_create_device_1(void)
6088 IDirect3DRM *d3drm = NULL;
6089 IDirect3DRMDevice *device = (IDirect3DRMDevice *)0xdeadbeef;
6090 HRESULT hr;
6092 hr = Direct3DRMCreate(&d3drm);
6093 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
6095 hr = IDirect3DRM_CreateDevice(d3drm, 640, 480, &device);
6096 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == D3DRMERR_BADDEVICE, got hr %#lx.\n", hr);
6097 ok(device == NULL, "Expected device returned == NULL, got %p.\n", device);
6098 hr = IDirect3DRM_CreateDevice(d3drm, 640, 480, NULL);
6099 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
6101 IDirect3DRM_Release(d3drm);
6104 static void test_create_device_2(void)
6106 IDirect3DRM *d3drm = NULL;
6107 IDirect3DRM2 *d3drm2 = NULL;
6108 IDirect3DRMDevice2 *device2 = (IDirect3DRMDevice2 *)0xdeadbeef;
6109 HRESULT hr;
6111 hr = Direct3DRMCreate(&d3drm);
6112 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
6113 hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM2, (void **)&d3drm2);
6114 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr);
6116 hr = IDirect3DRM2_CreateDevice(d3drm2, 640, 480, &device2);
6117 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == D3DRMERR_BADDEVICE, got %#lx.\n", hr);
6118 ok(device2 == NULL, "Expected device returned == NULL, got %p.\n", device2);
6119 hr = IDirect3DRM2_CreateDevice(d3drm2, 640, 480, NULL);
6120 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
6122 IDirect3DRM2_Release(d3drm2);
6123 IDirect3DRM_Release(d3drm);
6126 static void test_create_device_3(void)
6128 IDirect3DRM *d3drm = NULL;
6129 IDirect3DRM3 *d3drm3 = NULL;
6130 IDirect3DRMDevice3 *device3 = (IDirect3DRMDevice3 *)0xdeadbeef;
6131 HRESULT hr;
6133 hr = Direct3DRMCreate(&d3drm);
6134 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
6135 hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM3, (void **)&d3drm3);
6136 ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr);
6138 hr = IDirect3DRM3_CreateDevice(d3drm3, 640, 480, &device3);
6139 ok(hr == D3DRMERR_BADDEVICE, "Expected hr == D3DRMERR_BADDEVICE, got %#lx.\n", hr);
6140 ok(device3 == NULL, "Expected device returned == NULL, got %p.\n", device3);
6141 hr = IDirect3DRM3_CreateDevice(d3drm3, 640, 480, NULL);
6142 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
6144 IDirect3DRM3_Release(d3drm3);
6145 IDirect3DRM_Release(d3drm);
6148 static char *create_bitmap(unsigned int w, unsigned int h, BOOL palettized)
6150 unsigned int bpp = palettized ? 8 : 24;
6151 BITMAPFILEHEADER file_header;
6152 DWORD written, size, ret;
6153 unsigned char *buffer;
6154 char path[MAX_PATH];
6155 unsigned int i, j;
6156 BITMAPINFO *info;
6157 char *filename;
6158 HANDLE file;
6160 ret = GetTempPathA(MAX_PATH, path);
6161 ok(ret, "Failed to get temporary file path.\n");
6162 filename = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
6163 ret = GetTempFileNameA(path, "d3d", 0, filename);
6164 ok(ret, "Failed to get filename.\n");
6165 file = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
6166 ok(file != INVALID_HANDLE_VALUE, "Failed to open temporary file \"%s\".\n", filename);
6168 size = FIELD_OFFSET(BITMAPINFO, bmiColors[palettized ? 256 : 0]);
6170 memset(&file_header, 0, sizeof(file_header));
6171 file_header.bfType = 0x4d42; /* BM */
6172 file_header.bfOffBits = sizeof(file_header) + size;
6173 file_header.bfSize = file_header.bfOffBits + w * h * (bpp / 8);
6174 ret = WriteFile(file, &file_header, sizeof(file_header), &written, NULL);
6175 ok(ret && written == sizeof(file_header), "Failed to write file header.\n");
6177 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
6178 info->bmiHeader.biSize = sizeof(info->bmiHeader);
6179 info->bmiHeader.biBitCount = bpp;
6180 info->bmiHeader.biPlanes = 1;
6181 info->bmiHeader.biWidth = w;
6182 info->bmiHeader.biHeight = h;
6183 info->bmiHeader.biCompression = BI_RGB;
6184 if (palettized)
6186 for (i = 0; i < 256; ++i)
6188 info->bmiColors[i].rgbBlue = i;
6189 info->bmiColors[i].rgbGreen = i;
6190 info->bmiColors[i].rgbRed = i;
6193 ret = WriteFile(file, info, size, &written, NULL);
6194 ok(ret && written == size, "Failed to write bitmap info.\n");
6195 HeapFree(GetProcessHeap(), 0, info);
6197 size = w * h * (bpp / 8);
6198 buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
6199 for (i = 0, j = 0; i < size;)
6201 if (palettized)
6203 buffer[i++] = j++;
6204 j %= 256;
6206 else
6208 buffer[i++] = j % 251;
6209 buffer[i++] = j % 239;
6210 buffer[i++] = j++ % 247;
6213 ret = WriteFile(file, buffer, size, &written, NULL);
6214 ok(ret && written == size, "Failed to write bitmap data.\n");
6215 HeapFree(GetProcessHeap(), 0, buffer);
6217 CloseHandle(file);
6219 return filename;
6222 static void test_bitmap_data(unsigned int test_idx, const D3DRMIMAGE *img,
6223 BOOL upside_down, unsigned int w, unsigned int h, BOOL palettized)
6225 const unsigned char *data = img->buffer1;
6226 unsigned int i, j;
6228 ok(img->width == w, "Test %u: Got unexpected image width %u, expected %u.\n", test_idx, img->width, w);
6229 ok(img->height == h, "Test %u: Got unexpected image height %u, expected %u.\n", test_idx, img->height, h);
6230 ok(img->aspectx == 1, "Test %u: Got unexpected image aspectx %u.\n", test_idx, img->aspectx);
6231 ok(img->aspecty == 1, "Test %u: Got unexpected image aspecty %u.\n", test_idx, img->aspecty);
6232 ok(!img->buffer2, "Test %u: Got unexpected image buffer2 %p.\n", test_idx, img->buffer2);
6234 /* The image is palettized if the total number of colors used is <= 256. */
6235 if (w * h > 256 && !palettized)
6237 /* D3drm aligns the 24bpp texture to 4 bytes in the buffer, with one
6238 * byte padding from 24bpp texture. */
6239 ok(img->depth == 32, "Test %u: Got unexpected image depth %u.\n", test_idx, img->depth);
6240 ok(img->rgb == TRUE, "Test %u: Got unexpected image rgb %#x.\n", test_idx, img->rgb);
6241 ok(img->bytes_per_line == w * 4, "Test %u: Got unexpected image bytes per line %u, expected %u.\n",
6242 test_idx, img->bytes_per_line, w * 4);
6243 ok(img->red_mask == 0xff0000, "Test %u: Got unexpected image red mask %#lx.\n", test_idx, img->red_mask);
6244 ok(img->green_mask == 0x00ff00, "Test %u: Got unexpected image green mask %#lx.\n", test_idx, img->green_mask);
6245 ok(img->blue_mask == 0x0000ff, "Test %u: Got unexpected image blue mask %#lx.\n", test_idx, img->blue_mask);
6246 ok(!img->alpha_mask, "Test %u: Got unexpected image alpha mask %#lx.\n", test_idx, img->alpha_mask);
6247 ok(!img->palette_size, "Test %u: Got unexpected palette size %u.\n", test_idx, img->palette_size);
6248 ok(!img->palette, "Test %u: Got unexpected image palette %p.\n", test_idx, img->palette);
6249 for (i = 0; i < h; ++i)
6251 for (j = 0; j < w; ++j)
6253 const unsigned char *ptr = &data[i * img->bytes_per_line + j * 4];
6254 unsigned int idx = upside_down ? (h - 1 - i) * w + j : i * w + j;
6256 if (ptr[0] != idx % 251 || ptr[1] != idx % 239 || ptr[2] != idx % 247 || ptr[3] != 0xff)
6258 ok(0, "Test %u: Got unexpected color 0x%02x%02x%02x%02x at position %u, %u, "
6259 "expected 0x%02x%02x%02x%02x.\n", test_idx, ptr[0], ptr[1], ptr[2], ptr[3],
6260 j, i, idx % 251, idx % 239, idx % 247, 0xff);
6261 return;
6265 return;
6268 ok(img->depth == 8, "Test %u: Got unexpected image depth %u.\n", test_idx, img->depth);
6269 ok(!img->rgb, "Test %u: Got unexpected image rgb %#x.\n", test_idx, img->rgb);
6270 ok(img->red_mask == 0xff, "Test %u: Got unexpected image red mask %#lx.\n", test_idx, img->red_mask);
6271 ok(img->green_mask == 0xff, "Test %u: Got unexpected image green mask %#lx.\n", test_idx, img->green_mask);
6272 ok(img->blue_mask == 0xff, "Test %u: Got unexpected image blue mask %#lx.\n", test_idx, img->blue_mask);
6273 ok(!img->alpha_mask, "Test %u: Got unexpected image alpha mask %#lx.\n", test_idx, img->alpha_mask);
6274 ok(!!img->palette, "Test %u: Got unexpected image palette %p.\n", test_idx, img->palette);
6275 if (!palettized)
6277 /* In this case, bytes_per_line is aligned to the next multiple of
6278 * 4 from width. */
6279 ok(img->bytes_per_line == ((w + 3) & ~3), "Test %u: Got unexpected image bytes per line %u, expected %u.\n",
6280 test_idx, img->bytes_per_line, (w + 3) & ~3);
6281 ok(img->palette_size == w * h, "Test %u: Got unexpected palette size %u, expected %u.\n",
6282 test_idx, img->palette_size, w * h);
6283 for (i = 0; i < img->palette_size; ++i)
6285 unsigned int idx = upside_down ? (h - 1) * w - i + (i % w) * 2 : i;
6286 ok(img->palette[i].red == idx % 251
6287 && img->palette[i].green == idx % 239 && img->palette[i].blue == idx % 247,
6288 "Test %u: Got unexpected palette entry (%u) color 0x%02x%02x%02x.\n",
6289 test_idx, i, img->palette[i].red, img->palette[i].green, img->palette[i].blue);
6290 ok(img->palette[i].flags == D3DRMPALETTE_READONLY,
6291 "Test %u: Got unexpected palette entry (%u) flags %#x.\n",
6292 test_idx, i, img->palette[i].flags);
6294 for (i = 0; i < h; ++i)
6296 for (j = 0; j < w; ++j)
6298 if (data[i * img->bytes_per_line + j] != i * w + j)
6300 ok(0, "Test %u: Got unexpected color 0x%02x at position %u, %u, expected 0x%02x.\n",
6301 test_idx, data[i * img->bytes_per_line + j], j, i, i * w + j);
6302 return;
6306 return;
6309 /* bytes_per_line is not always aligned by d3drm depending on the
6310 * format. */
6311 ok(img->bytes_per_line == w, "Test %u: Got unexpected image bytes per line %u, expected %u.\n",
6312 test_idx, img->bytes_per_line, w);
6313 ok(img->palette_size == 256, "Test %u: Got unexpected palette size %u.\n", test_idx, img->palette_size);
6314 for (i = 0; i < 256; ++i)
6316 ok(img->palette[i].red == i && img->palette[i].green == i && img->palette[i].blue == i,
6317 "Test %u: Got unexpected palette entry (%u) color 0x%02x%02x%02x.\n",
6318 test_idx, i, img->palette[i].red, img->palette[i].green, img->palette[i].blue);
6319 ok(img->palette[i].flags == D3DRMPALETTE_READONLY,
6320 "Test %u: Got unexpected palette entry (%u) flags %#x.\n",
6321 test_idx, i, img->palette[i].flags);
6323 for (i = 0; i < h; ++i)
6325 for (j = 0; j < w; ++j)
6327 unsigned int idx = upside_down ? (h - 1 - i) * w + j : i * w + j;
6328 if (data[i * img->bytes_per_line + j] != idx % 256)
6330 ok(0, "Test %u: Got unexpected color 0x%02x at position %u, %u, expected 0x%02x.\n",
6331 test_idx, data[i * img->bytes_per_line + j], j, i, idx % 256);
6332 return;
6338 static void test_load_texture(void)
6340 IDirect3DRMTexture3 *texture3;
6341 IDirect3DRMTexture2 *texture2;
6342 IDirect3DRMTexture *texture1;
6343 D3DRMIMAGE *d3drm_img;
6344 IDirect3DRM3 *d3drm3;
6345 IDirect3DRM2 *d3drm2;
6346 IDirect3DRM *d3drm1;
6347 ULONG ref1, ref2;
6348 unsigned int i;
6349 char *filename;
6350 HRESULT hr;
6351 BOOL ret;
6353 static const struct
6355 unsigned int w;
6356 unsigned int h;
6357 BOOL palettized;
6359 tests[] =
6361 {100, 100, TRUE },
6362 {99, 100, TRUE },
6363 {100, 100, FALSE},
6364 {99, 100, FALSE},
6365 {3, 39, FALSE},
6368 hr = Direct3DRMCreate(&d3drm1);
6369 ok(hr == D3DRM_OK, "Failed to create IDirect3DRM object, hr %#lx.\n", hr);
6370 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
6371 ok(SUCCEEDED(hr), "Failed to get IDirect3DRM2 interface, hr %#lx.\n", hr);
6372 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
6373 ok(SUCCEEDED(hr), "Failed to get IDirect3DRM3 interface, hr %#lx.\n", hr);
6374 ref1 = get_refcount((IUnknown *)d3drm1);
6376 /* Test all failures together. */
6377 texture1 = (IDirect3DRMTexture *)0xdeadbeef;
6378 hr = IDirect3DRM_LoadTexture(d3drm1, NULL, &texture1);
6379 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
6380 ok(!texture1, "Got unexpected texture %p.\n", texture1);
6381 texture1 = (IDirect3DRMTexture *)0xdeadbeef;
6382 hr = IDirect3DRM_LoadTexture(d3drm1, "", &texture1);
6383 ok(hr == D3DRMERR_FILENOTFOUND, "Got unexpected hr %#lx.\n", hr);
6384 ok(!texture1, "Got unexpected texture %p.\n", texture1);
6385 hr = IDirect3DRM_LoadTexture(d3drm1, NULL, NULL);
6386 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
6388 texture2 = (IDirect3DRMTexture2 *)0xdeadbeef;
6389 hr = IDirect3DRM2_LoadTexture(d3drm2, NULL, &texture2);
6390 ok(hr == D3DRMERR_FILENOTFOUND, "Got unexpected hr %#lx.\n", hr);
6391 ok(!texture2, "Got unexpected texture %p.\n", texture2);
6392 texture2 = (IDirect3DRMTexture2 *)0xdeadbeef;
6393 hr = IDirect3DRM2_LoadTexture(d3drm2, "", &texture2);
6394 ok(hr == D3DRMERR_FILENOTFOUND, "Got unexpected hr %#lx.\n", hr);
6395 ok(!texture2, "Got unexpected texture %p.\n", texture2);
6396 hr = IDirect3DRM2_LoadTexture(d3drm2, NULL, NULL);
6397 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
6399 texture3 = (IDirect3DRMTexture3 *)0xdeadbeef;
6400 hr = IDirect3DRM3_LoadTexture(d3drm3, NULL, &texture3);
6401 ok(hr == D3DRMERR_FILENOTFOUND, "Got unexpected hr %#lx.\n", hr);
6402 ok(!texture3, "Got unexpected texture %p.\n", texture3);
6403 texture3 = (IDirect3DRMTexture3 *)0xdeadbeef;
6404 hr = IDirect3DRM_LoadTexture(d3drm3, "", &texture3);
6405 ok(hr == D3DRMERR_FILENOTFOUND, "Got unexpected hr %#lx.\n", hr);
6406 ok(!texture3, "Got unexpected texture %p.\n", texture3);
6407 hr = IDirect3DRM3_LoadTexture(d3drm3, NULL, NULL);
6408 ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#lx.\n", hr);
6410 for (i = 0; i < ARRAY_SIZE(tests); ++i)
6412 winetest_push_context("Test %u", i);
6414 filename = create_bitmap(tests[i].w, tests[i].h, tests[i].palettized);
6416 hr = IDirect3DRM_LoadTexture(d3drm1, filename, &texture1);
6417 ok(SUCCEEDED(hr), "Failed to load texture, hr %#lx.\n", hr);
6418 ref2 = get_refcount((IUnknown *)d3drm1);
6419 ok(ref2 > ref1, "Expected ref2 > ref1, got ref1 %lu, ref2 %lu.\n", ref1, ref2);
6421 hr = IDirect3DRMTexture_InitFromFile(texture1, filename);
6422 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
6423 /* InitFromFile() seems to AddRef() IDirect3DRM even if it fails. */
6424 IDirect3DRM_Release(d3drm1);
6425 d3drm_img = IDirect3DRMTexture_GetImage(texture1);
6426 ok(!!d3drm_img, "Failed to get image.\n");
6427 test_bitmap_data(i * 7, d3drm_img, FALSE, tests[i].w, tests[i].h, tests[i].palettized);
6428 IDirect3DRMTexture_Release(texture1);
6429 ref2 = get_refcount((IUnknown *)d3drm1);
6430 ok(ref1 == ref2, "Expected ref1 == ref2, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
6431 hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_CDirect3DRMTexture,
6432 NULL, &IID_IDirect3DRMTexture, (void **)&texture1);
6433 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6434 hr = IDirect3DRMTexture_InitFromFile(texture1, NULL);
6435 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
6436 hr = IDirect3DRMTexture_InitFromFile(texture1, "");
6437 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
6438 hr = IDirect3DRMTexture_InitFromFile(texture1, filename);
6439 ok(SUCCEEDED(hr), "Failed to initialise texture from file, hr %#lx.\n", hr);
6440 d3drm_img = IDirect3DRMTexture_GetImage(texture1);
6441 ok(!!d3drm_img, "Failed to get image.\n");
6442 test_bitmap_data(i * 7 + 1, d3drm_img, FALSE, tests[i].w, tests[i].h, tests[i].palettized);
6443 IDirect3DRMTexture_Release(texture1);
6445 hr = IDirect3DRM2_LoadTexture(d3drm2, filename, &texture2);
6446 ok(SUCCEEDED(hr), "Failed to load texture, hr %#lx.\n", hr);
6447 ref2 = get_refcount((IUnknown *)d3drm1);
6448 ok(ref2 > ref1, "Expected ref2 > ref1, got ref1 %lu, ref2 %lu.\n", ref1, ref2);
6450 hr = IDirect3DRMTexture2_InitFromFile(texture2, filename);
6451 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
6452 IDirect3DRM_Release(d3drm1);
6453 d3drm_img = IDirect3DRMTexture2_GetImage(texture2);
6454 ok(!!d3drm_img, "Failed to get image.\n");
6455 test_bitmap_data(i * 7 + 2, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
6456 IDirect3DRMTexture2_Release(texture2);
6457 ref2 = get_refcount((IUnknown *)d3drm1);
6458 ok(ref1 == ref2, "Expected ref1 == ref2, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
6459 hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMTexture,
6460 NULL, &IID_IDirect3DRMTexture2, (void **)&texture2);
6461 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6462 hr = IDirect3DRMTexture2_InitFromFile(texture2, NULL);
6463 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
6464 hr = IDirect3DRMTexture2_InitFromFile(texture2, "");
6465 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
6466 hr = IDirect3DRMTexture2_InitFromFile(texture2, filename);
6467 ok(SUCCEEDED(hr), "Failed to initialise texture from file, hr %#lx.\n", hr);
6468 d3drm_img = IDirect3DRMTexture2_GetImage(texture2);
6469 ok(!!d3drm_img, "Failed to get image.\n");
6470 test_bitmap_data(i * 7 + 3, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
6471 IDirect3DRMTexture2_Release(texture2);
6473 hr = IDirect3DRM3_LoadTexture(d3drm3, filename, &texture3);
6474 ok(SUCCEEDED(hr), "Failed to load texture, hr %#lx.\n", hr);
6475 ref2 = get_refcount((IUnknown *)d3drm1);
6476 ok(ref2 > ref1, "Expected ref2 > ref1, got ref1 %lu, ref2 %lu.\n", ref1, ref2);
6478 hr = IDirect3DRMTexture3_InitFromFile(texture3, filename);
6479 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
6480 IDirect3DRM_Release(d3drm1);
6481 d3drm_img = IDirect3DRMTexture3_GetImage(texture3);
6482 ok(!!d3drm_img, "Failed to get image.\n");
6483 test_bitmap_data(i * 7 + 4, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
6484 /* Test whether querying a version 1 texture from version 3 causes a
6485 * change in the loading behavior. */
6486 hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)&texture1);
6487 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMTexture interface, hr %#lx.\n", hr);
6488 d3drm_img = IDirect3DRMTexture_GetImage(texture1);
6489 ok(!!d3drm_img, "Failed to get image.\n");
6490 test_bitmap_data(i * 7 + 5, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
6491 IDirect3DRMTexture_Release(texture1);
6492 IDirect3DRMTexture3_Release(texture3);
6493 ref2 = get_refcount((IUnknown *)d3drm1);
6494 ok(ref1 == ref2, "Expected ref1 == ref2, got ref1 = %lu, ref2 = %lu.\n", ref1, ref2);
6496 hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMTexture,
6497 NULL, &IID_IDirect3DRMTexture3, (void **)&texture3);
6498 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6499 hr = IDirect3DRMTexture3_InitFromFile(texture3, NULL);
6500 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
6501 hr = IDirect3DRMTexture3_InitFromFile(texture3, "");
6502 ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#lx.\n", hr);
6503 hr = IDirect3DRMTexture3_InitFromFile(texture3, filename);
6504 ok(SUCCEEDED(hr), "Failed to initialize texture from file, hr %#lx.\n", hr);
6505 d3drm_img = IDirect3DRMTexture3_GetImage(texture3);
6506 ok(!!d3drm_img, "Failed to get image.\n");
6507 test_bitmap_data(i * 7 + 6, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
6508 IDirect3DRMTexture3_Release(texture3);
6510 ret = DeleteFileA(filename);
6511 ok(ret, "Failed to delete bitmap \"%s\".\n", filename);
6512 HeapFree(GetProcessHeap(), 0, filename);
6514 winetest_pop_context();
6517 IDirect3DRM3_Release(d3drm3);
6518 IDirect3DRM2_Release(d3drm2);
6519 IDirect3DRM_Release(d3drm1);
6522 static void test_texture_qi(void)
6524 static const struct qi_test tests[] =
6526 { &IID_IDirect3DRM3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6527 { &IID_IDirect3DRM2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6528 { &IID_IDirect3DRM, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6529 { &IID_IDirect3DRMDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6530 { &IID_IDirect3DRMDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6531 { &IID_IDirect3DRMDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6532 { &IID_IDirect3DRMWinDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6533 { &IID_IDirect3DRMObject, &IID_IUnknown, &IID_IDirect3DRMTexture, S_OK },
6534 { &IID_IDirect3DRMViewport, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6535 { &IID_IDirect3DRMViewport2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6536 { &IID_IDirect3DRMFrame, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6537 { &IID_IDirect3DRMFrame2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6538 { &IID_IDirect3DRMFrame3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6539 { &IID_IDirect3DRMVisual, &IID_IUnknown, &IID_IDirect3DRMTexture, S_OK },
6540 { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6541 { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6542 { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6543 { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6544 { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6545 { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6546 { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6547 { &IID_IDirect3DRMTexture, &IID_IUnknown, &IID_IDirect3DRMTexture, S_OK },
6548 { &IID_IDirect3DRMTexture2, &IID_IUnknown, &IID_IDirect3DRMTexture2, S_OK },
6549 { &IID_IDirect3DRMTexture3, &IID_IUnknown, &IID_IDirect3DRMTexture3, S_OK },
6550 { &IID_IDirect3DRMWrap, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6551 { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6552 { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6553 { &IID_IDirect3DRMAnimation, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6554 { &IID_IDirect3DRMAnimation2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6555 { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6556 { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6557 { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6558 { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6559 { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6560 { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6561 { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6562 { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6563 { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6564 { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6565 { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6566 { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6567 { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6568 { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6569 { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6570 { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6571 { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6572 { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6573 { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6574 { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6575 { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6576 { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6577 { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6578 { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6579 { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6580 { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6581 { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6582 { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6583 { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6584 { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6585 { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6586 { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6587 { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6588 { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6589 { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6590 { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6591 { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6592 { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6593 { &IID_IUnknown, &IID_IUnknown, NULL, S_OK, },
6595 HRESULT hr;
6596 IDirect3DRM *d3drm1;
6597 IDirect3DRM2 *d3drm2;
6598 IDirect3DRM3 *d3drm3;
6599 IDirect3DRMTexture *texture1;
6600 IDirect3DRMTexture2 *texture2;
6601 IDirect3DRMTexture3 *texture3;
6602 IUnknown *unknown;
6603 char *filename;
6604 BOOL check;
6606 hr = Direct3DRMCreate(&d3drm1);
6607 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface, hr %#lx\n", hr);
6608 filename = create_bitmap(1, 1, TRUE);
6609 hr = IDirect3DRM_LoadTexture(d3drm1, filename, &texture1);
6610 ok(SUCCEEDED(hr), "Failed to load texture, hr %#lx.\n", hr);
6611 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture interface, hr %#lx\n", hr);
6612 hr = IDirect3DRMTexture_QueryInterface(texture1, &IID_IUnknown, (void **)&unknown);
6613 ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMTexture, hr %#lx\n", hr);
6614 IDirect3DRMTexture_Release(texture1);
6615 test_qi("texture1_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
6616 IUnknown_Release(unknown);
6618 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
6619 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface, hr %#lx.\n", hr);
6620 hr = IDirect3DRM2_LoadTexture(d3drm2, filename, &texture2);
6621 ok(SUCCEEDED(hr), "Failed to load texture, hr %#lx.\n", hr);
6622 hr = IDirect3DRMTexture2_QueryInterface(texture2, &IID_IUnknown, (void **)&unknown);
6623 ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMTexture2, hr %#lx\n", hr);
6624 IDirect3DRMTexture2_Release(texture2);
6625 test_qi("texture2_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
6626 IUnknown_Release(unknown);
6628 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
6629 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr);
6630 hr = IDirect3DRM3_LoadTexture(d3drm3, filename, &texture3);
6631 ok(SUCCEEDED(hr), "Failed to load texture, hr %#lx.\n", hr);
6632 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface, hr %#lx\n", hr);
6633 hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IUnknown, (void **)&unknown);
6634 ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMTexture3, hr %#lx\n", hr);
6635 IDirect3DRMTexture3_Release(texture3);
6636 test_qi("texture3_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
6637 IUnknown_Release(unknown);
6639 IDirect3DRM3_Release(d3drm3);
6640 IDirect3DRM2_Release(d3drm2);
6641 IDirect3DRM_Release(d3drm1);
6642 check = DeleteFileA(filename);
6643 ok(check, "Cannot delete image stored in %s (error = %ld).\n", filename, GetLastError());
6644 HeapFree(GetProcessHeap(), 0, filename);
6647 static void test_viewport_qi(void)
6649 IDirect3DRM *d3drm1;
6650 IDirect3DRM2 *d3drm2;
6651 IDirect3DRM3 *d3drm3;
6652 IDirect3DRMFrame *frame1, *camera1;
6653 IDirect3DRMFrame3 *frame3, *camera3;
6654 IDirect3DRMDevice *device1;
6655 IDirect3DRMDevice3 *device3;
6656 IDirectDrawClipper *clipper;
6657 IDirect3DRMViewport *viewport1;
6658 IDirect3DRMViewport2 *viewport2;
6659 IUnknown *unknown;
6660 GUID driver = IID_IDirect3DRGBDevice;
6661 HRESULT hr;
6663 static const struct qi_test tests[] =
6665 { &IID_IDirect3DRM3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6666 { &IID_IDirect3DRM2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6667 { &IID_IDirect3DRM, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6668 { &IID_IDirect3DRMDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6669 { &IID_IDirect3DRMDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6670 { &IID_IDirect3DRMDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6671 { &IID_IDirect3DRMWinDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6672 { &IID_IDirect3DRMObject, &IID_IUnknown, &IID_IDirect3DRMViewport, S_OK },
6673 { &IID_IDirect3DRMViewport, &IID_IUnknown, &IID_IDirect3DRMViewport, S_OK },
6674 { &IID_IDirect3DRMViewport2, &IID_IUnknown, &IID_IDirect3DRMViewport2, S_OK },
6675 { &IID_IDirect3DRMFrame, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6676 { &IID_IDirect3DRMFrame2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6677 { &IID_IDirect3DRMFrame3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6678 { &IID_IDirect3DRMVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6679 { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6680 { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6681 { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6682 { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6683 { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6684 { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6685 { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6686 { &IID_IDirect3DRMTexture, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6687 { &IID_IDirect3DRMTexture2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6688 { &IID_IDirect3DRMTexture3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6689 { &IID_IDirect3DRMWrap, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6690 { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6691 { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6692 { &IID_IDirect3DRMAnimation, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6693 { &IID_IDirect3DRMAnimation2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6694 { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6695 { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6696 { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6697 { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6698 { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6699 { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6700 { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6701 { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6702 { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6703 { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6704 { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6705 { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6706 { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6707 { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6708 { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6709 { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6710 { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6711 { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6712 { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6713 { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6714 { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6715 { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6716 { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6717 { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6718 { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6719 { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6720 { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6721 { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6722 { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6723 { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6724 { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6725 { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6726 { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6727 { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6728 { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6729 { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6730 { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6731 { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
6732 { &IID_IUnknown, &IID_IUnknown, NULL, S_OK, },
6735 hr = DirectDrawCreateClipper(0, &clipper, NULL);
6736 ok(SUCCEEDED(hr), "Cannot get IDirectDrawClipper interface, hr %#lx.\n", hr);
6738 hr = Direct3DRMCreate(&d3drm1);
6739 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
6741 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, 640, 480, &device1);
6742 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface, hr %#lx.\n", hr);
6743 hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &frame1);
6744 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame interface, hr %#lx\n", hr);
6745 hr = IDirect3DRM_CreateFrame(d3drm1, frame1, &camera1);
6746 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame interface, hr %#lx\n", hr);
6747 hr = IDirect3DRM_CreateViewport(d3drm1, device1, camera1, 0, 0, 640, 480, &viewport1);
6748 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport interface, hr %#lx\n", hr);
6749 hr = IDirect3DRMViewport_QueryInterface(viewport1, &IID_IUnknown, (void **)&unknown);
6750 ok(SUCCEEDED(hr), "Cannot get IUnknown interface, hr %#lx.\n", hr);
6751 IDirect3DRMViewport_Release(viewport1);
6752 test_qi("viewport1_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
6753 IUnknown_Release(unknown);
6755 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
6756 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface, hr %#lx.\n", hr);
6757 hr = IDirect3DRM2_CreateViewport(d3drm2, device1, camera1, 0, 0, 640, 480, &viewport1);
6758 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport interface, hr %#lx\n", hr);
6759 hr = IDirect3DRMViewport_QueryInterface(viewport1, &IID_IUnknown, (void **)&unknown);
6760 ok(SUCCEEDED(hr), "Cannot get IUnknown interface, hr %#lx.\n", hr);
6761 IDirect3DRMViewport_Release(viewport1);
6762 test_qi("viewport1_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
6763 IUnknown_Release(unknown);
6764 IDirect3DRMDevice_Release(device1);
6765 IDirect3DRMFrame_Release(camera1);
6766 IDirect3DRMFrame_Release(frame1);
6768 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
6769 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr);
6770 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, 640, 480, &device3);
6771 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface, hr %#lx.\n", hr);
6772 hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &frame3);
6773 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame3 interface, hr %#lx\n", hr);
6774 hr = IDirect3DRM3_CreateFrame(d3drm3, frame3, &camera3);
6775 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame3 interface, hr %#lx\n", hr);
6776 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, camera3, 0, 0, 640, 480, &viewport2);
6777 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport2 interface, hr %#lx\n", hr);
6778 hr = IDirect3DRMViewport2_QueryInterface(viewport2, &IID_IUnknown, (void **)&unknown);
6779 ok(SUCCEEDED(hr), "Cannot get IUnknown interface, hr %#lx.\n", hr);
6780 IDirect3DRMViewport_Release(viewport2);
6781 test_qi("viewport2_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
6782 IUnknown_Release(unknown);
6783 IDirect3DRMDevice3_Release(device3);
6784 IDirect3DRMFrame3_Release(camera3);
6785 IDirect3DRMFrame3_Release(frame3);
6787 IDirectDrawClipper_Release(clipper);
6788 IDirect3DRM3_Release(d3drm3);
6789 IDirect3DRM2_Release(d3drm2);
6790 IDirect3DRM_Release(d3drm1);
6793 static D3DCOLOR get_surface_color(IDirectDrawSurface *surface, UINT x, UINT y)
6795 RECT rect = { x, y, x + 1, y + 1 };
6796 DDSURFACEDESC surface_desc;
6797 D3DCOLOR color;
6798 HRESULT hr;
6800 memset(&surface_desc, 0, sizeof(surface_desc));
6801 surface_desc.dwSize = sizeof(surface_desc);
6803 hr = IDirectDrawSurface_Lock(surface, &rect, &surface_desc, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
6804 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx.\n", hr);
6805 if (FAILED(hr))
6806 return 0xdeadbeef;
6808 color = *((DWORD *)surface_desc.lpSurface) & 0x00ffffff;
6810 hr = IDirectDrawSurface_Unlock(surface, NULL);
6811 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
6813 return color;
6816 static IDirect3DDevice2 *create_device2_without_ds(IDirectDraw2 *ddraw, HWND window)
6818 IDirectDrawSurface *surface;
6819 IDirect3DDevice2 *device = NULL;
6820 DDSURFACEDESC surface_desc;
6821 IDirect3D2 *d3d;
6822 HRESULT hr;
6823 RECT rc;
6825 GetClientRect(window, &rc);
6826 hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
6827 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
6829 memset(&surface_desc, 0, sizeof(surface_desc));
6830 surface_desc.dwSize = sizeof(surface_desc);
6831 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
6832 surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
6833 surface_desc.dwWidth = rc.right;
6834 surface_desc.dwHeight = rc.bottom;
6836 hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface, NULL);
6837 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
6839 hr = IDirectDraw2_QueryInterface(ddraw, &IID_IDirect3D2, (void **)&d3d);
6840 if (FAILED(hr))
6842 IDirectDrawSurface_Release(surface);
6843 return NULL;
6846 IDirect3D2_CreateDevice(d3d, &IID_IDirect3DHALDevice, surface, &device);
6848 IDirect3D2_Release(d3d);
6849 IDirectDrawSurface_Release(surface);
6850 return device;
6853 static void clear_depth_surface(IDirectDrawSurface *surface, DWORD value)
6855 HRESULT hr;
6856 DDBLTFX fx;
6858 memset(&fx, 0, sizeof(fx));
6859 fx.dwSize = sizeof(fx);
6860 U5(fx).dwFillDepth = value;
6862 hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_DEPTHFILL | DDBLT_WAIT, &fx);
6863 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
6866 static void set_execute_data(IDirect3DExecuteBuffer *execute_buffer, UINT vertex_count, UINT offset, UINT len)
6868 D3DEXECUTEDATA exec_data;
6869 HRESULT hr;
6871 memset(&exec_data, 0, sizeof(exec_data));
6872 exec_data.dwSize = sizeof(exec_data);
6873 exec_data.dwVertexCount = vertex_count;
6874 exec_data.dwInstructionOffset = offset;
6875 exec_data.dwInstructionLength = len;
6876 hr = IDirect3DExecuteBuffer_SetExecuteData(execute_buffer, &exec_data);
6877 ok(SUCCEEDED(hr), "Failed to set execute data, hr %#lx.\n", hr);
6880 static void emit_set_ts(void **ptr, D3DTRANSFORMSTATETYPE state, DWORD value)
6882 D3DINSTRUCTION *inst = *ptr;
6883 D3DSTATE *ts = (D3DSTATE *)(inst + 1);
6885 inst->bOpcode = D3DOP_STATETRANSFORM;
6886 inst->bSize = sizeof(*ts);
6887 inst->wCount = 1;
6889 U1(*ts).dtstTransformStateType = state;
6890 U2(*ts).dwArg[0] = value;
6892 *ptr = ts + 1;
6895 static void emit_set_rs(void **ptr, D3DRENDERSTATETYPE state, DWORD value)
6897 D3DINSTRUCTION *inst = *ptr;
6898 D3DSTATE *rs = (D3DSTATE *)(inst + 1);
6900 inst->bOpcode = D3DOP_STATERENDER;
6901 inst->bSize = sizeof(*rs);
6902 inst->wCount = 1;
6904 U1(*rs).drstRenderStateType = state;
6905 U2(*rs).dwArg[0] = value;
6907 *ptr = rs + 1;
6910 static void emit_process_vertices(void **ptr, DWORD flags, WORD base_idx, DWORD vertex_count)
6912 D3DINSTRUCTION *inst = *ptr;
6913 D3DPROCESSVERTICES *pv = (D3DPROCESSVERTICES *)(inst + 1);
6915 inst->bOpcode = D3DOP_PROCESSVERTICES;
6916 inst->bSize = sizeof(*pv);
6917 inst->wCount = 1;
6919 pv->dwFlags = flags;
6920 pv->wStart = base_idx;
6921 pv->wDest = 0;
6922 pv->dwCount = vertex_count;
6923 pv->dwReserved = 0;
6925 *ptr = pv + 1;
6928 static void emit_tquad(void **ptr, WORD base_idx)
6930 D3DINSTRUCTION *inst = *ptr;
6931 D3DTRIANGLE *tri = (D3DTRIANGLE *)(inst + 1);
6933 inst->bOpcode = D3DOP_TRIANGLE;
6934 inst->bSize = sizeof(*tri);
6935 inst->wCount = 2;
6937 U1(*tri).v1 = base_idx;
6938 U2(*tri).v2 = base_idx + 1;
6939 U3(*tri).v3 = base_idx + 2;
6940 tri->wFlags = D3DTRIFLAG_START;
6941 ++tri;
6943 U1(*tri).v1 = base_idx + 2;
6944 U2(*tri).v2 = base_idx + 1;
6945 U3(*tri).v3 = base_idx + 3;
6946 tri->wFlags = D3DTRIFLAG_ODD;
6947 ++tri;
6949 *ptr = tri;
6952 static void emit_end(void **ptr)
6954 D3DINSTRUCTION *inst = *ptr;
6956 inst->bOpcode = D3DOP_EXIT;
6957 inst->bSize = 0;
6958 inst->wCount = 0;
6960 *ptr = inst + 1;
6963 static void d3d_draw_quad1(IDirect3DDevice *device, IDirect3DViewport *viewport)
6965 IDirect3DExecuteBuffer *execute_buffer;
6966 D3DEXECUTEBUFFERDESC exec_desc;
6967 HRESULT hr;
6968 void *ptr;
6969 UINT inst_length;
6970 D3DMATRIXHANDLE world_handle, view_handle, proj_handle;
6971 static D3DMATRIX mat =
6973 1.0f, 0.0f, 0.0f, 0.0f,
6974 0.0f, 1.0f, 0.0f, 0.0f,
6975 0.0f, 0.0f, 1.0f, 0.0f,
6976 0.0f, 0.0f, 0.0f, 1.0f,
6978 static const D3DLVERTEX quad_strip[] =
6980 {{-1.0f}, {-1.0f}, {0.00f}, 0, {0xffbada55}, {0}, {0.0f}, {0.0f}},
6981 {{-1.0f}, { 1.0f}, {0.00f}, 0, {0xffbada55}, {0}, {0.0f}, {0.0f}},
6982 {{ 1.0f}, {-1.0f}, {1.00f}, 0, {0xffbada55}, {0}, {0.0f}, {0.0f}},
6983 {{ 1.0f}, { 1.0f}, {1.00f}, 0, {0xffbada55}, {0}, {0.0f}, {0.0f}},
6986 hr = IDirect3DDevice_CreateMatrix(device, &world_handle);
6987 ok(hr == D3D_OK, "Creating a matrix object failed, hr %#lx.\n", hr);
6988 hr = IDirect3DDevice_SetMatrix(device, world_handle, &mat);
6989 ok(hr == D3D_OK, "Setting a matrix object failed, hr %#lx.\n", hr);
6990 hr = IDirect3DDevice_CreateMatrix(device, &view_handle);
6991 ok(hr == D3D_OK, "Creating a matrix object failed, hr %#lx.\n", hr);
6992 hr = IDirect3DDevice_SetMatrix(device, view_handle, &mat);
6993 ok(hr == D3D_OK, "Setting a matrix object failed, hr %#lx.\n", hr);
6994 hr = IDirect3DDevice_CreateMatrix(device, &proj_handle);
6995 ok(hr == D3D_OK, "Creating a matrix object failed, hr %#lx.\n", hr);
6996 hr = IDirect3DDevice_SetMatrix(device, proj_handle, &mat);
6997 ok(hr == D3D_OK, "Setting a matrix object failed, hr %#lx.\n", hr);
6999 memset(&exec_desc, 0, sizeof(exec_desc));
7000 exec_desc.dwSize = sizeof(exec_desc);
7001 exec_desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
7002 exec_desc.dwBufferSize = 1024;
7003 exec_desc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY;
7005 hr = IDirect3DDevice_CreateExecuteBuffer(device, &exec_desc, &execute_buffer, NULL);
7006 ok(SUCCEEDED(hr), "Failed to create execute buffer, hr %#lx.\n", hr);
7008 hr = IDirect3DExecuteBuffer_Lock(execute_buffer, &exec_desc);
7009 ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#lx.\n", hr);
7011 memcpy(exec_desc.lpData, quad_strip, sizeof(quad_strip));
7012 ptr = ((BYTE *)exec_desc.lpData) + sizeof(quad_strip);
7013 emit_set_ts(&ptr, D3DTRANSFORMSTATE_WORLD, world_handle);
7014 emit_set_ts(&ptr, D3DTRANSFORMSTATE_VIEW, view_handle);
7015 emit_set_ts(&ptr, D3DTRANSFORMSTATE_PROJECTION, proj_handle);
7016 emit_set_rs(&ptr, D3DRENDERSTATE_CLIPPING, FALSE);
7017 emit_set_rs(&ptr, D3DRENDERSTATE_ZENABLE, TRUE);
7018 emit_set_rs(&ptr, D3DRENDERSTATE_FOGENABLE, FALSE);
7019 emit_set_rs(&ptr, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
7020 emit_set_rs(&ptr, D3DRENDERSTATE_SHADEMODE, D3DSHADE_FLAT);
7022 emit_process_vertices(&ptr, D3DPROCESSVERTICES_TRANSFORM, 0, 4);
7023 emit_tquad(&ptr, 0);
7025 emit_end(&ptr);
7026 inst_length = (BYTE *)ptr - (BYTE *)exec_desc.lpData;
7027 inst_length -= sizeof(quad_strip);
7029 hr = IDirect3DExecuteBuffer_Unlock(execute_buffer);
7030 ok(SUCCEEDED(hr), "Failed to unlock execute buffer, hr %#lx.\n", hr);
7032 hr = IDirect3DDevice_BeginScene(device);
7033 set_execute_data(execute_buffer, 4, sizeof(quad_strip), inst_length);
7034 hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED);
7035 ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#lx.\n", hr);
7036 hr = IDirect3DDevice_EndScene(device);
7037 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7039 IDirect3DExecuteBuffer_Release(execute_buffer);
7042 static void test_viewport_clear1(void)
7044 DDSCAPS caps = { DDSCAPS_ZBUFFER };
7045 IDirectDraw *ddraw;
7046 IDirectDrawClipper *clipper;
7047 IDirect3DRM *d3drm1;
7048 IDirect3DRMFrame *frame1, *camera1;
7049 IDirect3DRMDevice *device1;
7050 IDirect3DViewport *d3d_viewport;
7051 IDirect3DRMViewport *viewport1;
7052 IDirect3DDevice *d3d_device1;
7053 IDirectDrawSurface *surface, *ds, *d3drm_ds;
7054 HWND window;
7055 GUID driver = IID_IDirect3DRGBDevice;
7056 HRESULT hr;
7057 D3DCOLOR ret_color;
7058 RECT rc;
7060 window = create_window();
7061 GetClientRect(window, &rc);
7063 hr = DirectDrawCreate(NULL, &ddraw, NULL);
7064 ok(SUCCEEDED(hr), "Cannot create IDirectDraw interface, hr %#lx.\n", hr);
7066 hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
7067 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
7069 hr = IDirectDraw_CreateClipper(ddraw, 0, &clipper, NULL);
7070 ok(SUCCEEDED(hr), "Cannot create clipper, hr %#lx.\n", hr);
7072 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
7073 ok(SUCCEEDED(hr), "Cannot set HWnd to Clipper, hr %#lx\n", hr);
7075 hr = Direct3DRMCreate(&d3drm1);
7076 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
7078 hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, rc.right, rc.bottom, &device1);
7079 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMDevice interface, hr %#lx\n", hr);
7081 hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &frame1);
7082 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame interface, hr %#lx\n", hr);
7083 hr = IDirect3DRM_CreateFrame(d3drm1, frame1, &camera1);
7084 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame interface, hr %#lx\n", hr);
7086 hr = IDirect3DRM_CreateViewport(d3drm1, device1, camera1, 0, 0, rc.right,
7087 rc.bottom, &viewport1);
7088 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport2 interface, hr %#lx\n", hr);
7090 /* Fetch immediate mode device and viewport */
7091 hr = IDirect3DRMDevice_GetDirect3DDevice(device1, &d3d_device1);
7092 ok(SUCCEEDED(hr), "Cannot get IDirect3DDevice interface, hr %#lx.\n", hr);
7093 hr = IDirect3DRMViewport_GetDirect3DViewport(viewport1, &d3d_viewport);
7094 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
7096 hr = IDirect3DDevice_QueryInterface(d3d_device1, &IID_IDirectDrawSurface, (void **)&surface);
7097 ok(SUCCEEDED(hr), "Cannot get surface to the render target, hr %#lx.\n", hr);
7099 ret_color = get_surface_color(surface, 320, 240);
7100 ok(compare_color(ret_color, 0, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7102 /* Clear uses the scene frame's background color. */
7103 hr = IDirect3DRMFrame_SetSceneBackgroundRGB(frame1, 1.0f, 1.0f, 1.0f);
7104 ok(SUCCEEDED(hr), "Cannot set scene background RGB, hr %#lx\n", hr);
7105 ret_color = IDirect3DRMFrame_GetSceneBackground(frame1);
7106 ok(ret_color == 0xffffffff, "Expected scene color returned == 0xffffffff, got %#lx.\n", ret_color);
7107 hr = IDirect3DRMFrame_SetSceneBackgroundRGB(camera1, 0.0f, 1.0f, 0.0f);
7108 ok(SUCCEEDED(hr), "Cannot set scene background RGB, hr %#lx\n", hr);
7109 ret_color = IDirect3DRMFrame_GetSceneBackground(camera1);
7110 ok(ret_color == 0xff00ff00, "Expected scene color returned == 0xff00ff00, got %#lx.\n", ret_color);
7112 CHECK_REFCOUNT(frame1, 1);
7113 hr = IDirect3DRMViewport_Clear(viewport1);
7114 ok(SUCCEEDED(hr), "Cannot clear viewport, hr %#lx.\n", hr);
7115 ret_color = get_surface_color(surface, 320, 240);
7116 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7117 CHECK_REFCOUNT(frame1, 1);
7119 hr = IDirect3DRMFrame_SetSceneBackgroundRGB(frame1, 0.0f, 0.0f, 1.0f);
7120 ok(SUCCEEDED(hr), "Cannot set scene background RGB, hr %#lx\n", hr);
7121 ret_color = IDirect3DRMFrame_GetSceneBackground(frame1);
7122 ok(ret_color == 0xff0000ff, "Expected scene color returned == 0xff00ff00, got %#lx.\n", ret_color);
7124 hr = IDirect3DRMViewport_Configure(viewport1, 0, 0, rc.right, rc.bottom);
7125 todo_wine ok(SUCCEEDED(hr), "Cannot configure viewport, hr %#lx.\n", hr);
7126 hr = IDirect3DRMViewport_Clear(viewport1);
7127 ok(SUCCEEDED(hr), "Cannot clear viewport, hr %#lx.\n", hr);
7128 ret_color = get_surface_color(surface, 100, 200);
7129 ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7131 d3d_draw_quad1(d3d_device1, d3d_viewport);
7133 ret_color = get_surface_color(surface, 100, 200);
7134 ok(compare_color(ret_color, 0x00bada55, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7136 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
7137 ok(SUCCEEDED(hr), "Cannot get attached depth surface, hr %#lx.\n", hr);
7139 hr = IDirect3DRMViewport_Configure(viewport1, 0, 0, rc.right, rc.bottom);
7140 todo_wine ok(SUCCEEDED(hr), "Cannot configure viewport, hr %#lx.\n", hr);
7141 hr = IDirect3DRMViewport_Clear(viewport1);
7142 ok(SUCCEEDED(hr), "Cannot clear viewport, hr %#lx.\n", hr);
7143 ret_color = get_surface_color(surface, 100, 200);
7144 ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7146 /* Fill the depth surface with a value lower than the quad's depth value. */
7147 clear_depth_surface(ds, 0x7fff);
7149 /* Depth test passes here */
7150 d3d_draw_quad1(d3d_device1, d3d_viewport);
7151 ret_color = get_surface_color(surface, 100, 200);
7152 ok(compare_color(ret_color, 0x00bada55, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7153 /* Depth test fails here */
7154 ret_color = get_surface_color(surface, 500, 400);
7155 ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7157 /* Check what happens if we release the depth surface that d3drm created, and clear the viewport */
7158 hr = IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds);
7159 ok(SUCCEEDED(hr), "Cannot delete attached surface, hr %#lx.\n", hr);
7160 d3drm_ds = (IDirectDrawSurface *)0xdeadbeef;
7161 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
7162 ok(hr == DDERR_NOTFOUND, "Expected hr == DDERR_NOTFOUND, got %#lx.\n", hr);
7163 ok(d3drm_ds == NULL, "Expected NULL z-surface, got %p.\n", d3drm_ds);
7165 clear_depth_surface(ds, 0x7fff);
7166 hr = IDirect3DRMViewport_Configure(viewport1, 0, 0, rc.right, rc.bottom);
7167 todo_wine ok(SUCCEEDED(hr), "Cannot configure viewport, hr %#lx.\n", hr);
7168 hr = IDirect3DRMViewport_Clear(viewport1);
7169 ok(SUCCEEDED(hr), "Cannot clear viewport, hr %#lx.\n", hr);
7171 ret_color = get_surface_color(surface, 100, 200);
7172 ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7174 hr = IDirectDrawSurface_AddAttachedSurface(surface, ds);
7175 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#lx.\n", hr);
7176 IDirectDrawSurface_Release(ds);
7178 d3d_draw_quad1(d3d_device1, d3d_viewport);
7180 ret_color = get_surface_color(surface, 100, 200);
7181 ok(compare_color(ret_color, 0x00bada55, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7182 ret_color = get_surface_color(surface, 500, 400);
7183 ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7185 IDirect3DViewport_Release(d3d_viewport);
7186 IDirectDrawSurface_Release(surface);
7187 IDirect3DDevice_Release(d3d_device1);
7188 IDirect3DRMViewport_Release(viewport1);
7189 IDirect3DRMFrame_Release(frame1);
7190 IDirect3DRMFrame_Release(camera1);
7191 IDirect3DRMDevice_Release(device1);
7192 IDirect3DRM_Release(d3drm1);
7193 IDirectDrawClipper_Release(clipper);
7194 IDirectDraw_Release(ddraw);
7195 DestroyWindow(window);
7198 static void draw_quad2(IDirect3DDevice2 *device, IDirect3DViewport *viewport)
7200 static D3DLVERTEX tquad[] =
7202 {{-1.0f}, {-1.0f}, {0.0f}, 0, {0xffbada55}, {0}, {0.0f}, {0.0f}},
7203 {{-1.0f}, { 1.0f}, {0.0f}, 0, {0xffbada55}, {0}, {0.0f}, {1.0f}},
7204 {{ 1.0f}, {-1.0f}, {1.0f}, 0, {0xffbada55}, {0}, {1.0f}, {0.0f}},
7205 {{ 1.0f}, { 1.0f}, {1.0f}, 0, {0xffbada55}, {0}, {1.0f}, {1.0f}},
7207 static D3DMATRIX mat =
7209 1.0f, 0.0f, 0.0f, 0.0f,
7210 0.0f, 1.0f, 0.0f, 0.0f,
7211 0.0f, 0.0f, 1.0f, 0.0f,
7212 0.0f, 0.0f, 0.0f, 1.0f,
7214 IDirect3DViewport2 *viewport2;
7215 HRESULT hr;
7217 hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &mat);
7218 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#lx.\n", hr);
7219 hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_VIEW, &mat);
7220 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#lx.\n", hr);
7221 hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, &mat);
7222 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
7224 hr = IDirect3DViewport_QueryInterface(viewport, &IID_IDirect3DViewport2, (void **)&viewport2);
7225 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport2 interface, hr %#lx.\n", hr);
7226 hr = IDirect3DDevice2_SetCurrentViewport(device, viewport2);
7227 ok(SUCCEEDED(hr), "Failed to activate the viewport, hr %#lx.\n", hr);
7228 IDirect3DViewport2_Release(viewport2);
7230 hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_ZENABLE, D3DZB_TRUE);
7231 ok(SUCCEEDED(hr), "Failed to enable z testing, hr %#lx.\n", hr);
7232 hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
7233 ok(SUCCEEDED(hr), "Failed to set the z function, hr %#lx.\n", hr);
7235 hr = IDirect3DDevice2_BeginScene(device);
7236 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7237 hr = IDirect3DDevice2_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DVT_LVERTEX, tquad, 4, 0);
7238 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7239 hr = IDirect3DDevice2_EndScene(device);
7240 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7243 static void test_viewport_clear2(void)
7245 DDSCAPS caps = { DDSCAPS_ZBUFFER };
7246 IDirect3D2 *d3d2;
7247 IDirectDraw *ddraw1;
7248 IDirectDraw2 *ddraw2;
7249 IDirectDrawClipper *clipper;
7250 IDirect3DRM *d3drm1;
7251 IDirect3DRM3 *d3drm3;
7252 IDirect3DRMFrame3 *frame3, *camera3;
7253 IDirect3DRMDevice3 *device3;
7254 IDirect3DViewport *d3d_viewport;
7255 IDirect3DRMViewport2 *viewport2;
7256 IDirect3DDevice2 *d3d_device2;
7257 IDirectDrawSurface *surface, *ds, *d3drm_ds;
7258 HWND window;
7259 GUID driver = IID_IDirect3DRGBDevice;
7260 HRESULT hr;
7261 D3DCOLOR ret_color;
7262 RECT rc;
7264 window = create_window();
7265 GetClientRect(window, &rc);
7267 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
7268 ok(SUCCEEDED(hr), "Cannot create IDirectDraw interface, hr %#lx.\n", hr);
7270 hr = IDirectDraw_SetCooperativeLevel(ddraw1, window, DDSCL_NORMAL);
7271 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
7273 hr = IDirectDraw_CreateClipper(ddraw1, 0, &clipper, NULL);
7274 ok(SUCCEEDED(hr), "Cannot create clipper, hr %#lx.\n", hr);
7276 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
7277 ok(SUCCEEDED(hr), "Cannot set HWnd to Clipper, hr %#lx.\n", hr);
7279 hr = Direct3DRMCreate(&d3drm1);
7280 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
7282 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
7283 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr);
7285 hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, rc.right, rc.bottom, &device3);
7286 ok(hr == D3DRM_OK, "Cannot get IDirect3DRMDevice3 interface, hr %#lx.\n", hr);
7288 hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &frame3);
7289 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame3 interface, hr %#lx.\n", hr);
7290 hr = IDirect3DRM3_CreateFrame(d3drm3, frame3, &camera3);
7291 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame3 interface, hr %#lx.\n", hr);
7293 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, camera3, 0, 0, rc.right,
7294 rc.bottom, &viewport2);
7295 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport2 interface, hr %#lx.\n", hr);
7297 /* Fetch immediate mode device in order to access render target and test its color. */
7298 hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3d_device2);
7299 ok(SUCCEEDED(hr), "Cannot get IDirect3DDevice2 interface, hr %#lx.\n", hr);
7301 hr = IDirect3DDevice2_GetRenderTarget(d3d_device2, &surface);
7302 ok(SUCCEEDED(hr), "Cannot get surface to the render target, hr %#lx.\n", hr);
7304 ret_color = get_surface_color(surface, 320, 240);
7305 ok(compare_color(ret_color, 0, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7307 /* Clear uses the scene frame's background color. */
7308 hr = IDirect3DRMFrame3_SetSceneBackgroundRGB(frame3, 1.0f, 1.0f, 1.0f);
7309 ok(SUCCEEDED(hr), "Cannot set scene background RGB, hr %#lx.\n", hr);
7310 ret_color = IDirect3DRMFrame3_GetSceneBackground(frame3);
7311 ok(ret_color == 0xffffffff, "Expected scene color returned == 0xffffffff, got %#lx.\n", ret_color);
7312 hr = IDirect3DRMFrame3_SetSceneBackgroundRGB(camera3, 0.0f, 1.0f, 0.0f);
7313 ok(SUCCEEDED(hr), "Cannot set scene background RGB, hr %#lx.\n", hr);
7314 ret_color = IDirect3DRMFrame3_GetSceneBackground(camera3);
7315 ok(ret_color == 0xff00ff00, "Expected scene color returned == 0xff00ff00, got %#lx.\n", ret_color);
7317 CHECK_REFCOUNT(frame3, 1);
7318 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL);
7319 ok(SUCCEEDED(hr), "Cannot clear viewport, hr %#lx.\n", hr);
7320 ret_color = get_surface_color(surface, 320, 240);
7321 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7322 CHECK_REFCOUNT(frame3, 1);
7324 hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport);
7325 ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface, hr %#lx.\n", hr);
7327 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL);
7328 ok(SUCCEEDED(hr), "Cannot clear viewport, hr %#lx.\n", hr);
7330 /* d3drm seems to be calling BeginScene when Clear is called. */
7331 hr = IDirect3DDevice2_BeginScene(d3d_device2);
7332 todo_wine ok(hr == D3DERR_SCENE_IN_SCENE, "Expected hr == D3DERR_SCENE_IN_SCENE, got %#lx.\n", hr);
7333 hr = IDirect3DDevice2_EndScene(d3d_device2);
7334 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7336 ret_color = get_surface_color(surface, 320, 240);
7337 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7339 /* We're using d3d to draw using IDirect3DDevice2 created from d3drm. */
7340 draw_quad2(d3d_device2, d3d_viewport);
7341 ret_color = get_surface_color(surface, 320, 240);
7342 ok(compare_color(ret_color, 0x00bada55, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7344 /* Without calling Configure, Clear doesn't work. */
7345 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL);
7346 ok(SUCCEEDED(hr), "Cannot clear viewport, hr %#lx.\n", hr);
7347 ret_color = get_surface_color(surface, 320, 240);
7348 todo_wine ok(compare_color(ret_color, 0x00bada55, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7350 hr = IDirect3DRMViewport2_Configure(viewport2, 0, 0, rc.right, rc.bottom);
7351 todo_wine ok(SUCCEEDED(hr), "Cannot configure viewport, hr %#lx.\n", hr);
7352 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL);
7353 ok(SUCCEEDED(hr), "Cannot clear viewport, hr %#lx.\n", hr);
7355 ret_color = get_surface_color(surface, 320, 240);
7356 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7358 /* Fetch attached depth surface and see if viewport clears it if it's detached from the render target. */
7359 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
7360 ok(SUCCEEDED(hr), "Cannot get attached depth surface, hr %#lx.\n", hr);
7362 clear_depth_surface(ds, 0x39);
7363 draw_quad2(d3d_device2, d3d_viewport);
7365 ret_color = get_surface_color(surface, 320, 240);
7366 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7368 hr = IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds);
7369 ok(SUCCEEDED(hr), "Cannot delete attached surface, hr %#lx.\n", hr);
7370 d3drm_ds = (IDirectDrawSurface *)0xdeadbeef;
7371 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &d3drm_ds);
7372 ok(hr == DDERR_NOTFOUND, "Expected hr == DDERR_NOTFOUND, got %#lx.\n", hr);
7373 ok(d3drm_ds == NULL, "Expected NULL z-surface, got %p.\n", d3drm_ds);
7375 clear_depth_surface(ds, 0x7fff);
7377 /* This version of Clear still clears the depth surface even if it's deleted from the render target. */
7378 hr = IDirect3DRMViewport2_Configure(viewport2, 0, 0, rc.right, rc.bottom);
7379 todo_wine ok(SUCCEEDED(hr), "Cannot configure viewport, hr %#lx.\n", hr);
7380 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL);
7381 ok(SUCCEEDED(hr), "Cannot clear viewport, hr %#lx.\n", hr);
7383 hr = IDirectDrawSurface_AddAttachedSurface(surface, ds);
7384 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#lx.\n", hr);
7385 ret_color = get_surface_color(surface, 320, 240);
7386 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7388 draw_quad2(d3d_device2, d3d_viewport);
7389 ret_color = get_surface_color(surface, 100, 200);
7390 ok(compare_color(ret_color, 0x00bada55, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7391 ret_color = get_surface_color(surface, 500, 400);
7392 todo_wine ok(compare_color(ret_color, 0x00bada55, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7394 /* Remove old draw contents */
7395 hr = IDirect3DRMFrame3_SetSceneBackgroundRGB(frame3, 0.0f, 1.0f, 0.0f);
7396 ok(SUCCEEDED(hr), "Cannot set scene background RGB, hr %#lx.\n", hr);
7397 hr = IDirect3DRMViewport2_Configure(viewport2, 0, 0, rc.right, rc.bottom);
7398 todo_wine ok(SUCCEEDED(hr), "Cannot configure viewport, hr %#lx.\n", hr);
7399 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL);
7400 ok(SUCCEEDED(hr), "Cannot clear viewport, hr %#lx.\n", hr);
7401 hr = IDirect3DRMFrame3_SetSceneBackgroundRGB(frame3, 1.0f, 1.0f, 1.0f);
7402 ok(SUCCEEDED(hr), "Cannot set scene background RGB, hr %#lx.\n", hr);
7404 /* Clear with no flags */
7405 hr = IDirect3DRMViewport2_Configure(viewport2, 0, 0, rc.right, rc.bottom);
7406 todo_wine ok(SUCCEEDED(hr), "Cannot configure viewport, hr %#lx.\n", hr);
7407 hr = IDirect3DRMViewport2_Clear(viewport2, 0);
7408 ok(SUCCEEDED(hr), "Cannot clear viewport, hr %#lx.\n", hr);
7409 ret_color = get_surface_color(surface, 320, 240);
7410 ok(compare_color(ret_color, 0x0000ff00, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7412 hr = IDirect3DRMViewport2_Configure(viewport2, 0, 0, rc.right, rc.bottom);
7413 todo_wine ok(SUCCEEDED(hr), "Cannot configure viewport, hr %#lx.\n", hr);
7414 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL);
7415 ok(SUCCEEDED(hr), "Cannot clear viewport, hr %#lx.\n", hr);
7416 ret_color = get_surface_color(surface, 320, 240);
7417 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7419 IDirect3DViewport_Release(d3d_viewport);
7420 IDirectDrawSurface_Release(surface);
7421 IDirectDrawSurface_Release(ds);
7422 IDirect3DDevice2_Release(d3d_device2);
7423 IDirect3DRMViewport2_Release(viewport2);
7424 IDirect3DRMDevice3_Release(device3);
7426 /* Create device without depth surface attached */
7427 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2);
7428 ok(SUCCEEDED(hr), "Cannot get IDirectDraw2 interface, hr %#lx.\n", hr);
7429 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D2, (void **)&d3d2);
7430 ok(SUCCEEDED(hr), "Cannot get IDirect3D2 interface, hr %#lx.\n", hr);
7431 d3d_device2 = create_device2_without_ds(ddraw2, window);
7432 if (!d3d_device2)
7433 goto cleanup;
7435 hr = IDirect3DRM3_CreateDeviceFromD3D(d3drm3, d3d2, d3d_device2, &device3);
7436 ok(SUCCEEDED(hr), "Failed to create IDirect3DRMDevice interface, hr %#lx.\n", hr);
7437 hr = IDirect3DRM3_CreateViewport(d3drm3, device3, camera3, 0, 0, rc.right,
7438 rc.bottom, &viewport2);
7439 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport2 interface, hr %#lx.\n", hr);
7440 hr = IDirect3DDevice2_GetRenderTarget(d3d_device2, &surface);
7441 ok(SUCCEEDED(hr), "Cannot get surface to the render target, hr %#lx.\n", hr);
7443 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL);
7444 ok(SUCCEEDED(hr), "Cannot clear viewport, hr %#lx.\n", hr);
7445 ret_color = get_surface_color(surface, 320, 240);
7446 ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
7448 hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ZBUFFER);
7449 ok(SUCCEEDED(hr), "Cannot clear viewport, hr %#lx.\n", hr);
7451 IDirectDrawSurface_Release(surface);
7452 IDirect3DRMViewport2_Release(viewport2);
7453 IDirect3DRMDevice3_Release(device3);
7454 IDirect3DDevice2_Release(d3d_device2);
7456 cleanup:
7457 IDirect3DRMFrame3_Release(camera3);
7458 IDirect3DRMFrame3_Release(frame3);
7459 IDirect3DRM3_Release(d3drm3);
7460 IDirect3DRM_Release(d3drm1);
7461 IDirectDrawClipper_Release(clipper);
7462 IDirect3D2_Release(d3d2);
7463 IDirectDraw2_Release(ddraw2);
7464 IDirectDraw_Release(ddraw1);
7465 DestroyWindow(window);
7468 static void test_create_texture_from_surface(void)
7470 D3DRMIMAGE testimg =
7472 0, 0, 0, 0, 0,
7473 TRUE, 0, (void *)0xcafebabe, NULL,
7474 0x000000ff, 0x0000ff00, 0x00ff0000, 0, 0, NULL
7476 IDirectDrawSurface *surface = NULL, *surface2 = NULL, *ds = NULL;
7477 IDirect3DRMTexture *texture1;
7478 IDirect3DRMTexture2 *texture2;
7479 IDirect3DRMTexture3 *texture3;
7480 IDirectDraw *ddraw = NULL;
7481 IDirect3DRM *d3drm1 = NULL;
7482 IDirect3DRM2 *d3drm2 = NULL;
7483 IDirect3DRM3 *d3drm3 = NULL;
7484 ULONG ref1, ref2, ref3;
7485 D3DRMIMAGE *image;
7486 DDSURFACEDESC desc;
7487 HWND window;
7488 HRESULT hr;
7489 RECT rc;
7491 hr = DirectDrawCreate(NULL, &ddraw, NULL);
7492 ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr);
7494 window = create_window();
7495 GetClientRect(window, &rc);
7497 hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
7498 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
7500 hr = Direct3DRMCreate(&d3drm1);
7501 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface, hr %#lx.\n", hr);
7503 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2);
7504 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface, hr %#lx.\n", hr);
7506 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
7507 ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr);
7509 /* Create a surface and use it to create a texture. */
7510 memset(&desc, 0, sizeof(desc));
7511 desc.dwSize = sizeof(desc);
7512 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
7513 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
7514 desc.dwWidth = rc.right;
7515 desc.dwHeight = rc.bottom;
7517 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
7518 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
7520 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface2, NULL);
7521 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
7523 /* Test NULL params */
7524 texture1 = (IDirect3DRMTexture *)0xdeadbeef;
7525 hr = IDirect3DRM_CreateTextureFromSurface(d3drm1, NULL, &texture1);
7526 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#lx.\n", hr);
7527 ok(!texture1, "Expected texture returned == NULL, got %p.\n", texture1);
7529 hr = IDirect3DRM_CreateTextureFromSurface(d3drm1, NULL, NULL);
7530 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#lx.\n", hr);
7532 texture2 = (IDirect3DRMTexture2 *)0xdeadbeef;
7533 hr = IDirect3DRM2_CreateTextureFromSurface(d3drm2, NULL, &texture2);
7534 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#lx.\n", hr);
7535 ok(!texture2, "Expected texture returned == NULL, got %p.\n", texture2);
7537 hr = IDirect3DRM2_CreateTextureFromSurface(d3drm2, NULL, NULL);
7538 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#lx.\n", hr);
7540 texture3 = (IDirect3DRMTexture3 *)0xdeadbeef;
7541 hr = IDirect3DRM3_CreateTextureFromSurface(d3drm3, NULL, &texture3);
7542 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#lx.\n", hr);
7543 ok(!texture3, "Expected texture returned == NULL, got %p.\n", texture3);
7545 hr = IDirect3DRM3_CreateTextureFromSurface(d3drm3, NULL, NULL);
7546 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#lx.\n", hr);
7548 ok(get_refcount((IUnknown *)surface) == 1, "Unexpected surface refcount.\n");
7549 hr = IDirect3DRM_CreateTextureFromSurface(d3drm1, surface, &texture1);
7550 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
7552 ok(get_refcount((IUnknown *)surface) == 2, "Unexpected surface refcount.\n");
7553 image = IDirect3DRMTexture_GetImage(texture1);
7554 ok(image == NULL, "Unexpected image, %p.\n", image);
7555 hr = IDirect3DRMTexture_InitFromSurface(texture1, NULL);
7556 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#lx.\n", hr);
7557 IDirect3DRMTexture_Release(texture1);
7559 ok(get_refcount((IUnknown *)surface) == 1, "Unexpected surface refcount.\n");
7560 hr = IDirect3DRM2_CreateTextureFromSurface(d3drm2, surface, &texture2);
7561 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
7562 ok(get_refcount((IUnknown *)surface) == 2, "Unexpected surface refcount.\n");
7563 image = IDirect3DRMTexture2_GetImage(texture2);
7564 ok(image == NULL, "Unexpected image, %p.\n", image);
7565 hr = IDirect3DRMTexture2_InitFromSurface(texture2, NULL);
7566 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#lx.\n", hr);
7567 IDirect3DRMTexture_Release(texture2);
7569 ok(get_refcount((IUnknown *)surface) == 1, "Unexpected surface refcount.\n");
7570 hr = IDirect3DRM3_CreateTextureFromSurface(d3drm3, surface, &texture3);
7571 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
7572 ok(get_refcount((IUnknown *)surface) == 2, "Unexpected surface refcount.\n");
7573 image = IDirect3DRMTexture3_GetImage(texture3);
7574 ok(image == NULL, "Unexpected image, %p.\n", image);
7575 hr = IDirect3DRMTexture3_InitFromSurface(texture3, NULL);
7576 ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got hr %#lx.\n", hr);
7577 hr = IDirect3DRMTexture3_GetSurface(texture3, 0, NULL);
7578 ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got hr %#lx.\n", hr);
7579 hr = IDirect3DRMTexture3_GetSurface(texture3, 0, &ds);
7580 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
7581 ok(ds == surface, "Expected same surface back.\n");
7582 IDirectDrawSurface_Release(ds);
7584 /* Init already initialized texture with same surface. */
7585 hr = IDirect3DRMTexture3_InitFromSurface(texture3, surface);
7586 ok(hr == D3DRMERR_BADOBJECT, "Expected a failure, hr %#lx.\n", hr);
7588 /* Init already initialized texture with different surface. */
7589 hr = IDirect3DRMTexture3_InitFromSurface(texture3, surface2);
7590 ok(hr == D3DRMERR_BADOBJECT, "Expected a failure, hr %#lx.\n", hr);
7592 hr = IDirect3DRMTexture3_GetSurface(texture3, 0, &ds);
7593 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
7594 ok(ds == surface, "Expected same surface back.\n");
7595 IDirectDrawSurface_Release(ds);
7597 ref1 = get_refcount((IUnknown *)d3drm1);
7598 ref2 = get_refcount((IUnknown *)d3drm2);
7599 ref3 = get_refcount((IUnknown *)d3drm3);
7600 hr = IDirect3DRMTexture3_InitFromImage(texture3, &testimg);
7601 ok(hr == D3DRMERR_BADOBJECT, "Expected a failure, hr %#lx.\n", hr);
7602 ok(ref1 < get_refcount((IUnknown *)d3drm1), "Expected d3drm1 reference taken.\n");
7603 ok(ref2 == get_refcount((IUnknown *)d3drm2), "Expected d3drm2 reference unchanged.\n");
7604 ok(ref3 == get_refcount((IUnknown *)d3drm3), "Expected d3drm3 reference unchanged.\n");
7605 /* Release leaked reference to d3drm1 */
7606 IDirect3DRM_Release(d3drm1);
7608 IDirect3DRMTexture_Release(texture3);
7610 /* Create from image, initialize from surface. */
7611 hr = IDirect3DRM3_CreateTexture(d3drm3, &testimg, &texture3);
7612 ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface, hr %#lx.\n", hr);
7614 ref1 = get_refcount((IUnknown *)d3drm1);
7615 ref2 = get_refcount((IUnknown *)d3drm2);
7616 ref3 = get_refcount((IUnknown *)d3drm3);
7617 hr = IDirect3DRMTexture3_InitFromSurface(texture3, surface);
7618 ok(hr == D3DRMERR_BADOBJECT, "Expected a failure, hr %#lx.\n", hr);
7619 ok(ref1 < get_refcount((IUnknown *)d3drm1), "Expected d3drm1 reference taken.\n");
7620 ok(ref2 == get_refcount((IUnknown *)d3drm2), "Expected d3drm2 reference unchanged.\n");
7621 ok(ref3 == get_refcount((IUnknown *)d3drm3), "Expected d3drm3 reference unchanged.\n");
7622 /* Release leaked reference to d3drm1 */
7623 IDirect3DRM_Release(d3drm1);
7624 IDirect3DRMTexture3_Release(texture3);
7626 IDirectDrawSurface_Release(surface2);
7627 IDirectDrawSurface_Release(surface);
7628 IDirect3DRM3_Release(d3drm3);
7629 IDirect3DRM2_Release(d3drm2);
7630 IDirect3DRM_Release(d3drm1);
7631 IDirectDraw_Release(ddraw);
7634 static void test_animation(void)
7636 IDirect3DRMAnimation2 *animation2;
7637 IDirect3DRMAnimation *animation;
7638 D3DRMANIMATIONOPTIONS options;
7639 IDirect3DRMObject *obj, *obj2;
7640 D3DRMANIMATIONKEY keys[10];
7641 IDirect3DRMFrame3 *frame3;
7642 IDirect3DRMFrame *frame;
7643 D3DRMANIMATIONKEY key;
7644 IDirect3DRM *d3drm1;
7645 D3DRMQUATERNION q;
7646 DWORD count, i;
7647 HRESULT hr;
7648 D3DVECTOR v;
7650 hr = Direct3DRMCreate(&d3drm1);
7651 ok(SUCCEEDED(hr), "Failed to create IDirect3DRM instance, hr %#lx.\n", hr);
7653 hr = IDirect3DRM_CreateAnimation(d3drm1, NULL);
7654 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
7656 CHECK_REFCOUNT(d3drm1, 1);
7657 hr = IDirect3DRM_CreateAnimation(d3drm1, &animation);
7658 ok(SUCCEEDED(hr), "Failed to create animation hr %#lx.\n", hr);
7659 CHECK_REFCOUNT(d3drm1, 2);
7661 test_class_name((IDirect3DRMObject *)animation, "Animation");
7663 hr = IDirect3DRMAnimation_QueryInterface(animation, &IID_IDirect3DRMAnimation2, (void **)&animation2);
7664 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMAnimation2, hr %#lx.\n", hr);
7665 ok(animation != (void *)animation2, "Expected different interface pointer.\n");
7667 hr = IDirect3DRMAnimation_QueryInterface(animation, &IID_IDirect3DRMObject, (void **)&obj);
7668 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, hr %#lx.\n", hr);
7670 hr = IDirect3DRMAnimation2_QueryInterface(animation2, &IID_IDirect3DRMObject, (void **)&obj2);
7671 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, hr %#lx.\n", hr);
7673 ok(obj == obj2 && obj == (IDirect3DRMObject *)animation, "Unexpected object pointer.\n");
7675 IDirect3DRMObject_Release(obj);
7676 IDirect3DRMObject_Release(obj2);
7678 /* Set animated frame, get it back. */
7679 hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &frame);
7680 ok(SUCCEEDED(hr), "Failed to create a frame, hr %#lx.\n", hr);
7682 hr = IDirect3DRMAnimation_SetFrame(animation, NULL);
7683 ok(SUCCEEDED(hr), "Failed to reset frame, hr %#lx.\n", hr);
7685 CHECK_REFCOUNT(frame, 1);
7686 hr = IDirect3DRMAnimation_SetFrame(animation, frame);
7687 ok(SUCCEEDED(hr), "Failed to set a frame, hr %#lx.\n", hr);
7688 CHECK_REFCOUNT(frame, 1);
7690 hr = IDirect3DRMAnimation2_GetFrame(animation2, NULL);
7691 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
7693 hr = IDirect3DRMAnimation2_GetFrame(animation2, &frame3);
7694 ok(SUCCEEDED(hr), "Failed to get the frame, hr %#lx.\n", hr);
7695 ok(frame3 != (void *)frame, "Unexpected interface pointer.\n");
7696 CHECK_REFCOUNT(frame, 2);
7698 IDirect3DRMFrame3_Release(frame3);
7700 hr = IDirect3DRMAnimation_SetFrame(animation, NULL);
7701 ok(SUCCEEDED(hr), "Failed to reset frame, hr %#lx.\n", hr);
7703 hr = IDirect3DRMFrame_QueryInterface(frame, &IID_IDirect3DRMFrame3, (void **)&frame3);
7704 ok(SUCCEEDED(hr), "Failed to get IDirect3DRMFrame3, hr %#lx.\n", hr);
7706 CHECK_REFCOUNT(frame3, 2);
7707 hr = IDirect3DRMAnimation2_SetFrame(animation2, frame3);
7708 ok(SUCCEEDED(hr), "Failed to set a frame, hr %#lx.\n", hr);
7709 CHECK_REFCOUNT(frame3, 2);
7711 IDirect3DRMFrame3_Release(frame3);
7712 IDirect3DRMFrame_Release(frame);
7714 /* Animation options. */
7715 options = IDirect3DRMAnimation_GetOptions(animation);
7716 ok(options == (D3DRMANIMATION_CLOSED | D3DRMANIMATION_LINEARPOSITION),
7717 "Unexpected default options %#lx.\n", options);
7719 /* Undefined mask value */
7720 hr = IDirect3DRMAnimation_SetOptions(animation, 0xf0000000);
7721 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
7723 options = IDirect3DRMAnimation_GetOptions(animation);
7724 ok(options == (D3DRMANIMATION_CLOSED | D3DRMANIMATION_LINEARPOSITION),
7725 "Unexpected default options %#lx.\n", options);
7727 /* Ambiguous mask */
7728 hr = IDirect3DRMAnimation_SetOptions(animation, D3DRMANIMATION_OPEN | D3DRMANIMATION_CLOSED);
7729 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
7731 hr = IDirect3DRMAnimation_SetOptions(animation, D3DRMANIMATION_LINEARPOSITION | D3DRMANIMATION_SPLINEPOSITION);
7732 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
7734 hr = IDirect3DRMAnimation_SetOptions(animation, D3DRMANIMATION_SCALEANDROTATION | D3DRMANIMATION_POSITION);
7735 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
7737 options = IDirect3DRMAnimation_GetOptions(animation);
7738 ok(options == (D3DRMANIMATION_CLOSED | D3DRMANIMATION_LINEARPOSITION),
7739 "Unexpected default options %#lx.\n", options);
7741 /* Mask contains undefined bits together with valid one. */
7742 hr = IDirect3DRMAnimation_SetOptions(animation, 0xf0000000 | D3DRMANIMATION_OPEN);
7743 ok(SUCCEEDED(hr), "Failed to set animation options, hr %#lx.\n", hr);
7745 options = IDirect3DRMAnimation_GetOptions(animation);
7746 ok(options == (0xf0000000 | D3DRMANIMATION_OPEN), "Unexpected animation options %#lx.\n", options);
7748 hr = IDirect3DRMAnimation_SetOptions(animation, D3DRMANIMATION_SCALEANDROTATION);
7749 ok(SUCCEEDED(hr), "Failed to set animation options, hr %#lx.\n", hr);
7751 options = IDirect3DRMAnimation_GetOptions(animation);
7752 ok(options == D3DRMANIMATION_SCALEANDROTATION, "Unexpected options %#lx.\n", options);
7754 hr = IDirect3DRMAnimation_SetOptions(animation, D3DRMANIMATION_OPEN);
7755 ok(SUCCEEDED(hr), "Failed to set animation options, hr %#lx.\n", hr);
7757 options = IDirect3DRMAnimation_GetOptions(animation);
7758 ok(options == D3DRMANIMATION_OPEN, "Unexpected options %#lx.\n", options);
7760 hr = IDirect3DRMAnimation_SetOptions(animation, 0);
7761 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
7763 options = IDirect3DRMAnimation_GetOptions(animation);
7764 ok(options == D3DRMANIMATION_OPEN, "Unexpected options %#lx.\n", options);
7766 /* Key management. */
7767 hr = IDirect3DRMAnimation_AddPositionKey(animation, 0.0f, 1.0f, 0.0f, 0.0f);
7768 ok(SUCCEEDED(hr), "Failed to add position key, hr %#lx.\n", hr);
7770 hr = IDirect3DRMAnimation_AddScaleKey(animation, 0.0f, 1.0f, 2.0f, 1.0f);
7771 ok(SUCCEEDED(hr), "Failed to add scale key, hr %#lx.\n", hr);
7773 hr = IDirect3DRMAnimation_AddPositionKey(animation, 0.0f, 2.0f, 0.0f, 0.0f);
7774 ok(SUCCEEDED(hr), "Failed to add position key, hr %#lx.\n", hr);
7776 hr = IDirect3DRMAnimation_AddPositionKey(animation, 99.0f, 3.0f, 1.0f, 0.0f);
7777 ok(SUCCEEDED(hr), "Failed to add position key, hr %#lx.\n", hr);
7779 hr = IDirect3DRMAnimation_AddPositionKey(animation, 80.0f, 4.0f, 1.0f, 0.0f);
7780 ok(SUCCEEDED(hr), "Failed to add position key, hr %#lx.\n", hr);
7782 v.x = 1.0f;
7783 v.y = 0.0f;
7784 v.z = 0.0f;
7785 D3DRMQuaternionFromRotation(&q, &v, 1.0f);
7787 /* NULL quaternion pointer leads to a crash on Windows. */
7788 hr = IDirect3DRMAnimation_AddRotateKey(animation, 0.0f, &q);
7789 ok(SUCCEEDED(hr), "Failed to add rotation key, hr %#lx.\n", hr);
7791 count = 0;
7792 memset(keys, 0, sizeof(keys));
7793 hr = IDirect3DRMAnimation2_GetKeys(animation2, 0.0f, 99.0f, &count, keys);
7794 ok(SUCCEEDED(hr), "Failed to get animation keys, hr %#lx.\n", hr);
7795 ok(count == 6, "Unexpected key count %lu.\n", count);
7797 ok(keys[0].dwKeyType == D3DRMANIMATION_ROTATEKEY, "Unexpected key type %lu.\n", keys[0].dwKeyType);
7798 ok(keys[1].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %lu.\n", keys[1].dwKeyType);
7799 ok(keys[2].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %lu.\n", keys[2].dwKeyType);
7800 ok(keys[3].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %lu.\n", keys[3].dwKeyType);
7801 ok(keys[4].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %lu.\n", keys[4].dwKeyType);
7802 ok(keys[5].dwKeyType == D3DRMANIMATION_SCALEKEY, "Unexpected key type %lu.\n", keys[5].dwKeyType);
7804 /* Relative order, keys are returned sorted by time. */
7805 ok(keys[1].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[1].dvTime);
7806 ok(keys[2].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[2].dvTime);
7807 ok(keys[3].dvTime == 80.0f, "Unexpected key time %.8e.\n", keys[3].dvTime);
7808 ok(keys[4].dvTime == 99.0f, "Unexpected key time %.8e.\n", keys[4].dvTime);
7810 /* For keys with same time, order they were added in is kept. */
7811 ok(keys[1].dvPositionKey.x == 1.0f, "Unexpected key position x %.8e.\n", keys[1].dvPositionKey.x);
7812 ok(keys[2].dvPositionKey.x == 2.0f, "Unexpected key position x %.8e.\n", keys[2].dvPositionKey.x);
7813 ok(keys[3].dvPositionKey.x == 4.0f, "Unexpected key position x %.8e.\n", keys[3].dvPositionKey.x);
7814 ok(keys[4].dvPositionKey.x == 3.0f, "Unexpected key position x %.8e.\n", keys[4].dvPositionKey.x);
7816 for (i = 0; i < count; i++)
7818 winetest_push_context("%lu", i);
7820 ok(keys[i].dwSize == sizeof(*keys), "Unexpected dwSize value %lu.\n", keys[i].dwSize);
7822 todo_wine
7824 switch (keys[i].dwKeyType)
7826 case D3DRMANIMATION_ROTATEKEY:
7827 ok((keys[i].dwID & 0xf0000000) == 0x40000000, "Unexpected id mask %#lx.\n", keys[i].dwID);
7828 break;
7829 case D3DRMANIMATION_POSITIONKEY:
7830 ok((keys[i].dwID & 0xf0000000) == 0x80000000, "Unexpected id mask %#lx.\n", keys[i].dwID);
7831 break;
7832 case D3DRMANIMATION_SCALEKEY:
7833 ok((keys[i].dwID & 0xf0000000) == 0xc0000000, "Unexpected id mask %#lx.\n", keys[i].dwID);
7834 break;
7835 default:
7836 ok(0, "Unknown key type %ld.\n", keys[i].dwKeyType);
7840 winetest_pop_context();
7843 /* No keys in this range. */
7844 count = 10;
7845 hr = IDirect3DRMAnimation2_GetKeys(animation2, 100.0f, 200.0f, &count, NULL);
7846 ok(hr == D3DRMERR_NOSUCHKEY, "Unexpected hr %#lx.\n", hr);
7847 ok(count == 0, "Unexpected key count %lu.\n", count);
7849 count = 10;
7850 hr = IDirect3DRMAnimation2_GetKeys(animation2, 100.0f, 200.0f, &count, keys);
7851 ok(hr == D3DRMERR_NOSUCHKEY, "Unexpected hr %#lx.\n", hr);
7852 ok(count == 0, "Unexpected key count %lu.\n", count);
7854 count = 10;
7855 hr = IDirect3DRMAnimation2_GetKeys(animation2, 0.0f, 0.0f, &count, NULL);
7856 ok(SUCCEEDED(hr), "Failed to get animation keys, hr %#lx.\n", hr);
7857 ok(count == 4, "Unexpected key count %lu.\n", count);
7859 hr = IDirect3DRMAnimation2_GetKeys(animation2, 0.0f, 100.0f, NULL, NULL);
7860 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
7862 /* Time is 0-based. */
7863 hr = IDirect3DRMAnimation2_GetKeys(animation2, -100.0f, -50.0f, NULL, NULL);
7864 ok(hr == D3DRMERR_BADVALUE, "Unexpected hr %#lx.\n", hr);
7866 count = 10;
7867 hr = IDirect3DRMAnimation2_GetKeys(animation2, -100.0f, -50.0f, &count, NULL);
7868 ok(hr == D3DRMERR_NOSUCHKEY, "Unexpected hr %#lx.\n", hr);
7869 ok(count == 0, "Unexpected key count %lu.\n", count);
7871 count = 10;
7872 hr = IDirect3DRMAnimation2_GetKeys(animation2, -100.0f, 100.0f, &count, NULL);
7873 ok(SUCCEEDED(hr), "Failed to get animation keys, hr %#lx.\n", hr);
7874 ok(count == 6, "Unexpected key count %lu.\n", count);
7876 /* AddKey() tests. */
7877 hr = IDirect3DRMAnimation2_AddKey(animation2, NULL);
7878 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7880 memset(&key, 0, sizeof(key));
7881 key.dwKeyType = D3DRMANIMATION_POSITIONKEY;
7882 hr = IDirect3DRMAnimation2_AddKey(animation2, &key);
7883 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7885 memset(&key, 0, sizeof(key));
7886 key.dwSize = sizeof(key) - 1;
7887 key.dwKeyType = D3DRMANIMATION_POSITIONKEY;
7888 hr = IDirect3DRMAnimation2_AddKey(animation2, &key);
7889 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7891 memset(&key, 0, sizeof(key));
7892 key.dwSize = sizeof(key) + 1;
7893 key.dwKeyType = D3DRMANIMATION_POSITIONKEY;
7894 hr = IDirect3DRMAnimation2_AddKey(animation2, &key);
7895 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7897 memset(&key, 0, sizeof(key));
7898 key.dwSize = sizeof(key);
7899 key.dwKeyType = D3DRMANIMATION_POSITIONKEY;
7900 key.dvPositionKey.x = 8.0f;
7901 hr = IDirect3DRMAnimation2_AddKey(animation2, &key);
7902 ok(SUCCEEDED(hr), "Failed to add key, hr %#lx.\n", hr);
7904 /* Delete tests. */
7905 hr = IDirect3DRMAnimation_AddRotateKey(animation, 0.0f, &q);
7906 ok(SUCCEEDED(hr), "Failed to add rotation key, hr %#lx.\n", hr);
7908 hr = IDirect3DRMAnimation_AddScaleKey(animation, 0.0f, 1.0f, 2.0f, 1.0f);
7909 ok(SUCCEEDED(hr), "Failed to add scale key, hr %#lx.\n", hr);
7911 count = 0;
7912 memset(keys, 0, sizeof(keys));
7913 hr = IDirect3DRMAnimation2_GetKeys(animation2, -1000.0f, 1000.0f, &count, keys);
7914 ok(SUCCEEDED(hr), "Failed to get key count, hr %#lx.\n", hr);
7915 ok(count == 9, "Unexpected key count %lu.\n", count);
7917 ok(keys[0].dwKeyType == D3DRMANIMATION_ROTATEKEY, "Unexpected key type %lu.\n", keys[0].dwKeyType);
7918 ok(keys[1].dwKeyType == D3DRMANIMATION_ROTATEKEY, "Unexpected key type %lu.\n", keys[1].dwKeyType);
7919 ok(keys[2].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %lu.\n", keys[2].dwKeyType);
7920 ok(keys[3].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %lu.\n", keys[3].dwKeyType);
7921 ok(keys[4].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %lu.\n", keys[4].dwKeyType);
7922 ok(keys[5].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %lu.\n", keys[5].dwKeyType);
7923 ok(keys[6].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %lu.\n", keys[6].dwKeyType);
7924 ok(keys[7].dwKeyType == D3DRMANIMATION_SCALEKEY, "Unexpected key type %lu.\n", keys[7].dwKeyType);
7925 ok(keys[8].dwKeyType == D3DRMANIMATION_SCALEKEY, "Unexpected key type %lu.\n", keys[8].dwKeyType);
7927 ok(keys[0].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[0].dvTime);
7928 ok(keys[1].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[1].dvTime);
7929 ok(keys[2].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[2].dvTime);
7930 ok(keys[3].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[3].dvTime);
7931 ok(keys[4].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[4].dvTime);
7932 ok(keys[5].dvTime == 80.0f, "Unexpected key time %.8e.\n", keys[5].dvTime);
7933 ok(keys[6].dvTime == 99.0f, "Unexpected key time %.8e.\n", keys[6].dvTime);
7934 ok(keys[7].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[7].dvTime);
7935 ok(keys[8].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[8].dvTime);
7937 hr = IDirect3DRMAnimation_DeleteKey(animation, -100.0f);
7938 ok(SUCCEEDED(hr), "Failed to delete keys, hr %#lx.\n", hr);
7940 hr = IDirect3DRMAnimation_DeleteKey(animation, 100.0f);
7941 ok(SUCCEEDED(hr), "Failed to delete keys, hr %#lx.\n", hr);
7943 /* Only first Position keys are not removed. */
7944 hr = IDirect3DRMAnimation_DeleteKey(animation, 0.0f);
7945 ok(SUCCEEDED(hr), "Failed to delete keys, hr %#lx.\n", hr);
7947 count = 0;
7948 memset(keys, 0, sizeof(keys));
7949 hr = IDirect3DRMAnimation2_GetKeys(animation2, 0.0f, 100.0f, &count, keys);
7950 ok(SUCCEEDED(hr), "Failed to get key count, hr %#lx.\n", hr);
7951 ok(count == 6, "Unexpected key count %lu.\n", count);
7953 ok(keys[0].dwKeyType == D3DRMANIMATION_ROTATEKEY, "Unexpected key type %lu.\n", keys[0].dwKeyType);
7954 ok(keys[1].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %lu.\n", keys[1].dwKeyType);
7955 ok(keys[2].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %lu.\n", keys[2].dwKeyType);
7956 ok(keys[3].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %lu.\n", keys[3].dwKeyType);
7957 ok(keys[4].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %lu.\n", keys[4].dwKeyType);
7958 ok(keys[5].dwKeyType == D3DRMANIMATION_SCALEKEY, "Unexpected key type %lu.\n", keys[5].dwKeyType);
7960 ok(keys[0].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[0].dvTime);
7961 ok(keys[1].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[1].dvTime);
7962 ok(keys[2].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[2].dvTime);
7963 ok(keys[3].dvTime == 80.0f, "Unexpected key time %.8e.\n", keys[3].dvTime);
7964 ok(keys[4].dvTime == 99.0f, "Unexpected key time %.8e.\n", keys[4].dvTime);
7965 ok(keys[5].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[5].dvTime);
7967 hr = IDirect3DRMAnimation_DeleteKey(animation, 0.0f);
7968 ok(SUCCEEDED(hr), "Failed to delete keys, hr %#lx.\n", hr);
7970 count = 0;
7971 hr = IDirect3DRMAnimation2_GetKeys(animation2, 0.0f, 100.0f, &count, NULL);
7972 ok(SUCCEEDED(hr), "Failed to get key count, hr %#lx.\n", hr);
7973 ok(count == 3, "Unexpected key count %lu.\n", count);
7975 IDirect3DRMAnimation2_Release(animation2);
7976 IDirect3DRMAnimation_Release(animation);
7978 IDirect3DRM_Release(d3drm1);
7981 static void test_animation_qi(void)
7983 static const struct qi_test tests[] =
7985 { &IID_IDirect3DRMAnimation2, &IID_IUnknown, &IID_IDirect3DRMAnimation2, S_OK },
7986 { &IID_IDirect3DRMAnimation, &IID_IUnknown, &IID_IDirect3DRMAnimation, S_OK },
7987 { &IID_IDirect3DRM, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7988 { &IID_IDirect3DRMDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7989 { &IID_IDirect3DRMObject, &IID_IUnknown, &IID_IDirect3DRMAnimation, S_OK },
7990 { &IID_IDirect3DRMDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7991 { &IID_IDirect3DRMDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7992 { &IID_IDirect3DRMViewport, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7993 { &IID_IDirect3DRMViewport2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7994 { &IID_IDirect3DRM3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7995 { &IID_IDirect3DRM2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7996 { &IID_IDirect3DRMVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7997 { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7998 { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
7999 { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8000 { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8001 { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8002 { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8003 { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8004 { &IID_IDirect3DRMTexture, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8005 { &IID_IDirect3DRMTexture2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8006 { &IID_IDirect3DRMTexture3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8007 { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8008 { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8009 { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8010 { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8011 { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8012 { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8013 { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8014 { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8015 { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8016 { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8017 { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8018 { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8019 { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8020 { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8021 { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8022 { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8023 { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8024 { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8025 { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8026 { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8027 { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8028 { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8029 { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8030 { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8031 { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8032 { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8033 { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8034 { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8035 { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8036 { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8037 { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8038 { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8039 { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8040 { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8041 { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8042 { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8043 { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8044 { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8045 { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8046 { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8047 { &IID_IUnknown, &IID_IUnknown, NULL, S_OK },
8049 IDirect3DRMAnimation2 *animation2;
8050 IDirect3DRMAnimation *animation;
8051 IDirect3DRM3 *d3drm3;
8052 IDirect3DRM *d3drm1;
8053 IUnknown *unknown;
8054 HRESULT hr;
8056 hr = Direct3DRMCreate(&d3drm1);
8057 ok(SUCCEEDED(hr), "Failed to create d3drm instance, hr %#lx.\n", hr);
8059 hr = IDirect3DRM_CreateAnimation(d3drm1, &animation);
8060 ok(SUCCEEDED(hr), "Failed to create animation hr %#lx.\n", hr);
8062 hr = IDirect3DRMAnimation_QueryInterface(animation, &IID_IUnknown, (void **)&unknown);
8063 ok(SUCCEEDED(hr), "Failed to get IUnknown from animation, hr %#lx.\n", hr);
8064 IDirect3DRMAnimation_Release(animation);
8066 test_qi("animation_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
8067 IUnknown_Release(unknown);
8069 hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
8070 ok(SUCCEEDED(hr), "Failed to get IDirect3DRM3, hr %#lx.\n", hr);
8072 hr = IDirect3DRM3_CreateAnimation(d3drm3, &animation2);
8073 ok(SUCCEEDED(hr), "Failed to create animation hr %#lx.\n", hr);
8075 hr = IDirect3DRMAnimation2_QueryInterface(animation2, &IID_IUnknown, (void **)&unknown);
8076 ok(SUCCEEDED(hr), "Failed to get IUnknown from animation, hr %#lx.\n", hr);
8077 IDirect3DRMAnimation2_Release(animation2);
8079 test_qi("animation2_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
8080 IUnknown_Release(unknown);
8082 IDirect3DRM3_Release(d3drm3);
8083 IDirect3DRM_Release(d3drm1);
8086 static void test_wrap(void)
8088 IDirect3DRMWrap *wrap;
8089 IDirect3DRM *d3drm1;
8090 HRESULT hr;
8092 hr = Direct3DRMCreate(&d3drm1);
8093 ok(SUCCEEDED(hr), "Failed to create IDirect3DRM instance, hr %#lx.\n", hr);
8095 hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_CDirect3DRMWrap, NULL, &IID_IDirect3DRMWrap, (void **)&wrap);
8096 ok(SUCCEEDED(hr), "Failed to create wrap instance, hr %#lx.\n", hr);
8098 test_class_name((IDirect3DRMObject *)wrap, "");
8100 IDirect3DRMWrap_Release(wrap);
8101 IDirect3DRM_Release(d3drm1);
8104 static void test_wrap_qi(void)
8106 static const struct qi_test tests[] =
8108 { &IID_IDirect3DRMWrap, &IID_IUnknown, &IID_IDirect3DRMWrap, S_OK },
8109 { &IID_IDirect3DRM, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8110 { &IID_IDirect3DRMDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8111 { &IID_IDirect3DRMObject, &IID_IUnknown, &IID_IDirect3DRMWrap, S_OK },
8112 { &IID_IDirect3DRMDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8113 { &IID_IDirect3DRMDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8114 { &IID_IDirect3DRMViewport, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8115 { &IID_IDirect3DRMViewport2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8116 { &IID_IDirect3DRM3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8117 { &IID_IDirect3DRM2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8118 { &IID_IDirect3DRMVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8119 { &IID_IDirect3DRMMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8120 { &IID_IDirect3DRMMeshBuilder, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8121 { &IID_IDirect3DRMMeshBuilder2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8122 { &IID_IDirect3DRMMeshBuilder3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8123 { &IID_IDirect3DRMFace, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8124 { &IID_IDirect3DRMFace2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8125 { &IID_IDirect3DRMLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8126 { &IID_IDirect3DRMTexture, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8127 { &IID_IDirect3DRMTexture2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8128 { &IID_IDirect3DRMTexture3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8129 { &IID_IDirect3DRMMaterial, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8130 { &IID_IDirect3DRMMaterial2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8131 { &IID_IDirect3DRMAnimation, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8132 { &IID_IDirect3DRMAnimation2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8133 { &IID_IDirect3DRMAnimationSet, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8134 { &IID_IDirect3DRMAnimationSet2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8135 { &IID_IDirect3DRMObjectArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8136 { &IID_IDirect3DRMDeviceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8137 { &IID_IDirect3DRMViewportArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8138 { &IID_IDirect3DRMFrameArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8139 { &IID_IDirect3DRMVisualArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8140 { &IID_IDirect3DRMLightArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8141 { &IID_IDirect3DRMPickedArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8142 { &IID_IDirect3DRMFaceArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8143 { &IID_IDirect3DRMAnimationArray, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8144 { &IID_IDirect3DRMUserVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8145 { &IID_IDirect3DRMShadow, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8146 { &IID_IDirect3DRMShadow2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8147 { &IID_IDirect3DRMInterpolator, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8148 { &IID_IDirect3DRMProgressiveMesh, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8149 { &IID_IDirect3DRMPicked2Array, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8150 { &IID_IDirect3DRMClippedVisual, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8151 { &IID_IDirectDrawClipper, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8152 { &IID_IDirectDrawSurface7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8153 { &IID_IDirectDrawSurface4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8154 { &IID_IDirectDrawSurface3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8155 { &IID_IDirectDrawSurface2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8156 { &IID_IDirectDrawSurface, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8157 { &IID_IDirect3DDevice7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8158 { &IID_IDirect3DDevice3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8159 { &IID_IDirect3DDevice2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8160 { &IID_IDirect3DDevice, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8161 { &IID_IDirect3D7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8162 { &IID_IDirect3D3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8163 { &IID_IDirect3D2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8164 { &IID_IDirect3D, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8165 { &IID_IDirectDraw7, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8166 { &IID_IDirectDraw4, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8167 { &IID_IDirectDraw3, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8168 { &IID_IDirectDraw2, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8169 { &IID_IDirectDraw, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8170 { &IID_IDirect3DLight, NULL, NULL, CLASS_E_CLASSNOTAVAILABLE },
8171 { &IID_IUnknown, &IID_IUnknown, NULL, S_OK },
8173 IDirect3DRMWrap *wrap;
8174 IDirect3DRM *d3drm1;
8175 IUnknown *unknown;
8176 HRESULT hr;
8178 hr = Direct3DRMCreate(&d3drm1);
8179 ok(SUCCEEDED(hr), "Failed to create d3drm instance, hr %#lx.\n", hr);
8181 hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_CDirect3DRMWrap, NULL, &IID_IDirect3DRMWrap, (void **)&wrap);
8182 ok(SUCCEEDED(hr), "Failed to create wrap instance, hr %#lx.\n", hr);
8184 hr = IDirect3DRMWrap_QueryInterface(wrap, &IID_IUnknown, (void **)&unknown);
8185 ok(SUCCEEDED(hr), "Failed to get IUnknown from wrap, hr %#lx.\n", hr);
8186 IDirect3DRMWrap_Release(wrap);
8187 test_qi("wrap_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests));
8188 IUnknown_Release(unknown);
8190 IDirect3DRM_Release(d3drm1);
8192 START_TEST(d3drm)
8194 test_MeshBuilder();
8195 test_MeshBuilder3();
8196 test_Mesh();
8197 test_Face();
8198 test_Frame();
8199 test_Device();
8200 test_object();
8201 test_Viewport();
8202 test_Light();
8203 test_Material2();
8204 test_Texture();
8205 test_frame_transform();
8206 test_d3drm_load();
8207 test_frame_mesh_materials();
8208 test_d3drm_qi();
8209 test_frame_qi();
8210 test_device_qi();
8211 test_create_device_from_clipper1();
8212 test_create_device_from_clipper2();
8213 test_create_device_from_clipper3();
8214 test_create_device_from_surface1();
8215 test_create_device_from_surface2();
8216 test_create_device_from_surface3();
8217 test_create_device_from_d3d1();
8218 test_create_device_from_d3d2();
8219 test_create_device_from_d3d3();
8220 test_create_device_1();
8221 test_create_device_2();
8222 test_create_device_3();
8223 test_load_texture();
8224 test_texture_qi();
8225 test_viewport_qi();
8226 test_viewport_clear1();
8227 test_viewport_clear2();
8228 test_create_texture_from_surface();
8229 test_animation();
8230 test_animation_qi();
8231 test_wrap();
8232 test_wrap_qi();